From bb3abbb74efd22768590f88aa9eea0ae191efb53 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 14 Jul 2017 05:58:39 -0300 Subject: media: vimc: set id_table for platform drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vimc platform drivers define a platform device ID table but these are not set to the .id_table field in the platform driver structure. So the platform device ID table is only used to fill the aliases in the module but are not used for matching (works because the platform subsystem fallbacks to the driver's name if no .id_table is set). But this also means that the platform device ID table isn't used if the driver is built-in, which leads to the following build warning: This causes the following build warnings when the driver is built-in: drivers/media/platform/vimc//vimc-capture.c:528:40: warning: ‘vimc_cap_driver_ids’ defined but not used [-Wunused-const-variable=] static const struct platform_device_id vimc_cap_driver_ids[] = { ^~~~~~~~~~~~~~~~~~~ drivers/media/platform/vimc//vimc-debayer.c:588:40: warning: ‘vimc_deb_driver_ids’ defined but not used [-Wunused-const-variable=] static const struct platform_device_id vimc_deb_driver_ids[] = { ^~~~~~~~~~~~~~~~~~~ drivers/media/platform/vimc//vimc-scaler.c:442:40: warning: ‘vimc_sca_driver_ids’ defined but not used [-Wunused-const-variable=] static const struct platform_device_id vimc_sca_driver_ids[] = { ^~~~~~~~~~~~~~~~~~~ drivers/media/platform/vimc//vimc-sensor.c:376:40: warning: ‘vimc_sen_driver_ids’ defined but not used [-Wunused-const-variable=] static const struct platform_device_id vimc_sen_driver_ids[] = { ^~~~~~~~~~~~~~~~~~~ Reported-by: Mauro Carvalho Chehab Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Reviewed-by: Helen Koike Acked-by: Sakari Ailus --- drivers/media/platform/vimc/vimc-capture.c | 15 ++++++++------- drivers/media/platform/vimc/vimc-debayer.c | 15 ++++++++------- drivers/media/platform/vimc/vimc-scaler.c | 15 ++++++++------- drivers/media/platform/vimc/vimc-sensor.c | 15 ++++++++------- 4 files changed, 32 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index 14cb32e21130..88a1e5670c72 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c @@ -517,21 +517,22 @@ static int vimc_cap_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id vimc_cap_driver_ids[] = { + { + .name = VIMC_CAP_DRV_NAME, + }, + { } +}; + static struct platform_driver vimc_cap_pdrv = { .probe = vimc_cap_probe, .remove = vimc_cap_remove, + .id_table = vimc_cap_driver_ids, .driver = { .name = VIMC_CAP_DRV_NAME, }, }; -static const struct platform_device_id vimc_cap_driver_ids[] = { - { - .name = VIMC_CAP_DRV_NAME, - }, - { } -}; - module_platform_driver(vimc_cap_pdrv); MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids); diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 35b15bd4d61d..033a131f67af 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -577,21 +577,22 @@ static int vimc_deb_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id vimc_deb_driver_ids[] = { + { + .name = VIMC_DEB_DRV_NAME, + }, + { } +}; + static struct platform_driver vimc_deb_pdrv = { .probe = vimc_deb_probe, .remove = vimc_deb_remove, + .id_table = vimc_deb_driver_ids, .driver = { .name = VIMC_DEB_DRV_NAME, }, }; -static const struct platform_device_id vimc_deb_driver_ids[] = { - { - .name = VIMC_DEB_DRV_NAME, - }, - { } -}; - module_platform_driver(vimc_deb_pdrv); MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids); diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index fe77505d2679..0a3e086e12f3 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -431,21 +431,22 @@ static int vimc_sca_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id vimc_sca_driver_ids[] = { + { + .name = VIMC_SCA_DRV_NAME, + }, + { } +}; + static struct platform_driver vimc_sca_pdrv = { .probe = vimc_sca_probe, .remove = vimc_sca_remove, + .id_table = vimc_sca_driver_ids, .driver = { .name = VIMC_SCA_DRV_NAME, }, }; -static const struct platform_device_id vimc_sca_driver_ids[] = { - { - .name = VIMC_SCA_DRV_NAME, - }, - { } -}; - module_platform_driver(vimc_sca_pdrv); MODULE_DEVICE_TABLE(platform, vimc_sca_driver_ids); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index ebdbbe8c05ed..615c2b18dcfc 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -365,21 +365,22 @@ static int vimc_sen_remove(struct platform_device *pdev) return 0; } +static const struct platform_device_id vimc_sen_driver_ids[] = { + { + .name = VIMC_SEN_DRV_NAME, + }, + { } +}; + static struct platform_driver vimc_sen_pdrv = { .probe = vimc_sen_probe, .remove = vimc_sen_remove, + .id_table = vimc_sen_driver_ids, .driver = { .name = VIMC_SEN_DRV_NAME, }, }; -static const struct platform_device_id vimc_sen_driver_ids[] = { - { - .name = VIMC_SEN_DRV_NAME, - }, - { } -}; - module_platform_driver(vimc_sen_pdrv); MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids); -- cgit v1.2.3 From 23a52386fabe0e06ebaf15cd45cf86ef41bffca3 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Fri, 16 Jun 2017 16:45:33 -0300 Subject: media: ov6650: convert to standalone v4l2 subdevice Remove the soc_camera dependencies and move the diver to i2c Lost features, fortunately not used or not critical on test platform: - soc_camera power on/off callback - replaced with clock enable/disable only, no support for platform provided regulators nor power callback, - soc_camera sense request - replaced with arbitrarily selected default master clock rate and pixel clock limit, no support for platform requested values, - soc_camera board flags - no support for platform requested mbus config tweaks. Tested on Amstrad Delta with now out of tree but still locally maintained omap1_camera host driver. Signed-off-by: Janusz Krzysztofik Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/ov6650.c | 1052 ++++++++++++++++++++++++++++++++ drivers/media/i2c/soc_camera/Kconfig | 6 - drivers/media/i2c/soc_camera/Makefile | 1 - drivers/media/i2c/soc_camera/ov6650.c | 1083 --------------------------------- 6 files changed, 1064 insertions(+), 1090 deletions(-) create mode 100644 drivers/media/i2c/ov6650.c delete mode 100644 drivers/media/i2c/soc_camera/ov6650.c (limited to 'drivers') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 121b3b5394cb..6add6ad53afe 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -593,6 +593,17 @@ config VIDEO_OV5647 To compile this driver as a module, choose M here: the module will be called ov5647. +config VIDEO_OV6650 + tristate "OmniVision OV6650 sensor support" + depends on I2C && VIDEO_V4L2 + depends on MEDIA_CAMERA_SUPPORT + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV6650 camera. + + To compile this driver as a module, choose M here: the + module will be called ov6650. + config VIDEO_OV7640 tristate "OmniVision OV7640 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 2c0868fa6034..aefb3bcb1e81 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV5647) += ov5647.o +obj-$(CONFIG_VIDEO_OV6650) += ov6650.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o obj-$(CONFIG_VIDEO_OV9650) += ov9650.o diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c new file mode 100644 index 000000000000..768f2950ea36 --- /dev/null +++ b/drivers/media/i2c/ov6650.c @@ -0,0 +1,1052 @@ +/* + * V4L2 subdevice driver for OmniVision OV6650 Camera Sensor + * + * Copyright (C) 2010 Janusz Krzysztofik + * + * Based on OmniVision OV96xx Camera Driver + * Copyright (C) 2009 Marek Vasut + * + * Based on ov772x camera driver: + * Copyright (C) 2008 Renesas Solutions Corp. + * Kuninori Morimoto + * + * Based on ov7670 and soc_camera_platform driver, + * Copyright 2006-7 Jonathan Corbet + * Copyright (C) 2008 Magnus Damm + * Copyright (C) 2008, Guennadi Liakhovetski + * + * Hardware specific bits initialy based on former work by Matt Callow + * drivers/media/video/omap/sensor_ov6650.c + * Copyright (C) 2006 Matt Callow + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Register definitions */ +#define REG_GAIN 0x00 /* range 00 - 3F */ +#define REG_BLUE 0x01 +#define REG_RED 0x02 +#define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */ +#define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */ + +#define REG_BRT 0x06 + +#define REG_PIDH 0x0a +#define REG_PIDL 0x0b + +#define REG_AECH 0x10 +#define REG_CLKRC 0x11 /* Data Format and Internal Clock */ + /* [7:6] Input system clock (MHz)*/ + /* 00=8, 01=12, 10=16, 11=24 */ + /* [5:0]: Internal Clock Pre-Scaler */ +#define REG_COMA 0x12 /* [7] Reset */ +#define REG_COMB 0x13 +#define REG_COMC 0x14 +#define REG_COMD 0x15 +#define REG_COML 0x16 +#define REG_HSTRT 0x17 +#define REG_HSTOP 0x18 +#define REG_VSTRT 0x19 +#define REG_VSTOP 0x1a +#define REG_PSHFT 0x1b +#define REG_MIDH 0x1c +#define REG_MIDL 0x1d +#define REG_HSYNS 0x1e +#define REG_HSYNE 0x1f +#define REG_COME 0x20 +#define REG_YOFF 0x21 +#define REG_UOFF 0x22 +#define REG_VOFF 0x23 +#define REG_AEW 0x24 +#define REG_AEB 0x25 +#define REG_COMF 0x26 +#define REG_COMG 0x27 +#define REG_COMH 0x28 +#define REG_COMI 0x29 + +#define REG_FRARL 0x2b +#define REG_COMJ 0x2c +#define REG_COMK 0x2d +#define REG_AVGY 0x2e +#define REG_REF0 0x2f +#define REG_REF1 0x30 +#define REG_REF2 0x31 +#define REG_FRAJH 0x32 +#define REG_FRAJL 0x33 +#define REG_FACT 0x34 +#define REG_L1AEC 0x35 +#define REG_AVGU 0x36 +#define REG_AVGV 0x37 + +#define REG_SPCB 0x60 +#define REG_SPCC 0x61 +#define REG_GAM1 0x62 +#define REG_GAM2 0x63 +#define REG_GAM3 0x64 +#define REG_SPCD 0x65 + +#define REG_SPCE 0x68 +#define REG_ADCL 0x69 + +#define REG_RMCO 0x6c +#define REG_GMCO 0x6d +#define REG_BMCO 0x6e + + +/* Register bits, values, etc. */ +#define OV6650_PIDH 0x66 /* high byte of product ID number */ +#define OV6650_PIDL 0x50 /* low byte of product ID number */ +#define OV6650_MIDH 0x7F /* high byte of mfg ID */ +#define OV6650_MIDL 0xA2 /* low byte of mfg ID */ + +#define DEF_GAIN 0x00 +#define DEF_BLUE 0x80 +#define DEF_RED 0x80 + +#define SAT_SHIFT 4 +#define SAT_MASK (0xf << SAT_SHIFT) +#define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK) + +#define HUE_EN BIT(5) +#define HUE_MASK 0x1f +#define DEF_HUE 0x10 +#define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK)) + +#define DEF_AECH 0x4D + +#define CLKRC_6MHz 0x00 +#define CLKRC_12MHz 0x40 +#define CLKRC_16MHz 0x80 +#define CLKRC_24MHz 0xc0 +#define CLKRC_DIV_MASK 0x3f +#define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1) + +#define COMA_RESET BIT(7) +#define COMA_QCIF BIT(5) +#define COMA_RAW_RGB BIT(4) +#define COMA_RGB BIT(3) +#define COMA_BW BIT(2) +#define COMA_WORD_SWAP BIT(1) +#define COMA_BYTE_SWAP BIT(0) +#define DEF_COMA 0x00 + +#define COMB_FLIP_V BIT(7) +#define COMB_FLIP_H BIT(5) +#define COMB_BAND_FILTER BIT(4) +#define COMB_AWB BIT(2) +#define COMB_AGC BIT(1) +#define COMB_AEC BIT(0) +#define DEF_COMB 0x5f + +#define COML_ONE_CHANNEL BIT(7) + +#define DEF_HSTRT 0x24 +#define DEF_HSTOP 0xd4 +#define DEF_VSTRT 0x04 +#define DEF_VSTOP 0x94 + +#define COMF_HREF_LOW BIT(4) + +#define COMJ_PCLK_RISING BIT(4) +#define COMJ_VSYNC_HIGH BIT(0) + +/* supported resolutions */ +#define W_QCIF (DEF_HSTOP - DEF_HSTRT) +#define W_CIF (W_QCIF << 1) +#define H_QCIF (DEF_VSTOP - DEF_VSTRT) +#define H_CIF (H_QCIF << 1) + +#define FRAME_RATE_MAX 30 + + +struct ov6650_reg { + u8 reg; + u8 val; +}; + +struct ov6650 { + struct v4l2_subdev subdev; + struct v4l2_ctrl_handler hdl; + struct { + /* exposure/autoexposure cluster */ + struct v4l2_ctrl *autoexposure; + struct v4l2_ctrl *exposure; + }; + struct { + /* gain/autogain cluster */ + struct v4l2_ctrl *autogain; + struct v4l2_ctrl *gain; + }; + struct { + /* blue/red/autowhitebalance cluster */ + struct v4l2_ctrl *autowb; + struct v4l2_ctrl *blue; + struct v4l2_ctrl *red; + }; + struct v4l2_clk *clk; + bool half_scale; /* scale down output by 2 */ + struct v4l2_rect rect; /* sensor cropping window */ + unsigned long pclk_limit; /* from host */ + unsigned long pclk_max; /* from resolution and format */ + struct v4l2_fract tpf; /* as requested with s_parm */ + u32 code; + enum v4l2_colorspace colorspace; +}; + + +static u32 ov6650_codes[] = { + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_Y8_1X8, +}; + +/* read a register */ +static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret; + u8 data = reg; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &data, + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + goto err; + + msg.flags = I2C_M_RD; + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + goto err; + + *val = data; + return 0; + +err: + dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg); + return ret; +} + +/* write a register */ +static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val) +{ + int ret; + unsigned char data[2] = { reg, val }; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = data, + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + udelay(100); + + if (ret < 0) { + dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg); + return ret; + } + return 0; +} + + +/* Read a register, alter its bits, write it back */ +static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask) +{ + u8 val; + int ret; + + ret = ov6650_reg_read(client, reg, &val); + if (ret) { + dev_err(&client->dev, + "[Read]-Modify-Write of register 0x%02x failed!\n", + reg); + return ret; + } + + val &= ~mask; + val |= set; + + ret = ov6650_reg_write(client, reg, val); + if (ret) + dev_err(&client->dev, + "Read-Modify-[Write] of register 0x%02x failed!\n", + reg); + + return ret; +} + +static struct ov6650 *to_ov6650(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct ov6650, subdev); +} + +/* Start/Stop streaming from the device */ +static int ov6650_s_stream(struct v4l2_subdev *sd, int enable) +{ + return 0; +} + +/* Get status of additional camera capabilities */ +static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl); + struct v4l2_subdev *sd = &priv->subdev; + struct i2c_client *client = v4l2_get_subdevdata(sd); + uint8_t reg, reg2; + int ret; + + switch (ctrl->id) { + case V4L2_CID_AUTOGAIN: + ret = ov6650_reg_read(client, REG_GAIN, ®); + if (!ret) + priv->gain->val = reg; + return ret; + case V4L2_CID_AUTO_WHITE_BALANCE: + ret = ov6650_reg_read(client, REG_BLUE, ®); + if (!ret) + ret = ov6650_reg_read(client, REG_RED, ®2); + if (!ret) { + priv->blue->val = reg; + priv->red->val = reg2; + } + return ret; + case V4L2_CID_EXPOSURE_AUTO: + ret = ov6650_reg_read(client, REG_AECH, ®); + if (!ret) + priv->exposure->val = reg; + return ret; + } + return -EINVAL; +} + +/* Set status of additional camera capabilities */ +static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl); + struct v4l2_subdev *sd = &priv->subdev; + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + switch (ctrl->id) { + case V4L2_CID_AUTOGAIN: + ret = ov6650_reg_rmw(client, REG_COMB, + ctrl->val ? COMB_AGC : 0, COMB_AGC); + if (!ret && !ctrl->val) + ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val); + return ret; + case V4L2_CID_AUTO_WHITE_BALANCE: + ret = ov6650_reg_rmw(client, REG_COMB, + ctrl->val ? COMB_AWB : 0, COMB_AWB); + if (!ret && !ctrl->val) { + ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val); + if (!ret) + ret = ov6650_reg_write(client, REG_RED, + priv->red->val); + } + return ret; + case V4L2_CID_SATURATION: + return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val), + SAT_MASK); + case V4L2_CID_HUE: + return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val), + HUE_MASK); + case V4L2_CID_BRIGHTNESS: + return ov6650_reg_write(client, REG_BRT, ctrl->val); + case V4L2_CID_EXPOSURE_AUTO: + ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val == + V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC); + if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL) + ret = ov6650_reg_write(client, REG_AECH, + priv->exposure->val); + return ret; + case V4L2_CID_GAMMA: + return ov6650_reg_write(client, REG_GAM1, ctrl->val); + case V4L2_CID_VFLIP: + return ov6650_reg_rmw(client, REG_COMB, + ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V); + case V4L2_CID_HFLIP: + return ov6650_reg_rmw(client, REG_COMB, + ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H); + } + + return -EINVAL; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ov6650_get_register(struct v4l2_subdev *sd, + struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + u8 val; + + if (reg->reg & ~0xff) + return -EINVAL; + + reg->size = 1; + + ret = ov6650_reg_read(client, reg->reg, &val); + if (!ret) + reg->val = (__u64)val; + + return ret; +} + +static int ov6650_set_register(struct v4l2_subdev *sd, + const struct v4l2_dbg_register *reg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (reg->reg & ~0xff || reg->val & ~0xff) + return -EINVAL; + + return ov6650_reg_write(client, reg->reg, reg->val); +} +#endif + +static int ov6650_s_power(struct v4l2_subdev *sd, int on) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + int ret = 0; + + if (on) + ret = v4l2_clk_enable(priv->clk); + else + v4l2_clk_disable(priv->clk); + + return ret; +} + +static int ov6650_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = DEF_HSTRT << 1; + sel->r.top = DEF_VSTRT << 1; + sel->r.width = W_CIF; + sel->r.height = H_CIF; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->rect; + return 0; + default: + return -EINVAL; + } +} + +static int ov6650_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + struct v4l2_rect rect = sel->r; + int ret; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + v4l_bound_align_image(&rect.width, 2, W_CIF, 1, + &rect.height, 2, H_CIF, 1, 0); + v4l_bound_align_image(&rect.left, DEF_HSTRT << 1, + (DEF_HSTRT << 1) + W_CIF - (__s32)rect.width, 1, + &rect.top, DEF_VSTRT << 1, + (DEF_VSTRT << 1) + H_CIF - (__s32)rect.height, 1, + 0); + + ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1); + if (!ret) { + priv->rect.left = rect.left; + ret = ov6650_reg_write(client, REG_HSTOP, + (rect.left + rect.width) >> 1); + } + if (!ret) { + priv->rect.width = rect.width; + ret = ov6650_reg_write(client, REG_VSTRT, rect.top >> 1); + } + if (!ret) { + priv->rect.top = rect.top; + ret = ov6650_reg_write(client, REG_VSTOP, + (rect.top + rect.height) >> 1); + } + if (!ret) + priv->rect.height = rect.height; + + return ret; +} + +static int ov6650_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + + if (format->pad) + return -EINVAL; + + mf->width = priv->rect.width >> priv->half_scale; + mf->height = priv->rect.height >> priv->half_scale; + mf->code = priv->code; + mf->colorspace = priv->colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} + +static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect) +{ + return width > rect->width >> 1 || height > rect->height >> 1; +} + +static u8 to_clkrc(struct v4l2_fract *timeperframe, + unsigned long pclk_limit, unsigned long pclk_max) +{ + unsigned long pclk; + + if (timeperframe->numerator && timeperframe->denominator) + pclk = pclk_max * timeperframe->denominator / + (FRAME_RATE_MAX * timeperframe->numerator); + else + pclk = pclk_max; + + if (pclk_limit && pclk_limit < pclk) + pclk = pclk_limit; + + return (pclk_max - 1) / pclk; +} + +/* set the format we will capture in */ +static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .r.left = priv->rect.left + (priv->rect.width >> 1) - + (mf->width >> (1 - half_scale)), + .r.top = priv->rect.top + (priv->rect.height >> 1) - + (mf->height >> (1 - half_scale)), + .r.width = mf->width << half_scale, + .r.height = mf->height << half_scale, + }; + u32 code = mf->code; + unsigned long mclk, pclk; + u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; + int ret; + + /* select color matrix configuration for given color encoding */ + switch (code) { + case MEDIA_BUS_FMT_Y8_1X8: + dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); + coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; + coma_set |= COMA_BW; + break; + case MEDIA_BUS_FMT_YUYV8_2X8: + dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); + coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; + coma_set |= COMA_WORD_SWAP; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); + coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | + COMA_BYTE_SWAP; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); + if (half_scale) { + coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; + coma_set |= COMA_BYTE_SWAP; + } else { + coma_mask |= COMA_RGB | COMA_BW; + coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; + } + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); + if (half_scale) { + coma_mask |= COMA_RGB | COMA_BW; + coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; + } else { + coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; + coma_set |= COMA_BYTE_SWAP; + } + break; + case MEDIA_BUS_FMT_SBGGR8_1X8: + dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); + coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; + coma_set |= COMA_RAW_RGB | COMA_RGB; + break; + default: + dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); + return -EINVAL; + } + priv->code = code; + + if (code == MEDIA_BUS_FMT_Y8_1X8 || + code == MEDIA_BUS_FMT_SBGGR8_1X8) { + coml_mask = COML_ONE_CHANNEL; + coml_set = 0; + priv->pclk_max = 4000000; + } else { + coml_mask = 0; + coml_set = COML_ONE_CHANNEL; + priv->pclk_max = 8000000; + } + + if (code == MEDIA_BUS_FMT_SBGGR8_1X8) + priv->colorspace = V4L2_COLORSPACE_SRGB; + else if (code != 0) + priv->colorspace = V4L2_COLORSPACE_JPEG; + + if (half_scale) { + dev_dbg(&client->dev, "max resolution: QCIF\n"); + coma_set |= COMA_QCIF; + priv->pclk_max /= 2; + } else { + dev_dbg(&client->dev, "max resolution: CIF\n"); + coma_mask |= COMA_QCIF; + } + priv->half_scale = half_scale; + + clkrc = CLKRC_12MHz; + mclk = 12000000; + priv->pclk_limit = 1334000; + dev_dbg(&client->dev, "using 12MHz input clock\n"); + + clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); + + pclk = priv->pclk_max / GET_CLKRC_DIV(clkrc); + dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", + mclk / pclk, 10 * mclk % pclk / pclk); + + ret = ov6650_set_selection(sd, NULL, &sel); + if (!ret) + ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); + if (!ret) + ret = ov6650_reg_write(client, REG_CLKRC, clkrc); + if (!ret) + ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); + + if (!ret) { + mf->colorspace = priv->colorspace; + mf->width = priv->rect.width >> half_scale; + mf->height = priv->rect.height >> half_scale; + } + return ret; +} + +static int ov6650_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *mf = &format->format; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + + if (format->pad) + return -EINVAL; + + if (is_unscaled_ok(mf->width, mf->height, &priv->rect)) + v4l_bound_align_image(&mf->width, 2, W_CIF, 1, + &mf->height, 2, H_CIF, 1, 0); + + mf->field = V4L2_FIELD_NONE; + + switch (mf->code) { + case MEDIA_BUS_FMT_Y10_1X10: + mf->code = MEDIA_BUS_FMT_Y8_1X8; + /* fall through */ + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + mf->colorspace = V4L2_COLORSPACE_JPEG; + break; + default: + mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; + /* fall through */ + case MEDIA_BUS_FMT_SBGGR8_1X8: + mf->colorspace = V4L2_COLORSPACE_SRGB; + break; + } + + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov6650_s_fmt(sd, mf); + cfg->try_fmt = *mf; + + return 0; +} + +static int ov6650_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes)) + return -EINVAL; + + code->code = ov6650_codes[code->index]; + return 0; +} + +static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + struct v4l2_captureparm *cp = &parms->parm.capture; + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(*cp)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, + priv->pclk_limit, priv->pclk_max)); + cp->timeperframe.denominator = FRAME_RATE_MAX; + + dev_dbg(&client->dev, "Frame interval: %u/%u s\n", + cp->timeperframe.numerator, cp->timeperframe.denominator); + + return 0; +} + +static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov6650 *priv = to_ov6650(client); + struct v4l2_captureparm *cp = &parms->parm.capture; + struct v4l2_fract *tpf = &cp->timeperframe; + int div, ret; + u8 clkrc; + + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (cp->extendedmode != 0) + return -EINVAL; + + if (tpf->numerator == 0 || tpf->denominator == 0) + div = 1; /* Reset to full rate */ + else + div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator; + + if (div == 0) + div = 1; + else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK)) + div = GET_CLKRC_DIV(CLKRC_DIV_MASK); + + /* + * Keep result to be used as tpf limit + * for subseqent clock divider calculations + */ + priv->tpf.numerator = div; + priv->tpf.denominator = FRAME_RATE_MAX; + + clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); + + ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK); + if (!ret) { + tpf->numerator = GET_CLKRC_DIV(clkrc); + tpf->denominator = FRAME_RATE_MAX; + } + + return ret; +} + +/* Soft reset the camera. This has nothing to do with the RESET pin! */ +static int ov6650_reset(struct i2c_client *client) +{ + int ret; + + dev_dbg(&client->dev, "reset\n"); + + ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0); + if (ret) + dev_err(&client->dev, + "An error occurred while entering soft reset!\n"); + + return ret; +} + +/* program default register values */ +static int ov6650_prog_dflt(struct i2c_client *client) +{ + int ret; + + dev_dbg(&client->dev, "initializing\n"); + + ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */ + if (!ret) + ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER); + + return ret; +} + +static int ov6650_video_probe(struct i2c_client *client) +{ + struct ov6650 *priv = to_ov6650(client); + u8 pidh, pidl, midh, midl; + int ret; + + ret = ov6650_s_power(&priv->subdev, 1); + if (ret < 0) + return ret; + + /* + * check and show product ID and manufacturer ID + */ + ret = ov6650_reg_read(client, REG_PIDH, &pidh); + if (!ret) + ret = ov6650_reg_read(client, REG_PIDL, &pidl); + if (!ret) + ret = ov6650_reg_read(client, REG_MIDH, &midh); + if (!ret) + ret = ov6650_reg_read(client, REG_MIDL, &midl); + + if (ret) + goto done; + + if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) { + dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n", + pidh, pidl); + ret = -ENODEV; + goto done; + } + + dev_info(&client->dev, + "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n", + pidh, pidl, midh, midl); + + ret = ov6650_reset(client); + if (!ret) + ret = ov6650_prog_dflt(client); + if (!ret) + ret = v4l2_ctrl_handler_setup(&priv->hdl); + +done: + ov6650_s_power(&priv->subdev, 0); + return ret; +} + +static const struct v4l2_ctrl_ops ov6550_ctrl_ops = { + .g_volatile_ctrl = ov6550_g_volatile_ctrl, + .s_ctrl = ov6550_s_ctrl, +}; + +static const struct v4l2_subdev_core_ops ov6650_core_ops = { +#ifdef CONFIG_VIDEO_ADV_DEBUG + .g_register = ov6650_get_register, + .s_register = ov6650_set_register, +#endif + .s_power = ov6650_s_power, +}; + +/* Request bus settings on camera side */ +static int ov6650_g_mbus_config(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg) +{ + + cfg->flags = V4L2_MBUS_MASTER | + V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | + V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | + V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | + V4L2_MBUS_DATA_ACTIVE_HIGH; + cfg->type = V4L2_MBUS_PARALLEL; + + return 0; +} + +/* Alter bus settings on camera side */ +static int ov6650_s_mbus_config(struct v4l2_subdev *sd, + const struct v4l2_mbus_config *cfg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + if (cfg->flags & V4L2_MBUS_PCLK_SAMPLE_RISING) + ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); + else + ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); + if (ret) + return ret; + + if (cfg->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) + ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); + else + ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); + if (ret) + return ret; + + if (cfg->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) + ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); + else + ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); + + return ret; +} + +static const struct v4l2_subdev_video_ops ov6650_video_ops = { + .s_stream = ov6650_s_stream, + .g_parm = ov6650_g_parm, + .s_parm = ov6650_s_parm, + .g_mbus_config = ov6650_g_mbus_config, + .s_mbus_config = ov6650_s_mbus_config, +}; + +static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { + .enum_mbus_code = ov6650_enum_mbus_code, + .get_selection = ov6650_get_selection, + .set_selection = ov6650_set_selection, + .get_fmt = ov6650_get_fmt, + .set_fmt = ov6650_set_fmt, +}; + +static const struct v4l2_subdev_ops ov6650_subdev_ops = { + .core = &ov6650_core_ops, + .video = &ov6650_video_ops, + .pad = &ov6650_pad_ops, +}; + +/* + * i2c_driver function + */ +static int ov6650_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct ov6650 *priv; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&client->dev, + "Failed to allocate memory for private data!\n"); + return -ENOMEM; + } + + v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); + v4l2_ctrl_handler_init(&priv->hdl, 13); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN); + priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); + priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE); + priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_SATURATION, 0, 0xf, 1, 0x8); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80); + priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl, + &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, + V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO); + priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH); + v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, + V4L2_CID_GAMMA, 0, 0xff, 1, 0x12); + + priv->subdev.ctrl_handler = &priv->hdl; + if (priv->hdl.error) + return priv->hdl.error; + + v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true); + v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true); + v4l2_ctrl_auto_cluster(2, &priv->autoexposure, + V4L2_EXPOSURE_MANUAL, true); + + priv->rect.left = DEF_HSTRT << 1; + priv->rect.top = DEF_VSTRT << 1; + priv->rect.width = W_CIF; + priv->rect.height = H_CIF; + priv->half_scale = false; + priv->code = MEDIA_BUS_FMT_YUYV8_2X8; + priv->colorspace = V4L2_COLORSPACE_JPEG; + + priv->clk = v4l2_clk_get(&client->dev, NULL); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; + } + + ret = ov6650_video_probe(client); + if (ret) { + v4l2_clk_put(priv->clk); +eclkget: + v4l2_ctrl_handler_free(&priv->hdl); + } + + return ret; +} + +static int ov6650_remove(struct i2c_client *client) +{ + struct ov6650 *priv = to_ov6650(client); + + v4l2_clk_put(priv->clk); + v4l2_device_unregister_subdev(&priv->subdev); + v4l2_ctrl_handler_free(&priv->hdl); + return 0; +} + +static const struct i2c_device_id ov6650_id[] = { + { "ov6650", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ov6650_id); + +static struct i2c_driver ov6650_i2c_driver = { + .driver = { + .name = "ov6650", + }, + .probe = ov6650_probe, + .remove = ov6650_remove, + .id_table = ov6650_id, +}; + +module_i2c_driver(ov6650_i2c_driver); + +MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); +MODULE_AUTHOR("Janusz Krzysztofik "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig index 96859f37cb1c..72b369895b37 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig @@ -47,12 +47,6 @@ config SOC_CAMERA_OV5642 help This is a V4L2 camera driver for the OmniVision OV5642 sensor -config SOC_CAMERA_OV6650 - tristate "ov6650 sensor support" - depends on SOC_CAMERA && I2C - ---help--- - This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor - config SOC_CAMERA_OV772X tristate "ov772x camera support" depends on SOC_CAMERA && I2C diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile index 974bdb721dbe..78532a7fb8e2 100644 --- a/drivers/media/i2c/soc_camera/Makefile +++ b/drivers/media/i2c/soc_camera/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o -obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c deleted file mode 100644 index d2be64d54b22..000000000000 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * V4L2 SoC Camera driver for OmniVision OV6650 Camera Sensor - * - * Copyright (C) 2010 Janusz Krzysztofik - * - * Based on OmniVision OV96xx Camera Driver - * Copyright (C) 2009 Marek Vasut - * - * Based on ov772x camera driver: - * Copyright (C) 2008 Renesas Solutions Corp. - * Kuninori Morimoto - * - * Based on ov7670 and soc_camera_platform driver, - * Copyright 2006-7 Jonathan Corbet - * Copyright (C) 2008 Magnus Damm - * Copyright (C) 2008, Guennadi Liakhovetski - * - * Hardware specific bits initialy based on former work by Matt Callow - * drivers/media/video/omap/sensor_ov6650.c - * Copyright (C) 2006 Matt Callow - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Register definitions */ -#define REG_GAIN 0x00 /* range 00 - 3F */ -#define REG_BLUE 0x01 -#define REG_RED 0x02 -#define REG_SAT 0x03 /* [7:4] saturation [0:3] reserved */ -#define REG_HUE 0x04 /* [7:6] rsrvd [5] hue en [4:0] hue */ - -#define REG_BRT 0x06 - -#define REG_PIDH 0x0a -#define REG_PIDL 0x0b - -#define REG_AECH 0x10 -#define REG_CLKRC 0x11 /* Data Format and Internal Clock */ - /* [7:6] Input system clock (MHz)*/ - /* 00=8, 01=12, 10=16, 11=24 */ - /* [5:0]: Internal Clock Pre-Scaler */ -#define REG_COMA 0x12 /* [7] Reset */ -#define REG_COMB 0x13 -#define REG_COMC 0x14 -#define REG_COMD 0x15 -#define REG_COML 0x16 -#define REG_HSTRT 0x17 -#define REG_HSTOP 0x18 -#define REG_VSTRT 0x19 -#define REG_VSTOP 0x1a -#define REG_PSHFT 0x1b -#define REG_MIDH 0x1c -#define REG_MIDL 0x1d -#define REG_HSYNS 0x1e -#define REG_HSYNE 0x1f -#define REG_COME 0x20 -#define REG_YOFF 0x21 -#define REG_UOFF 0x22 -#define REG_VOFF 0x23 -#define REG_AEW 0x24 -#define REG_AEB 0x25 -#define REG_COMF 0x26 -#define REG_COMG 0x27 -#define REG_COMH 0x28 -#define REG_COMI 0x29 - -#define REG_FRARL 0x2b -#define REG_COMJ 0x2c -#define REG_COMK 0x2d -#define REG_AVGY 0x2e -#define REG_REF0 0x2f -#define REG_REF1 0x30 -#define REG_REF2 0x31 -#define REG_FRAJH 0x32 -#define REG_FRAJL 0x33 -#define REG_FACT 0x34 -#define REG_L1AEC 0x35 -#define REG_AVGU 0x36 -#define REG_AVGV 0x37 - -#define REG_SPCB 0x60 -#define REG_SPCC 0x61 -#define REG_GAM1 0x62 -#define REG_GAM2 0x63 -#define REG_GAM3 0x64 -#define REG_SPCD 0x65 - -#define REG_SPCE 0x68 -#define REG_ADCL 0x69 - -#define REG_RMCO 0x6c -#define REG_GMCO 0x6d -#define REG_BMCO 0x6e - - -/* Register bits, values, etc. */ -#define OV6650_PIDH 0x66 /* high byte of product ID number */ -#define OV6650_PIDL 0x50 /* low byte of product ID number */ -#define OV6650_MIDH 0x7F /* high byte of mfg ID */ -#define OV6650_MIDL 0xA2 /* low byte of mfg ID */ - -#define DEF_GAIN 0x00 -#define DEF_BLUE 0x80 -#define DEF_RED 0x80 - -#define SAT_SHIFT 4 -#define SAT_MASK (0xf << SAT_SHIFT) -#define SET_SAT(x) (((x) << SAT_SHIFT) & SAT_MASK) - -#define HUE_EN BIT(5) -#define HUE_MASK 0x1f -#define DEF_HUE 0x10 -#define SET_HUE(x) (HUE_EN | ((x) & HUE_MASK)) - -#define DEF_AECH 0x4D - -#define CLKRC_6MHz 0x00 -#define CLKRC_12MHz 0x40 -#define CLKRC_16MHz 0x80 -#define CLKRC_24MHz 0xc0 -#define CLKRC_DIV_MASK 0x3f -#define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1) - -#define COMA_RESET BIT(7) -#define COMA_QCIF BIT(5) -#define COMA_RAW_RGB BIT(4) -#define COMA_RGB BIT(3) -#define COMA_BW BIT(2) -#define COMA_WORD_SWAP BIT(1) -#define COMA_BYTE_SWAP BIT(0) -#define DEF_COMA 0x00 - -#define COMB_FLIP_V BIT(7) -#define COMB_FLIP_H BIT(5) -#define COMB_BAND_FILTER BIT(4) -#define COMB_AWB BIT(2) -#define COMB_AGC BIT(1) -#define COMB_AEC BIT(0) -#define DEF_COMB 0x5f - -#define COML_ONE_CHANNEL BIT(7) - -#define DEF_HSTRT 0x24 -#define DEF_HSTOP 0xd4 -#define DEF_VSTRT 0x04 -#define DEF_VSTOP 0x94 - -#define COMF_HREF_LOW BIT(4) - -#define COMJ_PCLK_RISING BIT(4) -#define COMJ_VSYNC_HIGH BIT(0) - -/* supported resolutions */ -#define W_QCIF (DEF_HSTOP - DEF_HSTRT) -#define W_CIF (W_QCIF << 1) -#define H_QCIF (DEF_VSTOP - DEF_VSTRT) -#define H_CIF (H_QCIF << 1) - -#define FRAME_RATE_MAX 30 - - -struct ov6650_reg { - u8 reg; - u8 val; -}; - -struct ov6650 { - struct v4l2_subdev subdev; - struct v4l2_ctrl_handler hdl; - struct { - /* exposure/autoexposure cluster */ - struct v4l2_ctrl *autoexposure; - struct v4l2_ctrl *exposure; - }; - struct { - /* gain/autogain cluster */ - struct v4l2_ctrl *autogain; - struct v4l2_ctrl *gain; - }; - struct { - /* blue/red/autowhitebalance cluster */ - struct v4l2_ctrl *autowb; - struct v4l2_ctrl *blue; - struct v4l2_ctrl *red; - }; - struct v4l2_clk *clk; - bool half_scale; /* scale down output by 2 */ - struct v4l2_rect rect; /* sensor cropping window */ - unsigned long pclk_limit; /* from host */ - unsigned long pclk_max; /* from resolution and format */ - struct v4l2_fract tpf; /* as requested with s_parm */ - u32 code; - enum v4l2_colorspace colorspace; -}; - - -static u32 ov6650_codes[] = { - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, - MEDIA_BUS_FMT_SBGGR8_1X8, - MEDIA_BUS_FMT_Y8_1X8, -}; - -/* read a register */ -static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int ret; - u8 data = reg; - struct i2c_msg msg = { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = &data, - }; - - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret < 0) - goto err; - - msg.flags = I2C_M_RD; - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret < 0) - goto err; - - *val = data; - return 0; - -err: - dev_err(&client->dev, "Failed reading register 0x%02x!\n", reg); - return ret; -} - -/* write a register */ -static int ov6650_reg_write(struct i2c_client *client, u8 reg, u8 val) -{ - int ret; - unsigned char data[2] = { reg, val }; - struct i2c_msg msg = { - .addr = client->addr, - .flags = 0, - .len = 2, - .buf = data, - }; - - ret = i2c_transfer(client->adapter, &msg, 1); - udelay(100); - - if (ret < 0) { - dev_err(&client->dev, "Failed writing register 0x%02x!\n", reg); - return ret; - } - return 0; -} - - -/* Read a register, alter its bits, write it back */ -static int ov6650_reg_rmw(struct i2c_client *client, u8 reg, u8 set, u8 mask) -{ - u8 val; - int ret; - - ret = ov6650_reg_read(client, reg, &val); - if (ret) { - dev_err(&client->dev, - "[Read]-Modify-Write of register 0x%02x failed!\n", - reg); - return ret; - } - - val &= ~mask; - val |= set; - - ret = ov6650_reg_write(client, reg, val); - if (ret) - dev_err(&client->dev, - "Read-Modify-[Write] of register 0x%02x failed!\n", - reg); - - return ret; -} - -static struct ov6650 *to_ov6650(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct ov6650, subdev); -} - -/* Start/Stop streaming from the device */ -static int ov6650_s_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - -/* Get status of additional camera capabilities */ -static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl); - struct v4l2_subdev *sd = &priv->subdev; - struct i2c_client *client = v4l2_get_subdevdata(sd); - uint8_t reg, reg2; - int ret; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - ret = ov6650_reg_read(client, REG_GAIN, ®); - if (!ret) - priv->gain->val = reg; - return ret; - case V4L2_CID_AUTO_WHITE_BALANCE: - ret = ov6650_reg_read(client, REG_BLUE, ®); - if (!ret) - ret = ov6650_reg_read(client, REG_RED, ®2); - if (!ret) { - priv->blue->val = reg; - priv->red->val = reg2; - } - return ret; - case V4L2_CID_EXPOSURE_AUTO: - ret = ov6650_reg_read(client, REG_AECH, ®); - if (!ret) - priv->exposure->val = reg; - return ret; - } - return -EINVAL; -} - -/* Set status of additional camera capabilities */ -static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl); - struct v4l2_subdev *sd = &priv->subdev; - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - ret = ov6650_reg_rmw(client, REG_COMB, - ctrl->val ? COMB_AGC : 0, COMB_AGC); - if (!ret && !ctrl->val) - ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val); - return ret; - case V4L2_CID_AUTO_WHITE_BALANCE: - ret = ov6650_reg_rmw(client, REG_COMB, - ctrl->val ? COMB_AWB : 0, COMB_AWB); - if (!ret && !ctrl->val) { - ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val); - if (!ret) - ret = ov6650_reg_write(client, REG_RED, - priv->red->val); - } - return ret; - case V4L2_CID_SATURATION: - return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val), - SAT_MASK); - case V4L2_CID_HUE: - return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val), - HUE_MASK); - case V4L2_CID_BRIGHTNESS: - return ov6650_reg_write(client, REG_BRT, ctrl->val); - case V4L2_CID_EXPOSURE_AUTO: - ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val == - V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC); - if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL) - ret = ov6650_reg_write(client, REG_AECH, - priv->exposure->val); - return ret; - case V4L2_CID_GAMMA: - return ov6650_reg_write(client, REG_GAM1, ctrl->val); - case V4L2_CID_VFLIP: - return ov6650_reg_rmw(client, REG_COMB, - ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V); - case V4L2_CID_HFLIP: - return ov6650_reg_rmw(client, REG_COMB, - ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H); - } - - return -EINVAL; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int ov6650_get_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u8 val; - - if (reg->reg & ~0xff) - return -EINVAL; - - reg->size = 1; - - ret = ov6650_reg_read(client, reg->reg, &val); - if (!ret) - reg->val = (__u64)val; - - return ret; -} - -static int ov6650_set_register(struct v4l2_subdev *sd, - const struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (reg->reg & ~0xff || reg->val & ~0xff) - return -EINVAL; - - return ov6650_reg_write(client, reg->reg, reg->val); -} -#endif - -static int ov6650_s_power(struct v4l2_subdev *sd, int on) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - struct ov6650 *priv = to_ov6650(client); - - return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); -} - -static int ov6650_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_selection *sel) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) - return -EINVAL; - - switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: - case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.left = DEF_HSTRT << 1; - sel->r.top = DEF_VSTRT << 1; - sel->r.width = W_CIF; - sel->r.height = H_CIF; - return 0; - case V4L2_SEL_TGT_CROP: - sel->r = priv->rect; - return 0; - default: - return -EINVAL; - } -} - -static int ov6650_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_selection *sel) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - struct v4l2_rect rect = sel->r; - int ret; - - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || - sel->target != V4L2_SEL_TGT_CROP) - return -EINVAL; - - rect.left = ALIGN(rect.left, 2); - rect.width = ALIGN(rect.width, 2); - rect.top = ALIGN(rect.top, 2); - rect.height = ALIGN(rect.height, 2); - soc_camera_limit_side(&rect.left, &rect.width, - DEF_HSTRT << 1, 2, W_CIF); - soc_camera_limit_side(&rect.top, &rect.height, - DEF_VSTRT << 1, 2, H_CIF); - - ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1); - if (!ret) { - priv->rect.left = rect.left; - ret = ov6650_reg_write(client, REG_HSTOP, - (rect.left + rect.width) >> 1); - } - if (!ret) { - priv->rect.width = rect.width; - ret = ov6650_reg_write(client, REG_VSTRT, rect.top >> 1); - } - if (!ret) { - priv->rect.top = rect.top; - ret = ov6650_reg_write(client, REG_VSTOP, - (rect.top + rect.height) >> 1); - } - if (!ret) - priv->rect.height = rect.height; - - return ret; -} - -static int ov6650_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *mf = &format->format; - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - - if (format->pad) - return -EINVAL; - - mf->width = priv->rect.width >> priv->half_scale; - mf->height = priv->rect.height >> priv->half_scale; - mf->code = priv->code; - mf->colorspace = priv->colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} - -static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect) -{ - return width > rect->width >> 1 || height > rect->height >> 1; -} - -static u8 to_clkrc(struct v4l2_fract *timeperframe, - unsigned long pclk_limit, unsigned long pclk_max) -{ - unsigned long pclk; - - if (timeperframe->numerator && timeperframe->denominator) - pclk = pclk_max * timeperframe->denominator / - (FRAME_RATE_MAX * timeperframe->numerator); - else - pclk = pclk_max; - - if (pclk_limit && pclk_limit < pclk) - pclk = pclk_limit; - - return (pclk_max - 1) / pclk; -} - -/* set the format we will capture in */ -static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); - struct soc_camera_sense *sense = icd->sense; - struct ov6650 *priv = to_ov6650(client); - bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); - struct v4l2_subdev_selection sel = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - .target = V4L2_SEL_TGT_CROP, - .r.left = priv->rect.left + (priv->rect.width >> 1) - - (mf->width >> (1 - half_scale)), - .r.top = priv->rect.top + (priv->rect.height >> 1) - - (mf->height >> (1 - half_scale)), - .r.width = mf->width << half_scale, - .r.height = mf->height << half_scale, - }; - u32 code = mf->code; - unsigned long mclk, pclk; - u8 coma_set = 0, coma_mask = 0, coml_set, coml_mask, clkrc; - int ret; - - /* select color matrix configuration for given color encoding */ - switch (code) { - case MEDIA_BUS_FMT_Y8_1X8: - dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); - coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; - coma_set |= COMA_BW; - break; - case MEDIA_BUS_FMT_YUYV8_2X8: - dev_dbg(&client->dev, "pixel format YUYV8_2X8_LE\n"); - coma_mask |= COMA_RGB | COMA_BW | COMA_BYTE_SWAP; - coma_set |= COMA_WORD_SWAP; - break; - case MEDIA_BUS_FMT_YVYU8_2X8: - dev_dbg(&client->dev, "pixel format YVYU8_2X8_LE (untested)\n"); - coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP | - COMA_BYTE_SWAP; - break; - case MEDIA_BUS_FMT_UYVY8_2X8: - dev_dbg(&client->dev, "pixel format YUYV8_2X8_BE\n"); - if (half_scale) { - coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; - coma_set |= COMA_BYTE_SWAP; - } else { - coma_mask |= COMA_RGB | COMA_BW; - coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; - } - break; - case MEDIA_BUS_FMT_VYUY8_2X8: - dev_dbg(&client->dev, "pixel format YVYU8_2X8_BE (untested)\n"); - if (half_scale) { - coma_mask |= COMA_RGB | COMA_BW; - coma_set |= COMA_BYTE_SWAP | COMA_WORD_SWAP; - } else { - coma_mask |= COMA_RGB | COMA_BW | COMA_WORD_SWAP; - coma_set |= COMA_BYTE_SWAP; - } - break; - case MEDIA_BUS_FMT_SBGGR8_1X8: - dev_dbg(&client->dev, "pixel format SBGGR8_1X8 (untested)\n"); - coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP; - coma_set |= COMA_RAW_RGB | COMA_RGB; - break; - default: - dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); - return -EINVAL; - } - priv->code = code; - - if (code == MEDIA_BUS_FMT_Y8_1X8 || - code == MEDIA_BUS_FMT_SBGGR8_1X8) { - coml_mask = COML_ONE_CHANNEL; - coml_set = 0; - priv->pclk_max = 4000000; - } else { - coml_mask = 0; - coml_set = COML_ONE_CHANNEL; - priv->pclk_max = 8000000; - } - - if (code == MEDIA_BUS_FMT_SBGGR8_1X8) - priv->colorspace = V4L2_COLORSPACE_SRGB; - else if (code != 0) - priv->colorspace = V4L2_COLORSPACE_JPEG; - - if (half_scale) { - dev_dbg(&client->dev, "max resolution: QCIF\n"); - coma_set |= COMA_QCIF; - priv->pclk_max /= 2; - } else { - dev_dbg(&client->dev, "max resolution: CIF\n"); - coma_mask |= COMA_QCIF; - } - priv->half_scale = half_scale; - - if (sense) { - if (sense->master_clock == 8000000) { - dev_dbg(&client->dev, "8MHz input clock\n"); - clkrc = CLKRC_6MHz; - } else if (sense->master_clock == 12000000) { - dev_dbg(&client->dev, "12MHz input clock\n"); - clkrc = CLKRC_12MHz; - } else if (sense->master_clock == 16000000) { - dev_dbg(&client->dev, "16MHz input clock\n"); - clkrc = CLKRC_16MHz; - } else if (sense->master_clock == 24000000) { - dev_dbg(&client->dev, "24MHz input clock\n"); - clkrc = CLKRC_24MHz; - } else { - dev_err(&client->dev, - "unsupported input clock, check platform data\n"); - return -EINVAL; - } - mclk = sense->master_clock; - priv->pclk_limit = sense->pixel_clock_max; - } else { - clkrc = CLKRC_24MHz; - mclk = 24000000; - priv->pclk_limit = 0; - dev_dbg(&client->dev, "using default 24MHz input clock\n"); - } - - clkrc |= to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); - - pclk = priv->pclk_max / GET_CLKRC_DIV(clkrc); - dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", - mclk / pclk, 10 * mclk % pclk / pclk); - - ret = ov6650_set_selection(sd, NULL, &sel); - if (!ret) - ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); - if (!ret) - ret = ov6650_reg_write(client, REG_CLKRC, clkrc); - if (!ret) - ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); - - if (!ret) { - mf->colorspace = priv->colorspace; - mf->width = priv->rect.width >> half_scale; - mf->height = priv->rect.height >> half_scale; - } - return ret; -} - -static int ov6650_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *mf = &format->format; - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - - if (format->pad) - return -EINVAL; - - if (is_unscaled_ok(mf->width, mf->height, &priv->rect)) - v4l_bound_align_image(&mf->width, 2, W_CIF, 1, - &mf->height, 2, H_CIF, 1, 0); - - mf->field = V4L2_FIELD_NONE; - - switch (mf->code) { - case MEDIA_BUS_FMT_Y10_1X10: - mf->code = MEDIA_BUS_FMT_Y8_1X8; - /* fall through */ - case MEDIA_BUS_FMT_Y8_1X8: - case MEDIA_BUS_FMT_YVYU8_2X8: - case MEDIA_BUS_FMT_YUYV8_2X8: - case MEDIA_BUS_FMT_VYUY8_2X8: - case MEDIA_BUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; - break; - default: - mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; - /* fall through */ - case MEDIA_BUS_FMT_SBGGR8_1X8: - mf->colorspace = V4L2_COLORSPACE_SRGB; - break; - } - - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) - return ov6650_s_fmt(sd, mf); - cfg->try_fmt = *mf; - - return 0; -} - -static int ov6650_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) -{ - if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes)) - return -EINVAL; - - code->code = ov6650_codes[code->index]; - return 0; -} - -static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - struct v4l2_captureparm *cp = &parms->parm.capture; - - if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - memset(cp, 0, sizeof(*cp)); - cp->capability = V4L2_CAP_TIMEPERFRAME; - cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, - priv->pclk_limit, priv->pclk_max)); - cp->timeperframe.denominator = FRAME_RATE_MAX; - - dev_dbg(&client->dev, "Frame interval: %u/%u s\n", - cp->timeperframe.numerator, cp->timeperframe.denominator); - - return 0; -} - -static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov6650 *priv = to_ov6650(client); - struct v4l2_captureparm *cp = &parms->parm.capture; - struct v4l2_fract *tpf = &cp->timeperframe; - int div, ret; - u8 clkrc; - - if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (cp->extendedmode != 0) - return -EINVAL; - - if (tpf->numerator == 0 || tpf->denominator == 0) - div = 1; /* Reset to full rate */ - else - div = (tpf->numerator * FRAME_RATE_MAX) / tpf->denominator; - - if (div == 0) - div = 1; - else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK)) - div = GET_CLKRC_DIV(CLKRC_DIV_MASK); - - /* - * Keep result to be used as tpf limit - * for subseqent clock divider calculations - */ - priv->tpf.numerator = div; - priv->tpf.denominator = FRAME_RATE_MAX; - - clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); - - ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK); - if (!ret) { - tpf->numerator = GET_CLKRC_DIV(clkrc); - tpf->denominator = FRAME_RATE_MAX; - } - - return ret; -} - -/* Soft reset the camera. This has nothing to do with the RESET pin! */ -static int ov6650_reset(struct i2c_client *client) -{ - int ret; - - dev_dbg(&client->dev, "reset\n"); - - ret = ov6650_reg_rmw(client, REG_COMA, COMA_RESET, 0); - if (ret) - dev_err(&client->dev, - "An error occurred while entering soft reset!\n"); - - return ret; -} - -/* program default register values */ -static int ov6650_prog_dflt(struct i2c_client *client) -{ - int ret; - - dev_dbg(&client->dev, "initializing\n"); - - ret = ov6650_reg_write(client, REG_COMA, 0); /* ~COMA_RESET */ - if (!ret) - ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_BAND_FILTER); - - return ret; -} - -static int ov6650_video_probe(struct i2c_client *client) -{ - struct ov6650 *priv = to_ov6650(client); - u8 pidh, pidl, midh, midl; - int ret; - - ret = ov6650_s_power(&priv->subdev, 1); - if (ret < 0) - return ret; - - /* - * check and show product ID and manufacturer ID - */ - ret = ov6650_reg_read(client, REG_PIDH, &pidh); - if (!ret) - ret = ov6650_reg_read(client, REG_PIDL, &pidl); - if (!ret) - ret = ov6650_reg_read(client, REG_MIDH, &midh); - if (!ret) - ret = ov6650_reg_read(client, REG_MIDL, &midl); - - if (ret) - goto done; - - if ((pidh != OV6650_PIDH) || (pidl != OV6650_PIDL)) { - dev_err(&client->dev, "Product ID error 0x%02x:0x%02x\n", - pidh, pidl); - ret = -ENODEV; - goto done; - } - - dev_info(&client->dev, - "ov6650 Product ID 0x%02x:0x%02x Manufacturer ID 0x%02x:0x%02x\n", - pidh, pidl, midh, midl); - - ret = ov6650_reset(client); - if (!ret) - ret = ov6650_prog_dflt(client); - if (!ret) - ret = v4l2_ctrl_handler_setup(&priv->hdl); - -done: - ov6650_s_power(&priv->subdev, 0); - return ret; -} - -static const struct v4l2_ctrl_ops ov6550_ctrl_ops = { - .g_volatile_ctrl = ov6550_g_volatile_ctrl, - .s_ctrl = ov6550_s_ctrl, -}; - -static const struct v4l2_subdev_core_ops ov6650_core_ops = { -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = ov6650_get_register, - .s_register = ov6650_set_register, -#endif - .s_power = ov6650_s_power, -}; - -/* Request bus settings on camera side */ -static int ov6650_g_mbus_config(struct v4l2_subdev *sd, - struct v4l2_mbus_config *cfg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - - cfg->flags = V4L2_MBUS_MASTER | - V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | - V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | - V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | - V4L2_MBUS_DATA_ACTIVE_HIGH; - cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); - - return 0; -} - -/* Alter bus settings on camera side */ -static int ov6650_s_mbus_config(struct v4l2_subdev *sd, - const struct v4l2_mbus_config *cfg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg); - int ret; - - if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) - ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0); - else - ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING); - if (ret) - return ret; - - if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) - ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0); - else - ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW); - if (ret) - return ret; - - if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) - ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0); - else - ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH); - - return ret; -} - -static const struct v4l2_subdev_video_ops ov6650_video_ops = { - .s_stream = ov6650_s_stream, - .g_parm = ov6650_g_parm, - .s_parm = ov6650_s_parm, - .g_mbus_config = ov6650_g_mbus_config, - .s_mbus_config = ov6650_s_mbus_config, -}; - -static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { - .enum_mbus_code = ov6650_enum_mbus_code, - .get_selection = ov6650_get_selection, - .set_selection = ov6650_set_selection, - .get_fmt = ov6650_get_fmt, - .set_fmt = ov6650_set_fmt, -}; - -static const struct v4l2_subdev_ops ov6650_subdev_ops = { - .core = &ov6650_core_ops, - .video = &ov6650_video_ops, - .pad = &ov6650_pad_ops, -}; - -/* - * i2c_driver function - */ -static int ov6650_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct ov6650 *priv; - struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - int ret; - - if (!ssdd) { - dev_err(&client->dev, "Missing platform_data for driver\n"); - return -EINVAL; - } - - priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&client->dev, - "Failed to allocate memory for private data!\n"); - return -ENOMEM; - } - - v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); - v4l2_ctrl_handler_init(&priv->hdl, 13); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN); - priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); - priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE); - priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_SATURATION, 0, 0xf, 1, 0x8); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80); - priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl, - &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO); - priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH); - v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops, - V4L2_CID_GAMMA, 0, 0xff, 1, 0x12); - - priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) - return priv->hdl.error; - - v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true); - v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true); - v4l2_ctrl_auto_cluster(2, &priv->autoexposure, - V4L2_EXPOSURE_MANUAL, true); - - priv->rect.left = DEF_HSTRT << 1; - priv->rect.top = DEF_VSTRT << 1; - priv->rect.width = W_CIF; - priv->rect.height = H_CIF; - priv->half_scale = false; - priv->code = MEDIA_BUS_FMT_YUYV8_2X8; - priv->colorspace = V4L2_COLORSPACE_JPEG; - - priv->clk = v4l2_clk_get(&client->dev, NULL); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto eclkget; - } - - ret = ov6650_video_probe(client); - if (ret) { - v4l2_clk_put(priv->clk); -eclkget: - v4l2_ctrl_handler_free(&priv->hdl); - } - - return ret; -} - -static int ov6650_remove(struct i2c_client *client) -{ - struct ov6650 *priv = to_ov6650(client); - - v4l2_clk_put(priv->clk); - v4l2_device_unregister_subdev(&priv->subdev); - v4l2_ctrl_handler_free(&priv->hdl); - return 0; -} - -static const struct i2c_device_id ov6650_id[] = { - { "ov6650", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ov6650_id); - -static struct i2c_driver ov6650_i2c_driver = { - .driver = { - .name = "ov6650", - }, - .probe = ov6650_probe, - .remove = ov6650_remove, - .id_table = ov6650_id, -}; - -module_i2c_driver(ov6650_i2c_driver); - -MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); -MODULE_AUTHOR("Janusz Krzysztofik "); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 299708e45e75500ba40b615896806c2f0877170f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 4 Jul 2017 11:21:14 -0300 Subject: media: cec: clear all cec_log_addrs fields The CEC version, vendor ID and OSD name were not cleared when clearing the current set of logical addresses. This was unexpected and somewhat confusing, so reset all these fields to their default values. Also document this since the documentation wasn't quite clear either. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst | 4 +++- drivers/media/cec/cec-adap.c | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index fcf863ab6f43..91cecc4d69cb 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -48,7 +48,9 @@ can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE` the ``EBUSY`` error code will be returned. To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields -will be ignored in that case. The adapter will go to the unconfigured state. +will be ignored in that case. The adapter will go to the unconfigured state and the +``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default +values (CEC version 2.0, no vendor ID and an empty OSD name). If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `), then this ioctl will block until all requested logical diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index bf45977b2823..5a2363cbaeb1 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1471,8 +1471,13 @@ int __cec_s_log_addrs(struct cec_adapter *adap, return -ENODEV; if (!log_addrs || log_addrs->num_log_addrs == 0) { - adap->log_addrs.num_log_addrs = 0; cec_adap_unconfigure(adap); + adap->log_addrs.num_log_addrs = 0; + for (i = 0; i < CEC_MAX_LOG_ADDRS; i++) + adap->log_addrs.log_addr[i] = CEC_LOG_ADDR_INVALID; + adap->log_addrs.osd_name[0] = '\0'; + adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; + adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; return 0; } -- cgit v1.2.3 From 15e809e961bad6c31f995100bf5e3c3f860b1b2c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 6 Jul 2017 11:09:52 -0300 Subject: media: cec: only increase the seqnr if CEC_TRANSMIT would return 0 The transmit code would increase the sequence number first thing, even though CEC_TRANSMIT would return an error due to a malformatted cec_msg struct later on. While valid behavior, this had the disadvantage of producing holes in the sequence list that made debugging harder. Only increase the sequence number when the whole message is validated. When debugging (i.e. with cec-ctl -M) the sequence numbering is now nicely increasing by 1 per message. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 5a2363cbaeb1..a311c52723a1 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -630,9 +630,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, msg->tx_nack_cnt = 0; msg->tx_low_drive_cnt = 0; msg->tx_error_cnt = 0; - msg->sequence = ++adap->sequence; - if (!msg->sequence) - msg->sequence = ++adap->sequence; + msg->sequence = 0; if (msg->reply && msg->timeout == 0) { /* Make sure the timeout isn't 0. */ @@ -671,6 +669,9 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, msg->tx_status = CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES; msg->tx_nack_cnt = 1; + msg->sequence = ++adap->sequence; + if (!msg->sequence) + msg->sequence = ++adap->sequence; return 0; } } @@ -705,6 +706,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, if (!data) return -ENOMEM; + msg->sequence = ++adap->sequence; + if (!msg->sequence) + msg->sequence = ++adap->sequence; + if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { msg->msg[2] = adap->phys_addr >> 8; msg->msg[3] = adap->phys_addr & 0xff; -- cgit v1.2.3 From bb789e03f2a140a80ddc7d18b7ef4d626c2a71d8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:34 -0300 Subject: media: cec: improve transmit timeout logging Kernel logging messes up the upcoming low-level CEC monitoring support which is very time-sensitive. So change the debug level of this message but keep a counter that is shown in the debugfs status log. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 17 +++++++++++++---- include/media/cec.h | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index a311c52723a1..7bd4d7d8713c 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -394,13 +394,17 @@ int cec_thread_func(void *_adap) if (adap->transmitting && timeout) { /* - * If we timeout, then log that. This really shouldn't - * happen and is an indication of a faulty CEC adapter - * driver, or the CEC bus is in some weird state. + * If we timeout, then log that. Normally this does + * not happen and it is an indication of a faulty CEC + * adapter driver, or the CEC bus is in some weird + * state. On rare occasions it can happen if there is + * so much traffic on the bus that the adapter was + * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). */ - dprintk(0, "%s: message %*ph timed out!\n", __func__, + dprintk(1, "%s: message %*ph timed out\n", __func__, adap->transmitting->msg.len, adap->transmitting->msg.msg); + adap->tx_timeouts++; /* Just give up on this. */ cec_data_cancel(adap->transmitting); goto unlock; @@ -1951,6 +1955,11 @@ int cec_adap_status(struct seq_file *file, void *priv) if (adap->monitor_all_cnt) seq_printf(file, "file handles in Monitor All mode: %u\n", adap->monitor_all_cnt); + if (adap->tx_timeouts) { + seq_printf(file, "transmit timeouts: %u\n", + adap->tx_timeouts); + adap->tx_timeouts = 0; + } data = adap->transmitting; if (data) seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", diff --git a/include/media/cec.h b/include/media/cec.h index 56643b27e4b8..e32b0e1a81a4 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -174,6 +174,8 @@ struct cec_adapter { bool passthrough; struct cec_log_addrs log_addrs; + u32 tx_timeouts; + #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; #endif -- cgit v1.2.3 From 0861ad14c6cfc9dc8bcde44bc23a7a355167eb9f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:35 -0300 Subject: media: cec: add *_ts variants for transmit_done/received_msg Currently the transmit_(attempt_)done and received_msg functions set the timestamp themselves. For the upcoming low-level pin API we need to pass this as an argument instead. So make _ts variants that allow the caller to specify the timestamp. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 35 +++++++++++++++++++---------------- include/media/cec.h | 32 ++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 7bd4d7d8713c..82c1633f5b92 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -471,12 +471,12 @@ unlock: /* * Called by the CEC adapter if a transmit finished. */ -void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, - u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt) +void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, + u8 error_cnt, ktime_t ts) { struct cec_data *data; struct cec_msg *msg; - u64 ts = ktime_get_ns(); dprintk(2, "%s: status %02x\n", __func__, status); mutex_lock(&adap->lock); @@ -496,7 +496,7 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, /* Drivers must fill in the status! */ WARN_ON(status == 0); - msg->tx_ts = ts; + msg->tx_ts = ktime_to_ns(ts); msg->tx_status |= status; msg->tx_arb_lost_cnt += arb_lost_cnt; msg->tx_nack_cnt += nack_cnt; @@ -559,25 +559,26 @@ wake_thread: unlock: mutex_unlock(&adap->lock); } -EXPORT_SYMBOL_GPL(cec_transmit_done); +EXPORT_SYMBOL_GPL(cec_transmit_done_ts); -void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) +void cec_transmit_attempt_done_ts(struct cec_adapter *adap, + u8 status, ktime_t ts) { switch (status) { case CEC_TX_STATUS_OK: - cec_transmit_done(adap, status, 0, 0, 0, 0); + cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts); return; case CEC_TX_STATUS_ARB_LOST: - cec_transmit_done(adap, status, 1, 0, 0, 0); + cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts); return; case CEC_TX_STATUS_NACK: - cec_transmit_done(adap, status, 0, 1, 0, 0); + cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts); return; case CEC_TX_STATUS_LOW_DRIVE: - cec_transmit_done(adap, status, 0, 0, 1, 0); + cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts); return; case CEC_TX_STATUS_ERROR: - cec_transmit_done(adap, status, 0, 0, 0, 1); + cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts); return; default: /* Should never happen */ @@ -585,7 +586,7 @@ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status) return; } } -EXPORT_SYMBOL_GPL(cec_transmit_attempt_done); +EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts); /* * Called when waiting for a reply times out. @@ -721,7 +722,8 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, if (msg->timeout) dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", - __func__, msg->len, msg->msg, msg->reply, !block ? ", nb" : ""); + __func__, msg->len, msg->msg, msg->reply, + !block ? ", nb" : ""); else dprintk(2, "%s: %*ph%s\n", __func__, msg->len, msg->msg, !block ? " (nb)" : ""); @@ -918,7 +920,8 @@ static const u8 cec_msg_size[256] = { }; /* Called by the CEC adapter if a message is received */ -void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) +void cec_received_msg_ts(struct cec_adapter *adap, + struct cec_msg *msg, ktime_t ts) { struct cec_data *data; u8 msg_init = cec_msg_initiator(msg); @@ -946,7 +949,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) cec_has_log_addr(adap, msg_init)) return; - msg->rx_ts = ktime_get_ns(); + msg->rx_ts = ktime_to_ns(ts); msg->rx_status = CEC_RX_STATUS_OK; msg->sequence = msg->reply = msg->timeout = 0; msg->tx_status = 0; @@ -1111,7 +1114,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg) */ cec_receive_notify(adap, msg, is_reply); } -EXPORT_SYMBOL_GPL(cec_received_msg); +EXPORT_SYMBOL_GPL(cec_received_msg_ts); /* Logical Address Handling */ diff --git a/include/media/cec.h b/include/media/cec.h index e32b0e1a81a4..e1e60dbb66c3 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -228,15 +228,39 @@ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, bool block); /* Called by the adapter */ -void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt, - u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt); +void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, + u8 error_cnt, ktime_t ts); + +static inline void cec_transmit_done(struct cec_adapter *adap, u8 status, + u8 arb_lost_cnt, u8 nack_cnt, + u8 low_drive_cnt, u8 error_cnt) +{ + cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt, + low_drive_cnt, error_cnt, ktime_get()); +} /* * Simplified version of cec_transmit_done for hardware that doesn't retry * failed transmits. So this is always just one attempt in which case * the status is sufficient. */ -void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status); -void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); +void cec_transmit_attempt_done_ts(struct cec_adapter *adap, + u8 status, ktime_t ts); + +static inline void cec_transmit_attempt_done(struct cec_adapter *adap, + u8 status) +{ + cec_transmit_attempt_done_ts(adap, status, ktime_get()); +} + +void cec_received_msg_ts(struct cec_adapter *adap, + struct cec_msg *msg, ktime_t ts); + +static inline void cec_received_msg(struct cec_adapter *adap, + struct cec_msg *msg) +{ + cec_received_msg_ts(adap, msg, ktime_get()); +} /** * cec_get_edid_phys_addr() - find and return the physical address -- cgit v1.2.3 From e6259b5f7ab74e399f838cb1abdc12f3e28668f4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:36 -0300 Subject: media: cec: add adap_free op This is needed for CEC adapters that allocate resources that have to be freed before the cec_adapter is deleted. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-core.c | 2 ++ include/media/cec.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index b516d599d6c4..2e5765344d07 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -374,6 +374,8 @@ void cec_delete_adapter(struct cec_adapter *adap) kthread_stop(adap->kthread); if (adap->kthread_config) kthread_stop(adap->kthread_config); + if (adap->ops->adap_free) + adap->ops->adap_free(adap); #ifdef CONFIG_MEDIA_CEC_RC rc_free_device(adap->rc); #endif diff --git a/include/media/cec.h b/include/media/cec.h index e1e60dbb66c3..37768203572d 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -114,6 +114,7 @@ struct cec_adap_ops { int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level CEC message callback */ int (*received)(struct cec_adapter *adap, struct cec_msg *msg); -- cgit v1.2.3 From 6b2bbb08747a56dcf4ee33606a06025eca571260 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:39 -0300 Subject: media: cec: rework the cec event handling Event handling was always fairly simplistic since there were only two events. With the addition of pin events this needed to be redesigned. The state_change and lost_msgs events are now core events with the guarantee that the last state is always available. The new pin events are a queue of events (up to 64 for each event) and the oldest event will be dropped if the application cannot keep up. Lost events are marked with a new event flag. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 128 +++++++++++++++++++++++++------------------ drivers/media/cec/cec-api.c | 48 +++++++++++----- include/media/cec.h | 14 ++++- include/uapi/linux/cec.h | 3 +- 4 files changed, 124 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 82c1633f5b92..5080d7aa6105 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -78,42 +78,62 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr * Queue a new event for this filehandle. If ts == 0, then set it * to the current time. * - * The two events that are currently defined do not need to keep track - * of intermediate events, so no actual queue of events is needed, - * instead just store the latest state and the total number of lost - * messages. - * - * Should new events be added in the future that require intermediate - * results to be queued as well, then a proper queue data structure is - * required. But until then, just keep it simple. + * We keep a queue of at most max_event events where max_event differs + * per event. If the queue becomes full, then drop the oldest event and + * keep track of how many events we've dropped. */ void cec_queue_event_fh(struct cec_fh *fh, const struct cec_event *new_ev, u64 ts) { - struct cec_event *ev = &fh->events[new_ev->event - 1]; + static const u8 max_events[CEC_NUM_EVENTS] = { + 1, 1, 64, 64, + }; + struct cec_event_entry *entry; + unsigned int ev_idx = new_ev->event - 1; + + if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events))) + return; if (ts == 0) ts = ktime_get_ns(); mutex_lock(&fh->lock); - if (new_ev->event == CEC_EVENT_LOST_MSGS && - fh->pending_events & (1 << new_ev->event)) { - /* - * If there is already a lost_msgs event, then just - * update the lost_msgs count. This effectively - * merges the old and new events into one. - */ - ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs; - goto unlock; - } + if (ev_idx < CEC_NUM_CORE_EVENTS) + entry = &fh->core_events[ev_idx]; + else + entry = kmalloc(sizeof(*entry), GFP_KERNEL); + if (entry) { + if (new_ev->event == CEC_EVENT_LOST_MSGS && + fh->queued_events[ev_idx]) { + entry->ev.lost_msgs.lost_msgs += + new_ev->lost_msgs.lost_msgs; + goto unlock; + } + entry->ev = *new_ev; + entry->ev.ts = ts; + + if (fh->queued_events[ev_idx] < max_events[ev_idx]) { + /* Add new msg at the end of the queue */ + list_add_tail(&entry->list, &fh->events[ev_idx]); + fh->queued_events[ev_idx]++; + fh->total_queued_events++; + goto unlock; + } - /* - * Intermediate states are not interesting, so just - * overwrite any older event. - */ - *ev = *new_ev; - ev->ts = ts; - fh->pending_events |= 1 << new_ev->event; + if (ev_idx >= CEC_NUM_CORE_EVENTS) { + list_add_tail(&entry->list, &fh->events[ev_idx]); + /* drop the oldest event */ + entry = list_first_entry(&fh->events[ev_idx], + struct cec_event_entry, list); + list_del(&entry->list); + kfree(entry); + } + } + /* Mark that events were lost */ + entry = list_first_entry_or_null(&fh->events[ev_idx], + struct cec_event_entry, list); + if (entry) + entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS; unlock: mutex_unlock(&fh->lock); @@ -134,46 +154,50 @@ static void cec_queue_event(struct cec_adapter *adap, } /* - * Queue a new message for this filehandle. If there is no more room - * in the queue, then send the LOST_MSGS event instead. + * Queue a new message for this filehandle. + * + * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the + * queue becomes full, then drop the oldest message and keep track + * of how many messages we've dropped. */ static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) { - static const struct cec_event ev_lost_msg = { - .ts = 0, + static const struct cec_event ev_lost_msgs = { .event = CEC_EVENT_LOST_MSGS, - .flags = 0, - { - .lost_msgs.lost_msgs = 1, - }, + .lost_msgs.lost_msgs = 1, }; struct cec_msg_entry *entry; mutex_lock(&fh->lock); entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto lost_msgs; - - entry->msg = *msg; - /* Add new msg at the end of the queue */ - list_add_tail(&entry->list, &fh->msgs); + if (entry) { + entry->msg = *msg; + /* Add new msg at the end of the queue */ + list_add_tail(&entry->list, &fh->msgs); + + if (fh->queued_msgs < CEC_MAX_MSG_RX_QUEUE_SZ) { + /* All is fine if there is enough room */ + fh->queued_msgs++; + mutex_unlock(&fh->lock); + wake_up_interruptible(&fh->wait); + return; + } - /* - * if the queue now has more than CEC_MAX_MSG_RX_QUEUE_SZ - * messages, drop the oldest one and send a lost message event. - */ - if (fh->queued_msgs == CEC_MAX_MSG_RX_QUEUE_SZ) { + /* + * if the message queue is full, then drop the oldest one and + * send a lost message event. + */ + entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list); list_del(&entry->list); - goto lost_msgs; + kfree(entry); } - fh->queued_msgs++; mutex_unlock(&fh->lock); - wake_up_interruptible(&fh->wait); - return; -lost_msgs: - mutex_unlock(&fh->lock); - cec_queue_event_fh(fh, &ev_lost_msg, 0); + /* + * We lost a message, either because kmalloc failed or the queue + * was full. + */ + cec_queue_event_fh(fh, &ev_lost_msgs, ktime_get_ns()); } /* diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index f7eb4c54a354..48bef1c718ad 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -57,7 +57,7 @@ static unsigned int cec_poll(struct file *filp, res |= POLLOUT | POLLWRNORM; if (fh->queued_msgs) res |= POLLIN | POLLRDNORM; - if (fh->pending_events) + if (fh->total_queued_events) res |= POLLPRI; poll_wait(filp, &fh->wait, poll); mutex_unlock(&adap->lock); @@ -289,15 +289,17 @@ static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh, static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, bool block, struct cec_event __user *parg) { - struct cec_event *ev = NULL; + struct cec_event_entry *ev = NULL; u64 ts = ~0ULL; unsigned int i; + unsigned int ev_idx; long err = 0; mutex_lock(&fh->lock); - while (!fh->pending_events && block) { + while (!fh->total_queued_events && block) { mutex_unlock(&fh->lock); - err = wait_event_interruptible(fh->wait, fh->pending_events); + err = wait_event_interruptible(fh->wait, + fh->total_queued_events); if (err) return err; mutex_lock(&fh->lock); @@ -305,23 +307,29 @@ static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh, /* Find the oldest event */ for (i = 0; i < CEC_NUM_EVENTS; i++) { - if (fh->pending_events & (1 << (i + 1)) && - fh->events[i].ts <= ts) { - ev = &fh->events[i]; - ts = ev->ts; + struct cec_event_entry *entry = + list_first_entry_or_null(&fh->events[i], + struct cec_event_entry, list); + + if (entry && entry->ev.ts <= ts) { + ev = entry; + ev_idx = i; + ts = ev->ev.ts; } } + if (!ev) { err = -EAGAIN; goto unlock; } + list_del(&ev->list); - if (copy_to_user(parg, ev, sizeof(*ev))) { + if (copy_to_user(parg, &ev->ev, sizeof(ev->ev))) err = -EFAULT; - goto unlock; - } - - fh->pending_events &= ~(1 << ev->event); + if (ev_idx >= CEC_NUM_CORE_EVENTS) + kfree(ev); + fh->queued_events[ev_idx]--; + fh->total_queued_events--; unlock: mutex_unlock(&fh->lock); @@ -495,6 +503,7 @@ static int cec_open(struct inode *inode, struct file *filp) .event = CEC_EVENT_STATE_CHANGE, .flags = CEC_EVENT_FL_INITIAL_STATE, }; + unsigned int i; int err; if (!fh) @@ -502,6 +511,8 @@ static int cec_open(struct inode *inode, struct file *filp) INIT_LIST_HEAD(&fh->msgs); INIT_LIST_HEAD(&fh->xfer_list); + for (i = 0; i < CEC_NUM_EVENTS; i++) + INIT_LIST_HEAD(&fh->events[i]); mutex_init(&fh->lock); init_waitqueue_head(&fh->wait); @@ -544,6 +555,7 @@ static int cec_release(struct inode *inode, struct file *filp) struct cec_devnode *devnode = cec_devnode_data(filp); struct cec_adapter *adap = to_cec_adapter(devnode); struct cec_fh *fh = filp->private_data; + unsigned int i; mutex_lock(&adap->lock); if (adap->cec_initiator == fh) @@ -585,6 +597,16 @@ static int cec_release(struct inode *inode, struct file *filp) list_del(&entry->list); kfree(entry); } + for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) { + while (!list_empty(&fh->events[i])) { + struct cec_event_entry *entry = + list_first_entry(&fh->events[i], + struct cec_event_entry, list); + + list_del(&entry->list); + kfree(entry); + } + } kfree(fh); cec_put_device(devnode); diff --git a/include/media/cec.h b/include/media/cec.h index 37768203572d..6cc862af74e5 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -81,7 +81,13 @@ struct cec_msg_entry { struct cec_msg msg; }; -#define CEC_NUM_EVENTS CEC_EVENT_LOST_MSGS +struct cec_event_entry { + struct list_head list; + struct cec_event ev; +}; + +#define CEC_NUM_CORE_EVENTS 2 +#define CEC_NUM_EVENTS CEC_EVENT_PIN_HIGH struct cec_fh { struct list_head list; @@ -92,9 +98,11 @@ struct cec_fh { /* Events */ wait_queue_head_t wait; - unsigned int pending_events; - struct cec_event events[CEC_NUM_EVENTS]; struct mutex lock; + struct list_head events[CEC_NUM_EVENTS]; /* queued events */ + u8 queued_events[CEC_NUM_EVENTS]; + unsigned int total_queued_events; + struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS]; struct list_head msgs; /* queued messages */ unsigned int queued_msgs; }; diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index bba73f33c8aa..d87a67b0bb06 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -412,6 +412,7 @@ struct cec_log_addrs { #define CEC_EVENT_PIN_HIGH 4 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) +#define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1) /** * struct cec_event_state_change - used when the CEC adapter changes state. @@ -424,7 +425,7 @@ struct cec_event_state_change { }; /** - * struct cec_event_lost_msgs - tells you how many messages were lost due. + * struct cec_event_lost_msgs - tells you how many messages were lost. * @lost_msgs: how many messages were lost. */ struct cec_event_lost_msgs { -- cgit v1.2.3 From b8d62f50b1df2571afcf47107bbbe9cd60f8aafd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:41 -0300 Subject: media: cec: add core support for low-level CEC pin monitoring Add support for the new MONITOR_PIN mode. Add the cec_pin_event function that the CEC pin code will call to queue pin change events. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 16 ++++++++++++++++ drivers/media/cec/cec-api.c | 15 +++++++++++++-- include/media/cec.h | 11 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 5080d7aa6105..b0bd466f75e2 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -153,6 +153,22 @@ static void cec_queue_event(struct cec_adapter *adap, mutex_unlock(&adap->devnode.lock); } +/* Notify userspace that the CEC pin changed state at the given time. */ +void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts) +{ + struct cec_event ev = { + .event = is_high ? CEC_EVENT_PIN_HIGH : CEC_EVENT_PIN_LOW, + }; + struct cec_fh *fh; + + mutex_lock(&adap->devnode.lock); + list_for_each_entry(fh, &adap->devnode.fhs, list) + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); + mutex_unlock(&adap->devnode.lock); +} +EXPORT_SYMBOL_GPL(cec_queue_pin_event); + /* * Queue a new message for this filehandle. * diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 48bef1c718ad..14279958dca1 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -370,6 +370,10 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, !(adap->capabilities & CEC_CAP_MONITOR_ALL)) return -EINVAL; + if (mode_follower == CEC_MODE_MONITOR_PIN && + !(adap->capabilities & CEC_CAP_MONITOR_PIN)) + return -EINVAL; + /* Follower modes should always be able to send CEC messages */ if ((mode_initiator == CEC_MODE_NO_INITIATOR || !(adap->capabilities & CEC_CAP_TRANSMIT)) && @@ -378,11 +382,11 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, return -EINVAL; /* Monitor modes require CEC_MODE_NO_INITIATOR */ - if (mode_initiator && mode_follower >= CEC_MODE_MONITOR) + if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) return -EINVAL; /* Monitor modes require CAP_NET_ADMIN */ - if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN)) + if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN)) return -EPERM; mutex_lock(&adap->lock); @@ -421,8 +425,13 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (fh->mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt--; + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + adap->monitor_pin_cnt--; if (mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt++; + if (mode_follower == CEC_MODE_MONITOR_PIN) { + adap->monitor_pin_cnt++; + } if (mode_follower == CEC_MODE_EXCL_FOLLOWER || mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { adap->passthrough = @@ -566,6 +575,8 @@ static int cec_release(struct inode *inode, struct file *filp) } if (fh->mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt--; + if (fh->mode_follower == CEC_MODE_MONITOR_PIN) + adap->monitor_pin_cnt--; if (fh->mode_follower == CEC_MODE_MONITOR_ALL) cec_monitor_all_cnt_dec(adap); mutex_unlock(&adap->lock); diff --git a/include/media/cec.h b/include/media/cec.h index 6cc862af74e5..d983960b37ad 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -177,6 +177,7 @@ struct cec_adapter { bool is_configuring; bool is_configured; u32 monitor_all_cnt; + u32 monitor_pin_cnt; u32 follower_cnt; struct cec_fh *cec_follower; struct cec_fh *cec_initiator; @@ -271,6 +272,16 @@ static inline void cec_received_msg(struct cec_adapter *adap, cec_received_msg_ts(adap, msg, ktime_get()); } +/** + * cec_queue_pin_event() - queue a pin event with a given timestamp. + * + * @adap: pointer to the cec adapter + * @is_high: when true the pin is high, otherwise it is low + * @ts: the timestamp for this event + * + */ +void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts); + /** * cec_get_edid_phys_addr() - find and return the physical address * -- cgit v1.2.3 From ea5c8ef296681b53480ebeeffd06083bb60e693d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 03:30:42 -0300 Subject: media: cec-pin: add low-level pin hardware support Add support for CEC hardware that relies on low-level pin polling or GPIO interrupts. One example is the Allwinner SoC. But any GPIO-based CEC implementation can use this as well. A GPIO implementation is very suitable as well for debugging: it can use interrupts to detect state changes and report it. Userspace can then verify if the bus traffic is correct. This also makes error injection possible. The disadvantage is that it is hard to get the timings right since linux isn't a hard realtime system. In general on an idle system it works quite well, but under load the timer will miss its mark every so often. The debugfs file /sys/kernel/debug/cec/cecX/status gives some statistics with respect to the timer overruns. When the adapter is unconfigured and the low-level driver supports interrupts, then the interrupt will be used to detect changes. This should be quite accurate. But when the adapter is configured a hrtimer has to be used. The hrtimer implements a state machine where for each state the code will read the bus or drive the bus and go on to the next state. It will re-arm the timer with a delay based on the next state. Signed-off-by: Hans Verkuil Reviewed-by: Maxime Ripard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 3 + drivers/media/cec/Makefile | 4 + drivers/media/cec/cec-api.c | 10 + drivers/media/cec/cec-pin.c | 794 ++++++++++++++++++++++++++++++++++++++++++++ include/media/cec-pin.h | 183 ++++++++++ include/media/cec.h | 4 + 6 files changed, 998 insertions(+) create mode 100644 drivers/media/cec/cec-pin.c create mode 100644 include/media/cec-pin.h (limited to 'drivers') diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 55d9c2b82b7e..94d4e7759127 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -8,6 +8,9 @@ config CEC_CORE config CEC_NOTIFIER bool +config CEC_PIN + bool + menuconfig MEDIA_SUPPORT tristate "Multimedia support" depends on HAS_IOMEM diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile index eaf408e64669..3353c1741961 100644 --- a/drivers/media/cec/Makefile +++ b/drivers/media/cec/Makefile @@ -4,4 +4,8 @@ ifeq ($(CONFIG_CEC_NOTIFIER),y) cec-objs += cec-notifier.o endif +ifeq ($(CONFIG_CEC_PIN),y) + cec-objs += cec-pin.o +endif + obj-$(CONFIG_CEC_CORE) += cec.o diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 14279958dca1..8dd16e263452 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -30,6 +30,7 @@ #include #include +#include #include "cec-priv.h" static inline struct cec_devnode *cec_devnode_data(struct file *filp) @@ -430,6 +431,15 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt++; if (mode_follower == CEC_MODE_MONITOR_PIN) { +#ifdef CONFIG_CEC_PIN + struct cec_event ev = { + .flags = CEC_EVENT_FL_INITIAL_STATE, + }; + + ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_HIGH : + CEC_EVENT_PIN_LOW; + cec_queue_event_fh(fh, &ev, 0); +#endif adap->monitor_pin_cnt++; } if (mode_follower == CEC_MODE_EXCL_FOLLOWER || diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c new file mode 100644 index 000000000000..03f800e5ec1f --- /dev/null +++ b/drivers/media/cec/cec-pin.c @@ -0,0 +1,794 @@ +/* + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include + +/* All timings are in microseconds */ + +/* start bit timings */ +#define CEC_TIM_START_BIT_LOW 3700 +#define CEC_TIM_START_BIT_LOW_MIN 3500 +#define CEC_TIM_START_BIT_LOW_MAX 3900 +#define CEC_TIM_START_BIT_TOTAL 4500 +#define CEC_TIM_START_BIT_TOTAL_MIN 4300 +#define CEC_TIM_START_BIT_TOTAL_MAX 4700 + +/* data bit timings */ +#define CEC_TIM_DATA_BIT_0_LOW 1500 +#define CEC_TIM_DATA_BIT_0_LOW_MIN 1300 +#define CEC_TIM_DATA_BIT_0_LOW_MAX 1700 +#define CEC_TIM_DATA_BIT_1_LOW 600 +#define CEC_TIM_DATA_BIT_1_LOW_MIN 400 +#define CEC_TIM_DATA_BIT_1_LOW_MAX 800 +#define CEC_TIM_DATA_BIT_TOTAL 2400 +#define CEC_TIM_DATA_BIT_TOTAL_MIN 2050 +#define CEC_TIM_DATA_BIT_TOTAL_MAX 2750 +/* earliest safe time to sample the bit state */ +#define CEC_TIM_DATA_BIT_SAMPLE 850 +/* earliest time the bit is back to 1 (T7 + 50) */ +#define CEC_TIM_DATA_BIT_HIGH 1750 + +/* when idle, sample once per millisecond */ +#define CEC_TIM_IDLE_SAMPLE 1000 +/* when processing the start bit, sample twice per millisecond */ +#define CEC_TIM_START_BIT_SAMPLE 500 +/* when polling for a state change, sample once every 50 micoseconds */ +#define CEC_TIM_SAMPLE 50 + +#define CEC_TIM_LOW_DRIVE_ERROR (1.5 * CEC_TIM_DATA_BIT_TOTAL) + +struct cec_state { + const char * const name; + unsigned int usecs; +}; + +static const struct cec_state states[CEC_PIN_STATES] = { + { "Off", 0 }, + { "Idle", CEC_TIM_IDLE_SAMPLE }, + { "Tx Wait", CEC_TIM_SAMPLE }, + { "Tx Wait for High", CEC_TIM_IDLE_SAMPLE }, + { "Tx Start Bit Low", CEC_TIM_START_BIT_LOW }, + { "Tx Start Bit High", CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW }, + { "Tx Data 0 Low", CEC_TIM_DATA_BIT_0_LOW }, + { "Tx Data 0 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW }, + { "Tx Data 1 Low", CEC_TIM_DATA_BIT_1_LOW }, + { "Tx Data 1 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW }, + { "Tx Data 1 Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW }, + { "Tx Data 1 Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE }, + { "Rx Start Bit Low", CEC_TIM_SAMPLE }, + { "Rx Start Bit High", CEC_TIM_SAMPLE }, + { "Rx Data Sample", CEC_TIM_DATA_BIT_SAMPLE }, + { "Rx Data Post Sample", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE }, + { "Rx Data High", CEC_TIM_SAMPLE }, + { "Rx Ack Low", CEC_TIM_DATA_BIT_0_LOW }, + { "Rx Ack Low Post", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW }, + { "Rx Ack High Post", CEC_TIM_DATA_BIT_HIGH }, + { "Rx Ack Finish", CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_DATA_BIT_HIGH }, + { "Rx Low Drive", CEC_TIM_LOW_DRIVE_ERROR }, + { "Rx Irq", 0 }, +}; + +static void cec_pin_update(struct cec_pin *pin, bool v, bool force) +{ + if (!force && v == pin->cur_value) + return; + + pin->cur_value = v; + if (atomic_read(&pin->work_pin_events) < CEC_NUM_PIN_EVENTS) { + pin->work_pin_is_high[pin->work_pin_events_wr] = v; + pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); + pin->work_pin_events_wr = + (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS; + atomic_inc(&pin->work_pin_events); + } + wake_up_interruptible(&pin->kthread_waitq); +} + +static bool cec_pin_read(struct cec_pin *pin) +{ + bool v = pin->ops->read(pin->adap); + + cec_pin_update(pin, v, false); + return v; +} + +static void cec_pin_low(struct cec_pin *pin) +{ + pin->ops->low(pin->adap); + cec_pin_update(pin, false, false); +} + +static bool cec_pin_high(struct cec_pin *pin) +{ + pin->ops->high(pin->adap); + return cec_pin_read(pin); +} + +static void cec_pin_to_idle(struct cec_pin *pin) +{ + /* + * Reset all status fields, release the bus and + * go to idle state. + */ + pin->rx_bit = pin->tx_bit = 0; + pin->rx_msg.len = 0; + memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); + pin->state = CEC_ST_IDLE; + pin->ts = 0; +} + +/* + * Handle Transmit-related states + * + * Basic state changes when transmitting: + * + * Idle -> Tx Wait (waiting for the end of signal free time) -> + * Tx Start Bit Low -> Tx Start Bit High -> + * + * Regular data bits + EOM: + * Tx Data 0 Low -> Tx Data 0 High -> + * or: + * Tx Data 1 Low -> Tx Data 1 High -> + * + * First 4 data bits or Ack bit: + * Tx Data 0 Low -> Tx Data 0 High -> + * or: + * Tx Data 1 Low -> Tx Data 1 High -> Tx Data 1 Pre Sample -> + * Tx Data 1 Post Sample -> + * + * After the last Ack go to Idle. + * + * If it detects a Low Drive condition then: + * Tx Wait For High -> Idle + * + * If it loses arbitration, then it switches to state Rx Data Post Sample. + */ +static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) +{ + bool v; + bool is_ack_bit, ack; + + switch (pin->state) { + case CEC_ST_TX_WAIT_FOR_HIGH: + if (cec_pin_read(pin)) + cec_pin_to_idle(pin); + break; + + case CEC_ST_TX_START_BIT_LOW: + pin->state = CEC_ST_TX_START_BIT_HIGH; + /* Generate start bit */ + cec_pin_high(pin); + break; + + case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: + /* If the read value is 1, then all is OK */ + if (!cec_pin_read(pin)) { + /* + * It's 0, so someone detected an error and pulled the + * line low for 1.5 times the nominal bit period. + */ + pin->tx_msg.len = 0; + pin->work_tx_ts = ts; + pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; + pin->state = CEC_ST_TX_WAIT_FOR_HIGH; + wake_up_interruptible(&pin->kthread_waitq); + break; + } + if (pin->tx_nacked) { + cec_pin_to_idle(pin); + pin->tx_msg.len = 0; + pin->work_tx_ts = ts; + pin->work_tx_status = CEC_TX_STATUS_NACK; + wake_up_interruptible(&pin->kthread_waitq); + break; + } + /* fall through */ + case CEC_ST_TX_DATA_BIT_0_HIGH: + case CEC_ST_TX_DATA_BIT_1_HIGH: + pin->tx_bit++; + /* fall through */ + case CEC_ST_TX_START_BIT_HIGH: + if (pin->tx_bit / 10 >= pin->tx_msg.len) { + cec_pin_to_idle(pin); + pin->tx_msg.len = 0; + pin->work_tx_ts = ts; + pin->work_tx_status = CEC_TX_STATUS_OK; + wake_up_interruptible(&pin->kthread_waitq); + break; + } + + switch (pin->tx_bit % 10) { + default: + v = pin->tx_msg.msg[pin->tx_bit / 10] & + (1 << (7 - (pin->tx_bit % 10))); + pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : + CEC_ST_TX_DATA_BIT_0_LOW; + break; + case 8: + v = pin->tx_bit / 10 == pin->tx_msg.len - 1; + pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : + CEC_ST_TX_DATA_BIT_0_LOW; + break; + case 9: + pin->state = CEC_ST_TX_DATA_BIT_1_LOW; + break; + } + cec_pin_low(pin); + break; + + case CEC_ST_TX_DATA_BIT_0_LOW: + case CEC_ST_TX_DATA_BIT_1_LOW: + v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW; + pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH : + CEC_ST_TX_DATA_BIT_0_HIGH; + is_ack_bit = pin->tx_bit % 10 == 9; + if (v && (pin->tx_bit < 4 || is_ack_bit)) + pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE; + cec_pin_high(pin); + break; + + case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: + /* Read the CEC value at the sample time */ + v = cec_pin_read(pin); + is_ack_bit = pin->tx_bit % 10 == 9; + /* + * If v == 0 and we're within the first 4 bits + * of the initiator, then someone else started + * transmitting and we lost the arbitration + * (i.e. the logical address of the other + * transmitter has more leading 0 bits in the + * initiator). + */ + if (!v && !is_ack_bit) { + pin->tx_msg.len = 0; + pin->work_tx_ts = ts; + pin->work_tx_status = CEC_TX_STATUS_ARB_LOST; + wake_up_interruptible(&pin->kthread_waitq); + pin->rx_bit = pin->tx_bit; + pin->tx_bit = 0; + memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); + pin->rx_msg.msg[0] = pin->tx_msg.msg[0]; + pin->rx_msg.msg[0] &= ~(1 << (7 - pin->rx_bit)); + pin->rx_msg.len = 0; + pin->state = CEC_ST_RX_DATA_POST_SAMPLE; + pin->rx_bit++; + break; + } + pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE; + if (!is_ack_bit) + break; + /* Was the message ACKed? */ + ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; + if (!ack) { + /* + * Note: the CEC spec is ambiguous regarding + * what action to take when a NACK appears + * before the last byte of the payload was + * transmitted: either stop transmitting + * immediately, or wait until the last byte + * was transmitted. + * + * Most CEC implementations appear to stop + * immediately, and that's what we do here + * as well. + */ + pin->tx_nacked = true; + } + break; + + default: + break; + } +} + +/* + * Handle Receive-related states + * + * Basic state changes when receiving: + * + * Rx Start Bit Low -> Rx Start Bit High -> + * Regular data bits + EOM: + * Rx Data Sample -> Rx Data Post Sample -> Rx Data High -> + * Ack bit 0: + * Rx Ack Low -> Rx Ack Low Post -> Rx Data High -> + * Ack bit 1: + * Rx Ack High Post -> Rx Data High -> + * Ack bit 0 && EOM: + * Rx Ack Low -> Rx Ack Low Post -> Rx Ack Finish -> Idle + */ +static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) +{ + s32 delta; + bool v; + bool ack; + bool bcast, for_us; + u8 dest; + + switch (pin->state) { + /* Receive states */ + case CEC_ST_RX_START_BIT_LOW: + v = cec_pin_read(pin); + if (!v) + break; + pin->state = CEC_ST_RX_START_BIT_HIGH; + delta = ktime_us_delta(ts, pin->ts); + pin->ts = ts; + /* Start bit low is too short, go back to idle */ + if (delta < CEC_TIM_START_BIT_LOW_MIN - + CEC_TIM_IDLE_SAMPLE) { + cec_pin_to_idle(pin); + } + break; + + case CEC_ST_RX_START_BIT_HIGH: + v = cec_pin_read(pin); + delta = ktime_us_delta(ts, pin->ts); + if (v && delta > CEC_TIM_START_BIT_TOTAL_MAX - + CEC_TIM_START_BIT_LOW_MIN) { + cec_pin_to_idle(pin); + break; + } + if (v) + break; + pin->state = CEC_ST_RX_DATA_SAMPLE; + pin->ts = ts; + pin->rx_eom = false; + break; + + case CEC_ST_RX_DATA_SAMPLE: + v = cec_pin_read(pin); + pin->state = CEC_ST_RX_DATA_POST_SAMPLE; + switch (pin->rx_bit % 10) { + default: + if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE) + pin->rx_msg.msg[pin->rx_bit / 10] |= + v << (7 - (pin->rx_bit % 10)); + break; + case 8: + pin->rx_eom = v; + pin->rx_msg.len = pin->rx_bit / 10 + 1; + break; + case 9: + break; + } + pin->rx_bit++; + break; + + case CEC_ST_RX_DATA_POST_SAMPLE: + pin->state = CEC_ST_RX_DATA_HIGH; + break; + + case CEC_ST_RX_DATA_HIGH: + v = cec_pin_read(pin); + delta = ktime_us_delta(ts, pin->ts); + if (v && delta > CEC_TIM_DATA_BIT_TOTAL_MAX) { + cec_pin_to_idle(pin); + break; + } + if (v) + break; + /* + * Go to low drive state when the total bit time is + * too short. + */ + if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) { + cec_pin_low(pin); + pin->state = CEC_ST_LOW_DRIVE; + break; + } + pin->ts = ts; + if (pin->rx_bit % 10 != 9) { + pin->state = CEC_ST_RX_DATA_SAMPLE; + break; + } + + dest = cec_msg_destination(&pin->rx_msg); + bcast = dest == CEC_LOG_ADDR_BROADCAST; + /* for_us == broadcast or directed to us */ + for_us = bcast || (pin->la_mask & (1 << dest)); + /* ACK bit value */ + ack = bcast ? 1 : !for_us; + + if (ack) { + /* No need to write to the bus, just wait */ + pin->state = CEC_ST_RX_ACK_HIGH_POST; + break; + } + cec_pin_low(pin); + pin->state = CEC_ST_RX_ACK_LOW; + break; + + case CEC_ST_RX_ACK_LOW: + cec_pin_high(pin); + pin->state = CEC_ST_RX_ACK_LOW_POST; + break; + + case CEC_ST_RX_ACK_LOW_POST: + case CEC_ST_RX_ACK_HIGH_POST: + v = cec_pin_read(pin); + if (v && pin->rx_eom) { + pin->work_rx_msg = pin->rx_msg; + pin->work_rx_msg.rx_ts = ts; + wake_up_interruptible(&pin->kthread_waitq); + pin->ts = ts; + pin->state = CEC_ST_RX_ACK_FINISH; + break; + } + pin->rx_bit++; + pin->state = CEC_ST_RX_DATA_HIGH; + break; + + case CEC_ST_RX_ACK_FINISH: + cec_pin_to_idle(pin); + break; + + default: + break; + } +} + +/* + * Main timer function + * + */ +static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) +{ + struct cec_pin *pin = container_of(timer, struct cec_pin, timer); + struct cec_adapter *adap = pin->adap; + ktime_t ts; + s32 delta; + + ts = ktime_get(); + if (pin->timer_ts) { + delta = ktime_us_delta(ts, pin->timer_ts); + pin->timer_cnt++; + if (delta > 100 && pin->state != CEC_ST_IDLE) { + /* Keep track of timer overruns */ + pin->timer_sum_overrun += delta; + pin->timer_100ms_overruns++; + if (delta > 300) + pin->timer_300ms_overruns++; + if (delta > pin->timer_max_overrun) + pin->timer_max_overrun = delta; + } + } + if (adap->monitor_pin_cnt) + cec_pin_read(pin); + + if (pin->wait_usecs) { + /* + * If we are monitoring the pin, then we have to + * sample at regular intervals. + */ + if (pin->wait_usecs > 150) { + pin->wait_usecs -= 100; + pin->timer_ts = ktime_add_us(ts, 100); + hrtimer_forward_now(timer, 100000); + return HRTIMER_RESTART; + } + if (pin->wait_usecs > 100) { + pin->wait_usecs /= 2; + pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); + hrtimer_forward_now(timer, pin->wait_usecs * 1000); + return HRTIMER_RESTART; + } + pin->timer_ts = ktime_add_us(ts, pin->wait_usecs); + hrtimer_forward_now(timer, pin->wait_usecs * 1000); + pin->wait_usecs = 0; + return HRTIMER_RESTART; + } + + switch (pin->state) { + /* Transmit states */ + case CEC_ST_TX_WAIT_FOR_HIGH: + case CEC_ST_TX_START_BIT_LOW: + case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: + case CEC_ST_TX_DATA_BIT_0_HIGH: + case CEC_ST_TX_DATA_BIT_1_HIGH: + case CEC_ST_TX_START_BIT_HIGH: + case CEC_ST_TX_DATA_BIT_0_LOW: + case CEC_ST_TX_DATA_BIT_1_LOW: + case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: + cec_pin_tx_states(pin, ts); + break; + + /* Receive states */ + case CEC_ST_RX_START_BIT_LOW: + case CEC_ST_RX_START_BIT_HIGH: + case CEC_ST_RX_DATA_SAMPLE: + case CEC_ST_RX_DATA_POST_SAMPLE: + case CEC_ST_RX_DATA_HIGH: + case CEC_ST_RX_ACK_LOW: + case CEC_ST_RX_ACK_LOW_POST: + case CEC_ST_RX_ACK_HIGH_POST: + case CEC_ST_RX_ACK_FINISH: + cec_pin_rx_states(pin, ts); + break; + + case CEC_ST_IDLE: + case CEC_ST_TX_WAIT: + if (!cec_pin_high(pin)) { + /* Start bit, switch to receive state */ + pin->ts = ts; + pin->state = CEC_ST_RX_START_BIT_LOW; + break; + } + if (pin->ts == 0) + pin->ts = ts; + if (pin->tx_msg.len) { + /* + * Check if the bus has been free for long enough + * so we can kick off the pending transmit. + */ + delta = ktime_us_delta(ts, pin->ts); + if (delta / CEC_TIM_DATA_BIT_TOTAL > + pin->tx_signal_free_time) { + pin->tx_nacked = false; + pin->state = CEC_ST_TX_START_BIT_LOW; + /* Generate start bit */ + cec_pin_low(pin); + break; + } + if (delta / CEC_TIM_DATA_BIT_TOTAL > + pin->tx_signal_free_time - 1) + pin->state = CEC_ST_TX_WAIT; + break; + } + if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL || + pin->enable_irq_failed || adap->is_configuring || + adap->is_configured || adap->monitor_all_cnt) + break; + /* Switch to interrupt mode */ + pin->work_enable_irq = true; + pin->state = CEC_ST_RX_IRQ; + wake_up_interruptible(&pin->kthread_waitq); + return HRTIMER_NORESTART; + + case CEC_ST_LOW_DRIVE: + cec_pin_to_idle(pin); + break; + + default: + break; + } + if (!adap->monitor_pin_cnt || states[pin->state].usecs <= 150) { + pin->wait_usecs = 0; + pin->timer_ts = ktime_add_us(ts, states[pin->state].usecs); + hrtimer_forward_now(timer, states[pin->state].usecs * 1000); + return HRTIMER_RESTART; + } + pin->wait_usecs = states[pin->state].usecs - 100; + pin->timer_ts = ktime_add_us(ts, 100); + hrtimer_forward_now(timer, 100000); + return HRTIMER_RESTART; +} + +static int cec_pin_thread_func(void *_adap) +{ + struct cec_adapter *adap = _adap; + struct cec_pin *pin = adap->pin; + + for (;;) { + wait_event_interruptible(pin->kthread_waitq, + kthread_should_stop() || + pin->work_rx_msg.len || + pin->work_tx_status || + pin->work_enable_irq || + atomic_read(&pin->work_pin_events)); + + if (pin->work_rx_msg.len) { + cec_received_msg_ts(adap, &pin->work_rx_msg, + pin->work_rx_msg.rx_ts); + pin->work_rx_msg.len = 0; + } + if (pin->work_tx_status) { + unsigned int tx_status = pin->work_tx_status; + + pin->work_tx_status = 0; + cec_transmit_attempt_done_ts(adap, tx_status, + pin->work_tx_ts); + } + while (atomic_read(&pin->work_pin_events)) { + unsigned int idx = pin->work_pin_events_rd; + + cec_queue_pin_event(adap, pin->work_pin_is_high[idx], + pin->work_pin_ts[idx]); + pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; + atomic_dec(&pin->work_pin_events); + } + if (pin->work_enable_irq) { + pin->work_enable_irq = false; + pin->enable_irq_failed = !pin->ops->enable_irq(adap); + if (pin->enable_irq_failed) { + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); + } + } + if (kthread_should_stop()) + break; + } + return 0; +} + +static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct cec_pin *pin = adap->pin; + + pin->enabled = enable; + if (enable) { + atomic_set(&pin->work_pin_events, 0); + pin->work_pin_events_rd = pin->work_pin_events_wr = 0; + cec_pin_read(pin); + cec_pin_to_idle(pin); + pin->tx_msg.len = 0; + pin->timer_ts = 0; + pin->work_enable_irq = false; + pin->kthread = kthread_run(cec_pin_thread_func, adap, + "cec-pin"); + if (IS_ERR(pin->kthread)) { + pr_err("cec-pin: kernel_thread() failed\n"); + return PTR_ERR(pin->kthread); + } + hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); + } else { + if (pin->ops->disable_irq) + pin->ops->disable_irq(adap); + hrtimer_cancel(&pin->timer); + kthread_stop(pin->kthread); + cec_pin_read(pin); + cec_pin_to_idle(pin); + pin->state = CEC_ST_OFF; + } + return 0; +} + +static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +{ + struct cec_pin *pin = adap->pin; + + if (log_addr == CEC_LOG_ADDR_INVALID) + pin->la_mask = 0; + else + pin->la_mask |= (1 << log_addr); + return 0; +} + +static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct cec_pin *pin = adap->pin; + + pin->tx_signal_free_time = signal_free_time; + pin->tx_msg = *msg; + pin->work_tx_status = 0; + pin->tx_bit = 0; + if (pin->state == CEC_ST_RX_IRQ) { + pin->work_enable_irq = false; + pin->ops->disable_irq(adap); + cec_pin_high(pin); + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); + } + return 0; +} + +static void cec_pin_adap_status(struct cec_adapter *adap, + struct seq_file *file) +{ + struct cec_pin *pin = adap->pin; + + seq_printf(file, "state: %s\n", states[pin->state].name); + seq_printf(file, "tx_bit: %d\n", pin->tx_bit); + seq_printf(file, "rx_bit: %d\n", pin->rx_bit); + seq_printf(file, "cec pin: %d\n", pin->ops->read(adap)); + seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed); + if (pin->timer_100ms_overruns) { + seq_printf(file, "timer overruns > 100ms: %u of %u\n", + pin->timer_100ms_overruns, pin->timer_cnt); + seq_printf(file, "timer overruns > 300ms: %u of %u\n", + pin->timer_300ms_overruns, pin->timer_cnt); + seq_printf(file, "max timer overrun: %u usecs\n", + pin->timer_max_overrun); + seq_printf(file, "avg timer overrun: %u usecs\n", + pin->timer_sum_overrun / pin->timer_100ms_overruns); + } + pin->timer_cnt = 0; + pin->timer_100ms_overruns = 0; + pin->timer_300ms_overruns = 0; + pin->timer_max_overrun = 0; + pin->timer_sum_overrun = 0; + if (pin->ops->status) + pin->ops->status(adap, file); +} + +static int cec_pin_adap_monitor_all_enable(struct cec_adapter *adap, + bool enable) +{ + struct cec_pin *pin = adap->pin; + + pin->monitor_all = enable; + return 0; +} + +static void cec_pin_adap_free(struct cec_adapter *adap) +{ + struct cec_pin *pin = adap->pin; + + if (pin->ops->free) + pin->ops->free(adap); + adap->pin = NULL; + kfree(pin); +} + +void cec_pin_changed(struct cec_adapter *adap, bool value) +{ + struct cec_pin *pin = adap->pin; + + cec_pin_update(pin, value, false); + if (!value && (adap->is_configuring || adap->is_configured || + adap->monitor_all_cnt)) { + pin->work_enable_irq = false; + pin->ops->disable_irq(adap); + cec_pin_high(pin); + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); + } +} +EXPORT_SYMBOL_GPL(cec_pin_changed); + +static const struct cec_adap_ops cec_pin_adap_ops = { + .adap_enable = cec_pin_adap_enable, + .adap_monitor_all_enable = cec_pin_adap_monitor_all_enable, + .adap_log_addr = cec_pin_adap_log_addr, + .adap_transmit = cec_pin_adap_transmit, + .adap_status = cec_pin_adap_status, + .adap_free = cec_pin_adap_free, +}; + +struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, + void *priv, const char *name, u32 caps) +{ + struct cec_adapter *adap; + struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL); + + if (pin == NULL) + return ERR_PTR(-ENOMEM); + pin->ops = pin_ops; + pin->cur_value = true; + hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pin->timer.function = cec_pin_timer; + init_waitqueue_head(&pin->kthread_waitq); + + adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name, + caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN, + CEC_MAX_LOG_ADDRS); + + if (PTR_ERR_OR_ZERO(adap)) { + kfree(pin); + return adap; + } + + adap->pin = pin; + pin->adap = adap; + cec_pin_update(pin, cec_pin_high(pin), true); + return adap; +} +EXPORT_SYMBOL_GPL(cec_pin_allocate_adapter); diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h new file mode 100644 index 000000000000..44b82d29d480 --- /dev/null +++ b/include/media/cec-pin.h @@ -0,0 +1,183 @@ +/* + * cec-pin.h - low-level CEC pin control + * + * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef LINUX_CEC_PIN_H +#define LINUX_CEC_PIN_H + +#include +#include +#include + +enum cec_pin_state { + /* CEC is off */ + CEC_ST_OFF, + /* CEC is idle, waiting for Rx or Tx */ + CEC_ST_IDLE, + + /* Tx states */ + + /* Pending Tx, waiting for Signal Free Time to expire */ + CEC_ST_TX_WAIT, + /* Low-drive was detected, wait for bus to go high */ + CEC_ST_TX_WAIT_FOR_HIGH, + /* Drive CEC low for the start bit */ + CEC_ST_TX_START_BIT_LOW, + /* Drive CEC high for the start bit */ + CEC_ST_TX_START_BIT_HIGH, + /* Drive CEC low for the 0 bit */ + CEC_ST_TX_DATA_BIT_0_LOW, + /* Drive CEC high for the 0 bit */ + CEC_ST_TX_DATA_BIT_0_HIGH, + /* Drive CEC low for the 1 bit */ + CEC_ST_TX_DATA_BIT_1_LOW, + /* Drive CEC high for the 1 bit */ + CEC_ST_TX_DATA_BIT_1_HIGH, + /* + * Wait for start of sample time to check for Ack bit or first + * four initiator bits to check for Arbitration Lost. + */ + CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE, + /* Wait for end of bit period after sampling */ + CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE, + + /* Rx states */ + + /* Start bit low detected */ + CEC_ST_RX_START_BIT_LOW, + /* Start bit high detected */ + CEC_ST_RX_START_BIT_HIGH, + /* Wait for bit sample time */ + CEC_ST_RX_DATA_SAMPLE, + /* Wait for earliest end of bit period after sampling */ + CEC_ST_RX_DATA_POST_SAMPLE, + /* Wait for CEC to go high (i.e. end of bit period */ + CEC_ST_RX_DATA_HIGH, + /* Drive CEC low to send 0 Ack bit */ + CEC_ST_RX_ACK_LOW, + /* End of 0 Ack time, wait for earliest end of bit period */ + CEC_ST_RX_ACK_LOW_POST, + /* Wait for CEC to go high (i.e. end of bit period */ + CEC_ST_RX_ACK_HIGH_POST, + /* Wait for earliest end of bit period and end of message */ + CEC_ST_RX_ACK_FINISH, + + /* Start low drive */ + CEC_ST_LOW_DRIVE, + /* Monitor pin using interrupts */ + CEC_ST_RX_IRQ, + + /* Total number of pin states */ + CEC_PIN_STATES +}; + +/** + * struct cec_pin_ops - low-level CEC pin operations + * @read: read the CEC pin. Return true if high, false if low. + * @low: drive the CEC pin low. + * @high: stop driving the CEC pin. The pull-up will drive the pin + * high, unless someone else is driving the pin low. + * @enable_irq: optional, enable the interrupt to detect pin voltage changes. + * @disable_irq: optional, disable the interrupt. + * @free: optional. Free any allocated resources. Called when the + * adapter is deleted. + * @status: optional, log status information. + * + * These operations are used by the cec pin framework to manipulate + * the CEC pin. + */ +struct cec_pin_ops { + bool (*read)(struct cec_adapter *adap); + void (*low)(struct cec_adapter *adap); + void (*high)(struct cec_adapter *adap); + bool (*enable_irq)(struct cec_adapter *adap); + void (*disable_irq)(struct cec_adapter *adap); + void (*free)(struct cec_adapter *adap); + void (*status)(struct cec_adapter *adap, struct seq_file *file); +}; + +#define CEC_NUM_PIN_EVENTS 128 + +struct cec_pin { + struct cec_adapter *adap; + const struct cec_pin_ops *ops; + struct task_struct *kthread; + wait_queue_head_t kthread_waitq; + struct hrtimer timer; + ktime_t ts; + unsigned int wait_usecs; + u16 la_mask; + bool enabled; + bool monitor_all; + bool cur_value; + bool rx_eom; + bool enable_irq_failed; + enum cec_pin_state state; + struct cec_msg tx_msg; + u32 tx_bit; + bool tx_nacked; + u32 tx_signal_free_time; + struct cec_msg rx_msg; + u32 rx_bit; + + struct cec_msg work_rx_msg; + u8 work_tx_status; + bool work_enable_irq; + ktime_t work_tx_ts; + atomic_t work_pin_events; + unsigned int work_pin_events_wr; + unsigned int work_pin_events_rd; + ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS]; + bool work_pin_is_high[CEC_NUM_PIN_EVENTS]; + ktime_t timer_ts; + u32 timer_cnt; + u32 timer_100ms_overruns; + u32 timer_300ms_overruns; + u32 timer_max_overrun; + u32 timer_sum_overrun; +}; + +/** + * cec_pin_changed() - update pin state from interrupt + * + * @adap: pointer to the cec adapter + * @value: when true the pin is high, otherwise it is low + * + * If changes of the CEC voltage are detected via an interrupt, then + * cec_pin_changed is called from the interrupt with the new value. + */ +void cec_pin_changed(struct cec_adapter *adap, bool value); + +/** + * cec_pin_allocate_adapter() - allocate a pin-based cec adapter + * + * @pin_ops: low-level pin operations + * @priv: will be stored in adap->priv and can be used by the adapter ops. + * Use cec_get_drvdata(adap) to get the priv pointer. + * @name: the name of the CEC adapter. Note: this name will be copied. + * @caps: capabilities of the CEC adapter. This will be ORed with + * CEC_CAP_MONITOR_ALL and CEC_CAP_MONITOR_PIN. + * + * Allocate a cec adapter using the cec pin framework. + * + * Return: a pointer to the cec adapter or an error pointer + */ +struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, + void *priv, const char *name, u32 caps); + +#endif diff --git a/include/media/cec.h b/include/media/cec.h index d983960b37ad..f9cab1a9f912 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -61,6 +61,7 @@ struct cec_devnode { struct cec_adapter; struct cec_data; +struct cec_pin; struct cec_data { struct list_head list; @@ -189,6 +190,9 @@ struct cec_adapter { #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; #endif +#ifdef CONFIG_CEC_PIN + struct cec_pin *pin; +#endif struct dentry *cec_dir; struct dentry *status_file; -- cgit v1.2.3 From 688318c35af41e0638e5773140284836bcf0c9f3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jul 2017 08:20:18 -0300 Subject: media: cec: be smarter about detecting the number of attempts made Some hardware does more than one attempt. So when it calls cec_transmit_done when an error occurred it will e.g. use an error count of 2 instead of 1. The framework always assumed a single attempt, but now it is smarter and will sum the counters to detect how many attempts were made. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index b0bd466f75e2..1a021828c8d4 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -517,8 +517,13 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, { struct cec_data *data; struct cec_msg *msg; + unsigned int attempts_made = arb_lost_cnt + nack_cnt + + low_drive_cnt + error_cnt; dprintk(2, "%s: status %02x\n", __func__, status); + if (attempts_made < 1) + attempts_made = 1; + mutex_lock(&adap->lock); data = adap->transmitting; if (!data) { @@ -551,10 +556,10 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, * the hardware didn't signal that it retried itself (by setting * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. */ - if (data->attempts > 1 && + if (data->attempts > attempts_made && !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { /* Retry this message */ - data->attempts--; + data->attempts -= attempts_made; if (msg->timeout) dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n", msg->len, msg->msg, data->attempts, msg->reply); -- cgit v1.2.3 From ed10b4e0870b446c0e8e089b287be21ccdbcf5d6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 15 Jul 2017 09:30:37 -0300 Subject: media: cec: drop senseless message Especially the '0.10' version number is confusing since CEC_ADAP_G_CAPS returns a completely different version number. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index 2e5765344d07..52f085ba104a 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -388,11 +388,8 @@ EXPORT_SYMBOL_GPL(cec_delete_adapter); */ static int __init cec_devnode_init(void) { - int ret; + int ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, CEC_NAME); - pr_info("Linux cec interface: v0.10\n"); - ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, - CEC_NAME); if (ret < 0) { pr_warn("cec: unable to allocate major\n"); return ret; -- cgit v1.2.3 From 0e6fd95802e25b2428749703f76ea9d54ea743a3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 15 Jul 2017 18:47:40 -0300 Subject: media: pulse8-cec/rainshadow-cec: make adapter name unique The CEC adapter name used by the pulse8-cec and rainshadow-cec USB device drivers was a fixed string, but it should be unique if you connect multiple of these devices to the same computer. Use dev_name(&serio->dev) instead, which make it unique again. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pulse8-cec/pulse8-cec.c | 2 +- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index c843070f24c1..e29d43237046 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -656,7 +656,7 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->serio = serio; pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8, - "HDMI CEC", caps, 1); + dev_name(&serio->dev), caps, 1); err = PTR_ERR_OR_ZERO(pulse8->adap); if (err < 0) goto free_device; diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index 65692576690f..30bff4c48f92 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -323,7 +323,7 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv) rain->serio = serio; rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain, - "HDMI CEC", caps, 1); + dev_name(&serio->dev), caps, 1); err = PTR_ERR_OR_ZERO(rain->adap); if (err < 0) goto free_device; -- cgit v1.2.3 From 6bcc051691186188256ebde07e0777cebcaeda22 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 29 Jun 2017 04:51:24 -0400 Subject: media: media/platform: add const to v4l2_file_operations structures Declare v4l2_file_operations structures as const as they are only stored in the fops field of video_device structures. This field is of type const, so declare v4l2_file_operations structures with similar properties as const. Cross compiled bfin_capture.o for blackfin arch. vpbe_display.o file did not cross compile for arm. Could not find any architecture matching the configuraion symbol for fsl-viu.c file. Signed-off-by: Bhumika Goyal Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/bfin_capture.c | 2 +- drivers/media/platform/davinci/vpbe_display.c | 2 +- drivers/media/platform/davinci/vpif_capture.c | 2 +- drivers/media/platform/fsl-viu.c | 2 +- drivers/media/platform/soc_camera/soc_camera.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 1c5166df46f5..294d696c4a3b 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -769,7 +769,7 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { .vidioc_log_status = bcap_log_status, }; -static struct v4l2_file_operations bcap_fops = { +static const struct v4l2_file_operations bcap_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index a9bc0175e4d3..ca2adfa565f6 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -1275,7 +1275,7 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { .vidioc_enum_dv_timings = vpbe_display_enum_dv_timings, }; -static struct v4l2_file_operations vpbe_fops = { +static const struct v4l2_file_operations vpbe_fops = { .owner = THIS_MODULE, .open = vpbe_display_open, .release = vpbe_display_release, diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 4be6554c56c5..46c0257fb249 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1344,7 +1344,7 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { }; /* vpif file operations */ -static struct v4l2_file_operations vpif_fops = { +static const struct v4l2_file_operations vpif_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 97e164b2075a..f7b88e58d00e 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1340,7 +1340,7 @@ static int viu_mmap(struct file *file, struct vm_area_struct *vma) return ret; } -static struct v4l2_file_operations viu_fops = { +static const struct v4l2_file_operations viu_fops = { .owner = THIS_MODULE, .open = viu_open, .release = viu_release, diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 45a0429d75bb..dd349efae3af 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -820,7 +820,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt) return res; } -static struct v4l2_file_operations soc_camera_fops = { +static const struct v4l2_file_operations soc_camera_fops = { .owner = THIS_MODULE, .open = soc_camera_open, .release = soc_camera_close, -- cgit v1.2.3 From 568bdaddc324c0068f26bbe3d4dc57acb8e3286b Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 29 Jun 2017 04:59:19 -0400 Subject: media: cx23885: add const to v4l2_file_operations structure Declare v4l2_file_operations structure as const as it is only stored in the fops field of video_device structure. This field is of type const, so declare v4l2_file_operations structures with similar properties as const. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-417.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c index 2ff1d1e274be..a71f3c7569ce 100644 --- a/drivers/media/pci/cx23885/cx23885-417.c +++ b/drivers/media/pci/cx23885/cx23885-417.c @@ -1416,7 +1416,7 @@ static int vidioc_log_status(struct file *file, void *priv) return 0; } -static struct v4l2_file_operations mpeg_fops = { +static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, -- cgit v1.2.3 From 6e03db38631f5607e81856418ffe779c29e53c56 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 1 Jul 2017 07:27:13 -0400 Subject: media: vb2 dma-contig: Constify dma_buf_ops structures dma_buf_ops are not supposed to change at runtime. All functions working with dma_buf_ops provided by work with const dma_buf_ops. So mark the non-const structs as const. File size before: text data bss dec hex filename 6035 272 0 6307 18a3 drivers/media/v4l2-core/videobuf2-dma-contig.o File size After adding 'const': text data bss dec hex filename 6155 160 0 6315 18ab drivers/media/v4l2-core/videobuf2-dma-contig.o Signed-off-by: Arvind Yadav Acked-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 4f246d166111..5b90a66b9e78 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -352,7 +352,7 @@ static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf, return vb2_dc_mmap(dbuf->priv, vma); } -static struct dma_buf_ops vb2_dc_dmabuf_ops = { +static const struct dma_buf_ops vb2_dc_dmabuf_ops = { .attach = vb2_dc_dmabuf_ops_attach, .detach = vb2_dc_dmabuf_ops_detach, .map_dma_buf = vb2_dc_dmabuf_ops_map, -- cgit v1.2.3 From 59310b7a06c1f9c7d8fd2d981dbc85226214dc32 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 1 Jul 2017 07:37:26 -0400 Subject: media: vb2 vmalloc: Constify dma_buf_ops structures dma_buf_ops are not supposed to change at runtime. All functions working with dma_buf_ops provided by work with const dma_buf_ops. So mark the non-const structs as const. File size before: text data bss dec hex filename 3171 192 0 3363 d23 drivers/media/v4l2-core/videobuf2-vmalloc.o File size After adding 'const': text data bss dec hex filename 3291 80 0 3371 d2b drivers/media/v4l2-core/videobuf2-vmalloc.o Signed-off-by: Arvind Yadav Acked-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index b337d780844c..6bc130fe84f6 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -338,7 +338,7 @@ static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf, return vb2_vmalloc_mmap(dbuf->priv, vma); } -static struct dma_buf_ops vb2_vmalloc_dmabuf_ops = { +static const struct dma_buf_ops vb2_vmalloc_dmabuf_ops = { .attach = vb2_vmalloc_dmabuf_ops_attach, .detach = vb2_vmalloc_dmabuf_ops_detach, .map_dma_buf = vb2_vmalloc_dmabuf_ops_map, -- cgit v1.2.3 From efaf515f0d5124193393e37adbef423866a99273 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 1 Jul 2017 08:18:24 -0400 Subject: media: vb2 dma-sg: Constify dma_buf_ops structures dma_buf_ops are not supposed to change at runtime. All functions working with dma_buf_ops provided by work with const dma_buf_ops. So mark the non-const structs as const. File size before: text data bss dec hex filename 5238 112 4 5354 14ea drivers/media/v4l2-core/videobuf2-dma-sg.o File size After adding 'const': text data bss dec hex filename 5358 0 4 5362 14f2 drivers/media/v4l2-core/videobuf2-dma-sg.o Signed-off-by: Arvind Yadav Acked-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 5defa1f22ca2..54f33938d45b 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -500,7 +500,7 @@ static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf, return vb2_dma_sg_mmap(dbuf->priv, vma); } -static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { +static const struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { .attach = vb2_dma_sg_dmabuf_ops_attach, .detach = vb2_dma_sg_dmabuf_ops_detach, .map_dma_buf = vb2_dma_sg_dmabuf_ops_map, -- cgit v1.2.3 From 2f9b8aa36b8cd335badf9a0cf16c96fd65f452e2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 3 Jul 2017 05:13:08 -0400 Subject: media: i2c: m5mols: fix spelling mistake: "Machanics" -> "Mechanics" Trivial fix to spelling mistake in v4l2_info message Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 9ccb5ee55fa9..463534d44756 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -457,7 +457,7 @@ static int m5mols_get_version(struct v4l2_subdev *sd) v4l2_info(sd, "Manufacturer\t[%s]\n", is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? - "Samsung Electro-Machanics" : + "Samsung Electro-Mechanics" : is_manufacturer(info, REG_SAMSUNG_OPTICS) ? "Samsung Fiber-Optics" : is_manufacturer(info, REG_SAMSUNG_TECHWIN) ? -- cgit v1.2.3 From 72c6efb0d3fb0eff8b13c14dfcebbd8e8e63c1e4 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 3 Jul 2017 05:26:39 -0400 Subject: media: media/i2c/saa717x: fix spelling mistake: "implementd" -> "implemented" Trivial fix to spelling mistake in v4l2_dbg debug message Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/saa717x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index e1f6bc219c64..102467e00fb3 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -1069,7 +1069,7 @@ static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std) struct saa717x_state *decoder = to_state(sd); v4l2_dbg(1, debug, sd, "decoder set norm "); - v4l2_dbg(1, debug, sd, "(not yet implementd)\n"); + v4l2_dbg(1, debug, sd, "(not yet implemented)\n"); decoder->radio = 0; decoder->std = std; -- cgit v1.2.3 From 6ad33dec835693e38c1994cedbd3c404782e84fb Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 5 Jul 2017 14:23:55 -0400 Subject: media: tuners: remove unnecessary static in simple_dvb_configure() Remove unnecessary static on local variable t_params. Such variable is initialized before being used, on every execution path throughout the function. The static has no benefit and, removing it reduces the code size. This issue was detected using Coccinelle and the following semantic patch: @bad exists@ position p; identifier x; type T; @@ static T x@p; ... x = <+...x...+> @@ identifier x; expression e; type T; position p != bad.p; @@ -static T x@p; ... when != x when strict ?x = e; In the following log you can see the difference in the code size. Also, there is a significant difference in the bss segment. This log is the output of the size command, before and after the code change: before: text data bss dec hex filename 23314 3640 832 27786 6c8a drivers/media/tuners/tuner-simple.o after: text data bss dec hex filename 23257 3552 768 27577 6bb9 drivers/media/tuners/tuner-simple.o Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tuner-simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c index 3339b13dd3f5..cf44d3657f55 100644 --- a/drivers/media/tuners/tuner-simple.c +++ b/drivers/media/tuners/tuner-simple.c @@ -846,7 +846,7 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf, /* This function returns the tuned frequency on success, 0 on error */ struct tuner_simple_priv *priv = fe->tuner_priv; struct tunertype *tun = priv->tun; - static struct tuner_params *t_params; + struct tuner_params *t_params; u8 config, cb; u32 div; int ret; -- cgit v1.2.3 From f3ab729c14ab8f0a542107a3aea4d60fd944bc1e Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:05:17 -0400 Subject: media: stm32-dcmi: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Acked-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 83d32a5d0f40..24ef88809d7c 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -662,7 +662,7 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) dcmi->errors_count, dcmi->buffers_count); } -static struct vb2_ops dcmi_video_qops = { +static const struct vb2_ops dcmi_video_qops = { .queue_setup = dcmi_queue_setup, .buf_init = dcmi_buf_init, .buf_prepare = dcmi_buf_prepare, -- cgit v1.2.3 From 9c91e706050fd22edde98ea1794d326cb9ceaf71 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:14:23 -0400 Subject: media: st-delta: constify vb2_ops structures Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Acked-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/delta/delta-v4l2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c index c6f2e244b7a8..ff9850ea3ed7 100644 --- a/drivers/media/platform/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/sti/delta/delta-v4l2.c @@ -1574,7 +1574,7 @@ static void delta_vb2_frame_stop_streaming(struct vb2_queue *q) } /* VB2 queue ops */ -static struct vb2_ops delta_vb2_au_ops = { +static const struct vb2_ops delta_vb2_au_ops = { .queue_setup = delta_vb2_au_queue_setup, .buf_prepare = delta_vb2_au_prepare, .buf_queue = delta_vb2_au_queue, @@ -1584,7 +1584,7 @@ static struct vb2_ops delta_vb2_au_ops = { .stop_streaming = delta_vb2_au_stop_streaming, }; -static struct vb2_ops delta_vb2_frame_ops = { +static const struct vb2_ops delta_vb2_frame_ops = { .queue_setup = delta_vb2_frame_queue_setup, .buf_prepare = delta_vb2_frame_prepare, .buf_finish = delta_vb2_frame_finish, -- cgit v1.2.3 From 7e645125a88b4fd5611fc09a2800e71b34963580 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:20:00 -0400 Subject: media: pxa_camera: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/pxa_camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 399095170b6e..5c3b7cf3638b 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -1557,7 +1557,7 @@ static void pxac_vb2_stop_streaming(struct vb2_queue *vq) pxa_camera_wakeup(pcdev, buf, VB2_BUF_STATE_ERROR); } -static struct vb2_ops pxac_vb2_ops = { +static const struct vb2_ops pxac_vb2_ops = { .queue_setup = pxac_vb2_queue_setup, .buf_init = pxac_vb2_init, .buf_prepare = pxac_vb2_prepare, -- cgit v1.2.3 From 0169daec966598859fb5cd76f11a7a720e721f89 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:25:32 -0400 Subject: media: rcar_fdp1: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_fdp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 3ee51fc3bb50..3245bc45f4a0 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2032,7 +2032,7 @@ static void fdp1_stop_streaming(struct vb2_queue *q) } } -static struct vb2_ops fdp1_qops = { +static const struct vb2_ops fdp1_qops = { .queue_setup = fdp1_queue_setup, .buf_prepare = fdp1_buf_prepare, .buf_queue = fdp1_buf_queue, -- cgit v1.2.3 From 62c11a541a50b0c53e80f1382e06c1f8b9379304 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:30:16 -0400 Subject: media: atmel-isc: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index d6534252cdcd..d4df3d4ccd85 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -873,7 +873,7 @@ static void isc_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&isc->dma_queue_lock, flags); } -static struct vb2_ops isc_vb2_ops = { +static const struct vb2_ops isc_vb2_ops = { .queue_setup = isc_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, -- cgit v1.2.3 From b0a4ceddfc3f49226ada4b17394e900c056bb790 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:35:53 -0400 Subject: media: davinci: vpif_display: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index bf982bf86542..56fe4e5b396e 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -290,7 +290,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&common->irqlock, flags); } -static struct vb2_ops video_qops = { +static const struct vb2_ops video_qops = { .queue_setup = vpif_buffer_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, -- cgit v1.2.3 From f5d7232977ae8ec9576049f07f1a50c276216295 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:39:21 -0400 Subject: media: davinci: vpif_capture: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 46c0257fb249..70ffba70164f 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -312,7 +312,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&common->irqlock, flags); } -static struct vb2_ops video_qops = { +static const struct vb2_ops video_qops = { .queue_setup = vpif_buffer_queue_setup, .buf_prepare = vpif_buffer_prepare, .start_streaming = vpif_start_streaming, -- cgit v1.2.3 From 94e8f761d3ba4012fa75a6d66fe3d9cf76d08628 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:46:00 -0400 Subject: media: mtk-mdp: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index 13afe48b9dc5..3038d62ba735 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -621,7 +621,7 @@ static void mtk_mdp_m2m_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); } -static struct vb2_ops mtk_mdp_m2m_qops = { +static const struct vb2_ops mtk_mdp_m2m_qops = { .queue_setup = mtk_mdp_m2m_queue_setup, .buf_prepare = mtk_mdp_m2m_buf_prepare, .buf_queue = mtk_mdp_m2m_buf_queue, -- cgit v1.2.3 From fda7e347239343349fcce30be723ebf1290f34c9 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 6 Jul 2017 16:51:27 -0400 Subject: media: mediatek: constify vb2_ops structure Check for vb2_ops structures that are only stored in the ops field of a vb2_queue structure. That field is declared const, so vb2_ops structures that have this property can be declared as const also. This issue was detected using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 451a54039e65..f17a86b2f917 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -756,7 +756,7 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) pm_runtime_put_sync(ctx->jpeg->dev); } -static struct vb2_ops mtk_jpeg_qops = { +static const struct vb2_ops mtk_jpeg_qops = { .queue_setup = mtk_jpeg_queue_setup, .buf_prepare = mtk_jpeg_buf_prepare, .buf_queue = mtk_jpeg_buf_queue, -- cgit v1.2.3 From 57d8ba0f0f6a4cfd6b6e0ce112fb1db2fbdcd397 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 10 Jul 2017 04:48:43 -0400 Subject: media: platform: video-mux: fix Kconfig dependency When CONFIG_V4L2 is built as a loadable module, the new video mux driver fails to link as built-in code: drivers/media/platform/video-mux.o: In function `video_mux_remove': video-mux.c:(.text+0x24): undefined reference to `v4l2_async_unregister_subdev' drivers/media/platform/video-mux.o: In function `video_mux_probe': video-mux.c:(.text+0x800): undefined reference to `v4l2_subdev_init' video-mux.c:(.text+0xa10): undefined reference to `v4l2_async_register_subdev' This makes it use the same Kconfig dependency as all the other users of the VIDEO_V4L2_SUBDEV_API symbol. Fixes: 68803ad4522f ("[media] platform: add video-multiplexer subdevice driver") Cc: Sascha Hauer Cc: Philipp Zabel Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 1313cd533436..323155d6754f 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -76,7 +76,7 @@ config VIDEO_M32R_AR_M64278 config VIDEO_MUX tristate "Video Multiplexer" - depends on OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER + depends on VIDEO_V4L2 && OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER select REGMAP help This driver provides support for N:1 video bus multiplexers. -- cgit v1.2.3 From d7552a1eea5b24f81a6e0cc42b434fc6d803d3e0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Jul 2017 14:51:03 -0400 Subject: media: solo6x10: make const array saa7128_regs_ntsc static Don't populate const array saa7128_regs_ntsc on the stack but insteaed make it static. Makes the object code smaller and saves nearly 840 bytes Before: text data bss dec hex filename 9218 360 0 9578 256a solo6x10-tw28.o After: text data bss dec hex filename 8237 504 0 8741 2225 solo6x10-tw28.o Signed-off-by: Colin Ian King Acked-by: Andrey Utkin Signed-off-by: Ismael Luceno Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-tw28.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/solo6x10/solo6x10-tw28.c b/drivers/media/pci/solo6x10/solo6x10-tw28.c index 0632d3f7c73c..1c013a03d851 100644 --- a/drivers/media/pci/solo6x10/solo6x10-tw28.c +++ b/drivers/media/pci/solo6x10/solo6x10-tw28.c @@ -532,7 +532,7 @@ static void saa712x_write_regs(struct solo_dev *dev, const u8 *vals, static void saa712x_setup(struct solo_dev *dev) { const int reg_start = 0x26; - const u8 saa7128_regs_ntsc[] = { + static const u8 saa7128_regs_ntsc[] = { /* :0x26 */ 0x0d, 0x00, /* :0x28 */ -- cgit v1.2.3 From e5c50e130ddc7976a989b1412ded4cd35ac7a8b0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 11 Jul 2017 05:43:49 -0400 Subject: media: fc001[23]: make const gain table arrays static Don't populate the gain tables on the stack but make them static const. Makes the object code smaller: Before: text data bss dec hex filename 7801 1408 0 9209 23f9 drivers/media/tuners/fc0012.o 8483 936 0 9419 24cb drivers/media/tuners/fc0013.o After: text data bss dec hex filename 7696 1464 0 9160 23c8 drivers/media/tuners/fc0012.o 8362 1024 0 9386 24aa drivers/media/tuners/fc0013.o Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/fc0012.c | 2 +- drivers/media/tuners/fc0013.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index dcc323ffbde7..625ac6f51c39 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c @@ -351,7 +351,7 @@ static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength) int ret; unsigned char tmp; int int_temp, lna_gain, int_lna, tot_agc_gain, power; - const int fc0012_lna_gain_table[] = { + static const int fc0012_lna_gain_table[] = { /* low gain */ -63, -58, -99, -73, -63, -65, -54, -60, diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index 91dfa770a5cc..e606118d1a9b 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -511,7 +511,7 @@ static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength) int ret; unsigned char tmp; int int_temp, lna_gain, int_lna, tot_agc_gain, power; - const int fc0013_lna_gain_table[] = { + static const int fc0013_lna_gain_table[] = { /* low gain */ -63, -58, -99, -73, -63, -65, -54, -60, -- cgit v1.2.3 From 5a634ae0b158f845fe7f9603ae843f429b8a4c85 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 11 Jul 2017 15:07:52 -0400 Subject: media: davinci: vpif_capture: fix potential NULL deref Fix potential NULL pointer dereference in the error path of memory allocation failure. Reported-by: Dan Carpenter Signed-off-by: Kevin Hilman Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 70ffba70164f..fe2a5748e554 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1593,9 +1593,11 @@ vpif_capture_get_pdata(struct platform_device *pdev) } done: - pdata->asd_sizes[0] = i; - pdata->subdev_count = i; - pdata->card_name = "DA850/OMAP-L138 Video Capture"; + if (pdata) { + pdata->asd_sizes[0] = i; + pdata->subdev_count = i; + pdata->card_name = "DA850/OMAP-L138 Video Capture"; + } return pdata; } -- cgit v1.2.3 From 462e8ce009cba0da6c636d245678a7f80d660769 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 23 Jun 2017 05:55:29 -0400 Subject: media: coda: add h264 and mpeg4 profile and level controls CODA7541 supports H.264 BP level 3/3.1 and MPEG-4 SP level 5/6. CODA960 supports H.264 BP level 4.0 and MPEG-4 SP level 5/6. Implement the necessary profile and level controls to let userspace know this. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 47 +++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 829c7895a98a..d119b4777328 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1683,12 +1683,23 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl) ctx->params.h264_deblk_enabled = (ctrl->val == V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED); break; + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + /* TODO: switch between baseline and constrained baseline */ + ctx->params.h264_profile_idc = 66; + break; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + /* nothing to do, this is set by the encoder */ + break; case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: ctx->params.mpeg4_intra_qp = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: ctx->params.mpeg4_inter_qp = ctrl->val; break; + case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: + /* nothing to do, these are fixed */ + break; case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: ctx->params.slice_mode = ctrl->val; break; @@ -1756,10 +1767,46 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED, 0x0, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED); + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_PROFILE, + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); + if (ctx->dev->devtype->product == CODA_7541) { + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1, + ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1)), + V4L2_MPEG_VIDEO_H264_LEVEL_3_1); + } + if (ctx->dev->devtype->product == CODA_960) { + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_H264_LEVEL, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0, + ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), + V4L2_MPEG_VIDEO_H264_LEVEL_4_0); + } v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, 1, 31, 1, 2); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, 1, 31, 1, 2); + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, 0x0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); + if (ctx->dev->devtype->product == CODA_7541 || + ctx->dev->devtype->product == CODA_960) { + v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, + ~(1 << V4L2_MPEG_VIDEO_MPEG4_LEVEL_5), + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5); + } v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, 0x0, -- cgit v1.2.3 From 9c2a4559435e2915209fd9588253111ee1dc2f7a Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 23 Jun 2017 07:57:27 -0400 Subject: media: coda: do not reassign ctx->tiled_map_type in coda_s_fmt This smatch warning: coda/coda-common.c:706 coda_s_fmt() warn: missing break? reassigning 'ctx->tiled_map_type' can be silenced by moving the ctx->tiled_map_type assignment into the breakout condition. That way the field is not reassigned when falling through to the next switch statement. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index d119b4777328..90c061e50409 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -714,9 +714,10 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f, ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; break; case V4L2_PIX_FMT_NV12: - ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; - if (!disable_tiling) + if (!disable_tiling) { + ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP; break; + } /* else fall through */ case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: -- cgit v1.2.3 From 0c62c679239095b8f2e53ac4127f826565d709bd Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 7 Jul 2017 05:58:27 -0400 Subject: media: coda: extend GOP size range CodaDx6 only accepts GOP sizes up to 60 frames, but CODA960 can handle up to 99 frames. If we disable automatic I frame generation altogether by setting GOP size to 0, we can let an application produce arbitrarily large I frame intervals using the V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME control. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 5 +++-- drivers/media/platform/coda/coda-common.c | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index bba1eb43b5d8..50eed636830f 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1006,7 +1006,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) break; } coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE); - value = ctx->params.gop_size & CODA_GOP_SIZE_MASK; + value = ctx->params.gop_size; coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE); } @@ -1250,7 +1250,8 @@ static int coda_prepare_encode(struct coda_ctx *ctx) force_ipicture = ctx->params.force_ipicture; if (force_ipicture) ctx->params.force_ipicture = false; - else if ((src_buf->sequence % ctx->params.gop_size) == 0) + else if (ctx->params.gop_size != 0 && + (src_buf->sequence % ctx->params.gop_size) == 0) force_ipicture = 1; /* diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 90c061e50409..3f80fb3c3b43 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1746,10 +1746,12 @@ static const struct v4l2_ctrl_ops coda_ctrl_ops = { static void coda_encode_ctrls(struct coda_ctx *ctx) { + int max_gop_size = (ctx->dev->devtype->product == CODA_DX6) ? 60 : 99; + v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1000, 0); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16); + V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, max_gop_size, 1, 16); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 0, 51, 1, 25); v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, -- cgit v1.2.3 From 52fde8491d834a82334f8be54c3560e0e83ddbdb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 7 Jul 2017 05:58:28 -0400 Subject: media: coda: set field of destination buffers Set the field of destination buffers properly. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 50eed636830f..a4abeabfa537 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1412,6 +1412,7 @@ static void coda_finish_encode(struct coda_ctx *ctx) } dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; + dst_buf->field = src_buf->field; dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; @@ -2154,6 +2155,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); dst_buf->sequence = ctx->osequence++; + dst_buf->field = V4L2_FIELD_NONE; dst_buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME); -- cgit v1.2.3 From 551c675782dd4c4441f2c6a8a42380eb7f961616 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 7 Jul 2017 05:58:29 -0400 Subject: media: coda: align internal mpeg4 framebuffers to 16x16 macroblocks This fixes visual artifacts in the first macroblock row of encoded MPEG-4 video output caused by 8 additional lines of luma data leaking into the chroma planes of the internal reference framebuffers: the buffer size is rounded up to a multiple of 16x16 macroblock size, same as for the h.264 encoder. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index a4abeabfa537..2f31c672aba0 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -394,7 +394,8 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx, int i; if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 || - ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264) { + ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264 || + ctx->codec->dst_fourcc == V4L2_PIX_FMT_MPEG4) { width = round_up(q_data->width, 16); height = round_up(q_data->height, 16); } else { -- cgit v1.2.3 From cdb9b988502d975706e9b788e850891ce75906ab Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 7 Jul 2017 05:58:30 -0400 Subject: media: coda: set MPEG-4 encoder class register Explicitly set MPEG-4 encoder class register instead of relying on the default value of 0. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 4 ++++ drivers/media/platform/coda/coda_regs.h | 1 + 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 2f31c672aba0..2a8e13c53f2e 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1655,6 +1655,10 @@ static int __coda_start_decoding(struct coda_ctx *ctx) ctx->params.codec_mode_aux = CODA_MP4_AUX_MPEG4; else ctx->params.codec_mode_aux = 0; + if (src_fourcc == V4L2_PIX_FMT_MPEG4) { + coda_write(dev, CODA_MP4_CLASS_MPEG4, + CODA_CMD_DEC_SEQ_MP4_ASP_CLASS); + } if (src_fourcc == V4L2_PIX_FMT_H264) { if (dev->devtype->product == CODA_7541) { coda_write(dev, ctx->psbuf.paddr, diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h index 77ee46a93427..38df5fd9a2fa 100644 --- a/drivers/media/platform/coda/coda_regs.h +++ b/drivers/media/platform/coda/coda_regs.h @@ -158,6 +158,7 @@ #define CODA_CMD_DEC_SEQ_PS_BB_START 0x194 #define CODA_CMD_DEC_SEQ_PS_BB_SIZE 0x198 #define CODA_CMD_DEC_SEQ_MP4_ASP_CLASS 0x19c +#define CODA_MP4_CLASS_MPEG4 0 #define CODA_CMD_DEC_SEQ_X264_MV_EN 0x19c #define CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE 0x1a0 -- cgit v1.2.3 From be7f1ab26f42706ced959db96380cee2457f4378 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 7 Jul 2017 05:58:31 -0400 Subject: media: coda: mark CODA960 firmware versions 2.3.10 and 3.1.1 as supported Firmware versions 2.3.10 revision 40778 and 3.1.1 revision 46072 are contained in the i.MX firmware download archives provided by NXP at http://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-3.5.7-1.0.0.bin and http://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-5.4.bin, respectively. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 2a8e13c53f2e..95e4b74d5dd0 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -703,6 +703,8 @@ static u32 coda_supported_firmwares[] = { CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5), CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50), CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5), + CODA_FIRMWARE_VERNUM(CODA_960, 2, 3, 10), + CODA_FIRMWARE_VERNUM(CODA_960, 3, 1, 1), }; static bool coda_firmware_supported(u32 vernum) -- cgit v1.2.3 From 8056402c54dcc7fcae48e28e51af3ca07f9480ff Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 17 Jul 2017 06:43:15 -0400 Subject: media: coda: wake up capture queue on encoder stop after output streamoff If an encoder stop command is issued after the output queue has already stopped streaming, the qsequence counter has been reset to 0. Always wake up the capture queue if the output queue is not streaming. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 3f80fb3c3b43..3992ef2bda42 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -933,7 +933,7 @@ static int coda_encoder_cmd(struct file *file, void *fh, ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; /* If there is no buffer in flight, wake up */ - if (ctx->qsequence == ctx->osequence) { + if (!ctx->streamon_out || ctx->qsequence == ctx->osequence) { dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); dst_vq->last_buffer_dequeued = true; -- cgit v1.2.3 From f3112735ebe4f097142da0ad02fca1fc82a50f02 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 20 Feb 2017 05:42:09 -0500 Subject: media: v4l: fwnode: Call CSI2 bus csi2, not csi The function to parse CSI2 bus parameters was called v4l2_fwnode_endpoint_parse_csi_bus(), rename it as v4l2_fwnode_endpoint_parse_csi2_bus() in anticipation of CSI1/CCP2 support. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 153c53ca3925..8df26010d006 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -28,8 +28,8 @@ #include -static int v4l2_fwnode_endpoint_parse_csi_bus(struct fwnode_handle *fwnode, - struct v4l2_fwnode_endpoint *vep) +static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep) { struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2; bool have_clk_lane = false; @@ -176,7 +176,7 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, memset(&vep->bus_type, 0, sizeof(*vep) - offsetof(typeof(*vep), bus_type)); - rval = v4l2_fwnode_endpoint_parse_csi_bus(fwnode, vep); + rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); if (rval) return rval; /* -- cgit v1.2.3 From e07a41f985898b9dae97c99bbb5d3d415b9ecd6c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 25 Feb 2015 14:51:01 -0500 Subject: media: v4l: fwnode: Obtain data bus type from FW Just obtain it. It'll actually get used soon with CSI-1/CCP2. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 8df26010d006..d71dd3913cd9 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -28,6 +28,14 @@ #include +enum v4l2_fwnode_bus_type { + V4L2_FWNODE_BUS_TYPE_GUESS = 0, + V4L2_FWNODE_BUS_TYPE_CSI2_CPHY, + V4L2_FWNODE_BUS_TYPE_CSI1, + V4L2_FWNODE_BUS_TYPE_CCP2, + NR_OF_V4L2_FWNODE_BUS_TYPE, +}; + static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) { @@ -168,6 +176,7 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus( int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) { + u32 bus_type = 0; int rval; fwnode_graph_parse_endpoint(fwnode, &vep->base); @@ -176,6 +185,8 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, memset(&vep->bus_type, 0, sizeof(*vep) - offsetof(typeof(*vep), bus_type)); + fwnode_property_read_u32(fwnode, "bus-type", &bus_type); + rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); if (rval) return rval; -- cgit v1.2.3 From 97bbdf02d905a0a48cb3c953ea352d7f4994643c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 25 Feb 2015 14:39:11 -0500 Subject: media: v4l: Add support for CSI-1 and CCP2 busses CCP2 and CSI-1, are older single data lane serial busses. [mchehab@s-opensource.com: don't use spaces for identation] Signed-off-by: Sakari Ailus Signed-off-by: Pavel Machek Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/pxa_camera.c | 3 ++ drivers/media/platform/soc_camera/soc_mediabus.c | 3 ++ drivers/media/v4l2-core/v4l2-fwnode.c | 58 +++++++++++++++++++----- include/media/v4l2-fwnode.h | 19 ++++++++ include/media/v4l2-mediabus.h | 4 ++ 5 files changed, 76 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 5c3b7cf3638b..3898a5cd8664 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -638,6 +638,9 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; + default: + __WARN(); + return -EINVAL; } return 0; } diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index 57581f626f4c..43192d80beef 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -508,6 +508,9 @@ unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; + default: + __WARN(); + return -EINVAL; } return 0; } diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index d71dd3913cd9..ca755a4832fc 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -154,6 +154,31 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus( } +void v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep, + u32 bus_type) +{ + struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1; + u32 v; + + if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) + bus->clock_inv = v; + + if (!fwnode_property_read_u32(fwnode, "strobe", &v)) + bus->strobe = v; + + if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) + bus->data_lane = v; + + if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) + bus->clock_lane = v; + + if (bus_type == V4L2_FWNODE_BUS_TYPE_CCP2) + vep->bus_type = V4L2_MBUS_CCP2; + else + vep->bus_type = V4L2_MBUS_CSI1; +} + /** * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties * @fwnode: pointer to the endpoint's fwnode handle @@ -187,17 +212,28 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, fwnode_property_read_u32(fwnode, "bus-type", &bus_type); - rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); - if (rval) - return rval; - /* - * Parse the parallel video bus properties only if none - * of the MIPI CSI-2 specific properties were found. - */ - if (vep->bus.mipi_csi2.flags == 0) - v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep); - - return 0; + switch (bus_type) { + case V4L2_FWNODE_BUS_TYPE_GUESS: + rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep); + if (rval) + return rval; + /* + * Parse the parallel video bus properties only if none + * of the MIPI CSI-2 specific properties were found. + */ + if (vep->bus.mipi_csi2.flags == 0) + v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep); + + return 0; + case V4L2_FWNODE_BUS_TYPE_CCP2: + case V4L2_FWNODE_BUS_TYPE_CSI1: + v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, bus_type); + + return 0; + default: + pr_warn("unsupported bus type %u\n", bus_type); + return -EINVAL; + } } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse); diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index ecc1233a873e..29ae22bbbbaf 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -55,6 +55,24 @@ struct v4l2_fwnode_bus_parallel { unsigned char data_shift; }; +/** + * struct v4l2_fwnode_bus_mipi_csi1 - CSI-1/CCP2 data bus structure + * @clock_inv: polarity of clock/strobe signal + * false - not inverted, true - inverted + * @strobe: false - data/clock, true - data/strobe + * @lane_polarity: the polarities of the clock (index 0) and data lanes + index (1) + * @data_lane: the number of the data lane + * @clock_lane: the number of the clock lane + */ +struct v4l2_fwnode_bus_mipi_csi1 { + bool clock_inv; + bool strobe; + bool lane_polarity[2]; + unsigned char data_lane; + unsigned char clock_lane; +}; + /** * struct v4l2_fwnode_endpoint - the endpoint data structure * @base: fwnode endpoint of the v4l2_fwnode @@ -72,6 +90,7 @@ struct v4l2_fwnode_endpoint { enum v4l2_mbus_type bus_type; union { struct v4l2_fwnode_bus_parallel parallel; + struct v4l2_fwnode_bus_mipi_csi1 mipi_csi1; struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2; } bus; u64 *link_frequencies; diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 34cc99e093ef..315c167a95dc 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -69,11 +69,15 @@ * @V4L2_MBUS_PARALLEL: parallel interface with hsync and vsync * @V4L2_MBUS_BT656: parallel interface with embedded synchronisation, can * also be used for BT.1120 + * @V4L2_MBUS_CSI1: MIPI CSI-1 serial interface + * @V4L2_MBUS_CCP2: CCP2 (Compact Camera Port 2) * @V4L2_MBUS_CSI2: MIPI CSI-2 serial interface */ enum v4l2_mbus_type { V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, + V4L2_MBUS_CSI1, + V4L2_MBUS_CCP2, V4L2_MBUS_CSI2, }; -- cgit v1.2.3 From 9d2656e9c09739c5dbd2dd516a8d90f27ed846ad Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 14 Feb 2017 17:39:09 -0500 Subject: media: smiapp: add CCP2 support Add support for CCP2 connected SMIA sensors as found on the Nokia N900. Signed-off-by: Sebastian Reichel Signed-off-by: Ivaylo Dimitrov Signed-off-by: Pavel Machek Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index e0b0c032c4ac..aff55e1dffe7 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2809,13 +2809,19 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) switch (bus_cfg->bus_type) { case V4L2_MBUS_CSI2: hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; + hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; + break; + case V4L2_MBUS_CCP2: + hwcfg->csi_signalling_mode = (bus_cfg->bus.mipi_csi1.strobe) ? + SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE : + SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK; + hwcfg->lanes = 1; break; - /* FIXME: add CCP2 support. */ default: + dev_err(dev, "unsupported bus %u\n", bus_cfg->bus_type); goto out_err; } - hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; dev_dbg(dev, "lanes %u\n", hwcfg->lanes); /* NVM size is not mandatory */ @@ -2828,8 +2834,8 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) goto out_err; } - dev_dbg(dev, "nvm %d, clk %d, csi %d\n", hwcfg->nvm_size, - hwcfg->ext_clk, hwcfg->csi_signalling_mode); + dev_dbg(dev, "nvm %d, clk %d, mode %d\n", + hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode); if (!bus_cfg->nr_of_link_frequencies) { dev_warn(dev, "no link frequencies defined\n"); -- cgit v1.2.3 From 831f3494d2327ef581bdae934caa7b6c9bc34da8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 28 Feb 2017 07:38:44 -0500 Subject: media: omap3isp: Check for valid port in endpoints Check that we do have a valid port in an endpoint, return an error if not. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 9df64c189883..40d1a200be32 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2080,7 +2080,7 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, default: dev_warn(dev, "%s: invalid interface %u\n", to_of_node(fwnode)->full_name, vep.base.port); - break; + return -EINVAL; } return 0; -- cgit v1.2.3 From 838a6c561899e7c595396321dede41bc04f1fb7e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sat, 4 Mar 2017 10:07:08 -0500 Subject: media: omap3isp: Destroy CSI-2 phy mutexes in error and module removal The CSI-2 phy driver did initialise mutexes in its init function but there was no corresponding cleanup function destroying them. Fix that. Also clean up ISP module initialisation a little. Signed-off-by: Sakari Ailus Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 6 ++++-- drivers/media/platform/omap3isp/ispcsiphy.c | 6 ++++++ drivers/media/platform/omap3isp/ispcsiphy.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 40d1a200be32..088dc8b1b78a 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1859,6 +1859,7 @@ static void isp_cleanup_modules(struct isp_device *isp) omap3isp_ccdc_cleanup(isp); omap3isp_ccp2_cleanup(isp); omap3isp_csi2_cleanup(isp); + omap3isp_csiphy_cleanup(isp); } static int isp_initialize_modules(struct isp_device *isp) @@ -1868,7 +1869,7 @@ static int isp_initialize_modules(struct isp_device *isp) ret = omap3isp_csiphy_init(isp); if (ret < 0) { dev_err(isp->dev, "CSI PHY initialization failed\n"); - goto error_csiphy; + return ret; } ret = omap3isp_csi2_init(isp); @@ -1936,7 +1937,8 @@ error_ccdc: error_ccp2: omap3isp_csi2_cleanup(isp); error_csi2: -error_csiphy: + omap3isp_csiphy_cleanup(isp); + return ret; } diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 871d4fe09c7f..83940e9d8291 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -345,3 +345,9 @@ int omap3isp_csiphy_init(struct isp_device *isp) return 0; } + +void omap3isp_csiphy_cleanup(struct isp_device *isp) +{ + mutex_destroy(&isp->isp_csiphy1.mutex); + mutex_destroy(&isp->isp_csiphy2.mutex); +} diff --git a/drivers/media/platform/omap3isp/ispcsiphy.h b/drivers/media/platform/omap3isp/ispcsiphy.h index 28b63b28f9f7..978ca5c80a6c 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.h +++ b/drivers/media/platform/omap3isp/ispcsiphy.h @@ -39,5 +39,6 @@ struct isp_csiphy { int omap3isp_csiphy_acquire(struct isp_csiphy *phy); void omap3isp_csiphy_release(struct isp_csiphy *phy); int omap3isp_csiphy_init(struct isp_device *isp); +void omap3isp_csiphy_cleanup(struct isp_device *isp); #endif /* OMAP3_ISP_CSI_PHY_H */ -- cgit v1.2.3 From 3a738c3fd8abc5927a9f98a913298c1e6f8a95fe Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 13 Jul 2017 12:11:32 -0400 Subject: media: omap3isp: Explicitly set the number of CSI-2 lanes used in lane cfg The omap3isp driver extracts the CSI-2 lane configuration from the V4L2 fwnode endpoint but misses the number of lanes itself. Get this information and use it in PHY configuration. Signed-off-by: Sakari Ailus Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 5 ++++- drivers/media/platform/omap3isp/ispcsiphy.c | 16 +++++++++++----- drivers/media/platform/omap3isp/omap3isp.h | 3 +++ 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 088dc8b1b78a..db2cccb57ceb 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2061,7 +2061,10 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, buscfg->bus.csi2.lanecfg.clk.pol, buscfg->bus.csi2.lanecfg.clk.pos); - for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) { + buscfg->bus.csi2.num_data_lanes = + vep.bus.mipi_csi2.num_data_lanes; + + for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { buscfg->bus.csi2.lanecfg.data[i].pos = vep.bus.mipi_csi2.data_lanes[i]; buscfg->bus.csi2.lanecfg.data[i].pol = diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 83940e9d8291..3efa71396aae 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -169,7 +169,7 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) struct isp_bus_cfg *buscfg = pipe->external->host_priv; struct isp_csiphy_lanes_cfg *lanes; int csi2_ddrclk_khz; - unsigned int used_lanes = 0; + unsigned int num_data_lanes, used_lanes = 0; unsigned int i; u32 reg; @@ -181,13 +181,19 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) } if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1 - || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) + || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) { lanes = &buscfg->bus.ccp2.lanecfg; - else + num_data_lanes = 1; + } else { lanes = &buscfg->bus.csi2.lanecfg; + num_data_lanes = buscfg->bus.csi2.num_data_lanes; + } + + if (num_data_lanes > phy->num_data_lanes) + return -EINVAL; /* Clock and data lanes verification */ - for (i = 0; i < phy->num_data_lanes; i++) { + for (i = 0; i < num_data_lanes; i++) { if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3) return -EINVAL; @@ -243,7 +249,7 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) /* DPHY lane configuration */ reg = isp_reg_readl(csi2->isp, phy->cfg_regs, ISPCSI2_PHY_CFG); - for (i = 0; i < phy->num_data_lanes; i++) { + for (i = 0; i < num_data_lanes; i++) { reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) | ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1)); reg |= (lanes->data[i].pol << diff --git a/drivers/media/platform/omap3isp/omap3isp.h b/drivers/media/platform/omap3isp/omap3isp.h index 443e8f7673e2..3c26f9a3f508 100644 --- a/drivers/media/platform/omap3isp/omap3isp.h +++ b/drivers/media/platform/omap3isp/omap3isp.h @@ -114,10 +114,13 @@ struct isp_ccp2_cfg { /** * struct isp_csi2_cfg - CSI2 interface configuration * @crc: Enable the cyclic redundancy check + * @lanecfg: CSI-2 lane configuration + * @num_data_lanes: The number of data lanes in use */ struct isp_csi2_cfg { unsigned crc:1; struct isp_csiphy_lanes_cfg lanecfg; + u8 num_data_lanes; }; struct isp_bus_cfg { -- cgit v1.2.3 From a6b687df8a8742511ae46f4363ac6a0cba0d31b1 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 13 Jul 2017 06:36:59 -0400 Subject: media: omap3isp: add CSI1 support CSI-2 PHY power management is only needed for major version 15 of the ISP. Additionally, set the CCP2 PHY for previous ISP versions as well. These changes are necessary for CCP2 support. Signed-off-by: Pavel Machek Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccp2.c | 1 + drivers/media/platform/omap3isp/ispcsiphy.c | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index ca095238510d..588f67a89f79 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1141,6 +1141,7 @@ int omap3isp_ccp2_init(struct isp_device *isp) "Could not get regulator vdds_csib\n"); ccp2->vdds_csib = NULL; } + ccp2->phy = &isp->isp_csiphy2; } else if (isp->revision == ISP_REVISION_15_0) { ccp2->phy = &isp->isp_csiphy1; } diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 3efa71396aae..addc6efbb033 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -292,13 +292,16 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy) if (rval < 0) goto done; - rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON); - if (rval) { - regulator_disable(phy->vdd); - goto done; + if (phy->isp->revision == ISP_REVISION_15_0) { + rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON); + if (rval) { + regulator_disable(phy->vdd); + goto done; + } + + csiphy_power_autoswitch_enable(phy, true); } - csiphy_power_autoswitch_enable(phy, true); phy->phy_in_use = 1; done: @@ -317,8 +320,10 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) csiphy_routing_cfg(phy, buscfg->interface, false, buscfg->bus.ccp2.phy_layer); - csiphy_power_autoswitch_enable(phy, false); - csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); + if (phy->isp->revision == ISP_REVISION_15_0) { + csiphy_power_autoswitch_enable(phy, false); + csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); + } regulator_disable(phy->vdd); phy->phy_in_use = 0; } -- cgit v1.2.3 From a4573084cb7596b13e0853fa97b069c8fb30b6e7 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 2 Mar 2017 07:45:32 -0500 Subject: media: omap3isp: Return -EPROBE_DEFER if the required regulators can't be obtained If regulator returns -EPROBE_DEFER, we need to return it too, so that omap3isp will be re-probed when regulator is ready. Signed-off-by: Pavel Machek Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 3 ++- drivers/media/platform/omap3isp/ispccp2.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index db2cccb57ceb..dbaede0d8974 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1880,7 +1880,8 @@ static int isp_initialize_modules(struct isp_device *isp) ret = omap3isp_ccp2_init(isp); if (ret < 0) { - dev_err(isp->dev, "CCP2 initialization failed\n"); + if (ret != -EPROBE_DEFER) + dev_err(isp->dev, "CCP2 initialization failed\n"); goto error_ccp2; } diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 588f67a89f79..8b6f7d2e79a0 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1137,6 +1137,11 @@ int omap3isp_ccp2_init(struct isp_device *isp) if (isp->revision == ISP_REVISION_2_0) { ccp2->vdds_csib = devm_regulator_get(isp->dev, "vdds_csib"); if (IS_ERR(ccp2->vdds_csib)) { + if (PTR_ERR(ccp2->vdds_csib) == -EPROBE_DEFER) { + dev_dbg(isp->dev, + "Can't get regulator vdds_csib, deferring probing\n"); + return -EPROBE_DEFER; + } dev_dbg(isp->dev, "Could not get regulator vdds_csib\n"); ccp2->vdds_csib = NULL; -- cgit v1.2.3 From 58f6d3675a2c423a95739ad6719607a7681af954 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 28 Feb 2017 06:53:27 -0500 Subject: media: omap3isp: Ignore endpoints with invalid configuration If endpoint has an invalid configuration, ignore it instead of happily proceeding to use it nonetheless. Ignoring such an endpoint is better than failing since there could be multiple endpoints, only some of which are bad. Signed-off-by: Sakari Ailus Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index dbaede0d8974..2de7a27bb0e5 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2111,10 +2111,12 @@ static int isp_fwnodes_parse(struct device *dev, if (!isd) goto error; - notifier->subdevs[notifier->num_subdevs] = &isd->asd; + if (isp_fwnode_parse(dev, fwnode, isd)) { + devm_kfree(dev, isd); + continue; + } - if (isp_fwnode_parse(dev, fwnode, isd)) - goto error; + notifier->subdevs[notifier->num_subdevs] = &isd->asd; isd->asd.match.fwnode.fwnode = fwnode_graph_get_remote_port_parent(fwnode); -- cgit v1.2.3 From f7b51859e830398a6b1faaca171156c8b18848a8 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Wed, 5 Jul 2017 04:44:47 -0400 Subject: media: ov5645: Set media entity function Set media entity function to MEDIA_ENT_F_CAM_SENSOR. Signed-off-by: Todor Tomov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5645.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index d1e844f7f03f..bb3dd0d057dd 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -1229,6 +1229,7 @@ static int ov5645_probe(struct i2c_client *client, ov5645->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ov5645->pad.flags = MEDIA_PAD_FL_SOURCE; ov5645->sd.dev = &client->dev; + ov5645->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&ov5645->sd.entity, 1, &ov5645->pad); if (ret < 0) { -- cgit v1.2.3 From 1c2177fd99ab9e622126b1ec29f2a452140edf86 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Wed, 5 Jul 2017 04:44:48 -0400 Subject: media: ov5645: Add control to export pixel clock frequency Add suport for standard V4L2_CID_PIXEL_RATE control. The pixel clock frequency value is specific for each sensor mode so the sensor mode structure is extended to add this. The control is read-only and its value is updated when the sensor mode is changed - on set_format. Signed-off-by: Todor Tomov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5645.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index bb3dd0d057dd..4583f66f7160 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -80,6 +80,7 @@ struct ov5645_mode_info { u32 height; const struct reg_value *data; u32 data_size; + u32 pixel_clock; }; struct ov5645 { @@ -99,6 +100,7 @@ struct ov5645 { const struct ov5645_mode_info *current_mode; struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *pixel_clock; /* Cached register values */ u8 aec_pk_manual; @@ -510,19 +512,22 @@ static const struct ov5645_mode_info ov5645_mode_info_data[] = { .width = 1280, .height = 960, .data = ov5645_setting_sxga, - .data_size = ARRAY_SIZE(ov5645_setting_sxga) + .data_size = ARRAY_SIZE(ov5645_setting_sxga), + .pixel_clock = 111440000 }, { .width = 1920, .height = 1080, .data = ov5645_setting_1080p, - .data_size = ARRAY_SIZE(ov5645_setting_1080p) + .data_size = ARRAY_SIZE(ov5645_setting_1080p), + .pixel_clock = 167160000 }, { .width = 2592, .height = 1944, .data = ov5645_setting_full, - .data_size = ARRAY_SIZE(ov5645_setting_full) + .data_size = ARRAY_SIZE(ov5645_setting_full), + .pixel_clock = 167160000 }, }; @@ -969,6 +974,7 @@ static int ov5645_set_format(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *__format; struct v4l2_rect *__crop; const struct ov5645_mode_info *new_mode; + int ret; __crop = __ov5645_get_pad_crop(ov5645, cfg, format->pad, format->which); @@ -978,8 +984,14 @@ static int ov5645_set_format(struct v4l2_subdev *sd, __crop->width = new_mode->width; __crop->height = new_mode->height; - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + ret = v4l2_ctrl_s_ctrl_int64(ov5645->pixel_clock, + new_mode->pixel_clock); + if (ret < 0) + return ret; + ov5645->current_mode = new_mode; + } __format = __ov5645_get_pad_format(ov5645, cfg, format->pad, format->which); @@ -1197,7 +1209,7 @@ static int ov5645_probe(struct i2c_client *client, mutex_init(&ov5645->power_lock); - v4l2_ctrl_handler_init(&ov5645->ctrls, 7); + v4l2_ctrl_handler_init(&ov5645->ctrls, 8); v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, V4L2_CID_SATURATION, -4, 4, 1, 0); v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, @@ -1215,6 +1227,10 @@ static int ov5645_probe(struct i2c_client *client, V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov5645_test_pattern_menu) - 1, 0, 0, ov5645_test_pattern_menu); + ov5645->pixel_clock = v4l2_ctrl_new_std(&ov5645->ctrls, + &ov5645_ctrl_ops, + V4L2_CID_PIXEL_RATE, + 1, INT_MAX, 1, 1); ov5645->sd.ctrl_handler = &ov5645->ctrls; -- cgit v1.2.3 From e72e6cbe7962fc72e9b13ffaa746ab93d7a20a9b Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Wed, 5 Jul 2017 04:44:49 -0400 Subject: media: ov5645: Add control to export CSI2 link frequency Add suport for standard integer menu V4L2_CID_LINK_FREQ control. The CSI2 link frequency value is specific for each sensor mode so the sensor mode structure is extended to add this. The control is made read-only and its value is updated when the sensor mode is changed - on set_format. Signed-off-by: Todor Tomov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5645.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 4583f66f7160..d28845f7356f 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -81,6 +81,7 @@ struct ov5645_mode_info { const struct reg_value *data; u32 data_size; u32 pixel_clock; + u32 link_freq; }; struct ov5645 { @@ -101,6 +102,7 @@ struct ov5645 { struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *pixel_clock; + struct v4l2_ctrl *link_freq; /* Cached register values */ u8 aec_pk_manual; @@ -507,27 +509,35 @@ static const struct reg_value ov5645_setting_full[] = { { 0x4202, 0x00 } }; +static const s64 link_freq[] = { + 222880000, + 334320000 +}; + static const struct ov5645_mode_info ov5645_mode_info_data[] = { { .width = 1280, .height = 960, .data = ov5645_setting_sxga, .data_size = ARRAY_SIZE(ov5645_setting_sxga), - .pixel_clock = 111440000 + .pixel_clock = 111440000, + .link_freq = 0 /* an index in link_freq[] */ }, { .width = 1920, .height = 1080, .data = ov5645_setting_1080p, .data_size = ARRAY_SIZE(ov5645_setting_1080p), - .pixel_clock = 167160000 + .pixel_clock = 167160000, + .link_freq = 1 /* an index in link_freq[] */ }, { .width = 2592, .height = 1944, .data = ov5645_setting_full, .data_size = ARRAY_SIZE(ov5645_setting_full), - .pixel_clock = 167160000 + .pixel_clock = 167160000, + .link_freq = 1 /* an index in link_freq[] */ }, }; @@ -990,6 +1000,11 @@ static int ov5645_set_format(struct v4l2_subdev *sd, if (ret < 0) return ret; + ret = v4l2_ctrl_s_ctrl(ov5645->link_freq, + new_mode->link_freq); + if (ret < 0) + return ret; + ov5645->current_mode = new_mode; } @@ -1209,7 +1224,7 @@ static int ov5645_probe(struct i2c_client *client, mutex_init(&ov5645->power_lock); - v4l2_ctrl_handler_init(&ov5645->ctrls, 8); + v4l2_ctrl_handler_init(&ov5645->ctrls, 9); v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, V4L2_CID_SATURATION, -4, 4, 1, 0); v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops, @@ -1231,6 +1246,13 @@ static int ov5645_probe(struct i2c_client *client, &ov5645_ctrl_ops, V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); + ov5645->link_freq = v4l2_ctrl_new_int_menu(&ov5645->ctrls, + &ov5645_ctrl_ops, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(link_freq) - 1, + 0, link_freq); + if (ov5645->link_freq) + ov5645->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ov5645->sd.ctrl_handler = &ov5645->ctrls; -- cgit v1.2.3 From 86026abf47b245a2d642f5407ec26659f91e499b Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Jul 2017 14:29:47 -0400 Subject: media: smiapp: make various const arrays static Don't populate const arrays on the stack but instead make them static. Makes the object code smaller and saves nearly 550 bytes. Before: text data bss dec hex filename 3638 752 0 4390 1126 smiapp-quirk.o After: text data bss dec hex filename 2802 1040 0 3842 f02 smiapp-quirk.o Signed-off-by: Colin Ian King Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-quirk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.c b/drivers/media/i2c/smiapp/smiapp-quirk.c index cb128eae9c54..95c0272bb014 100644 --- a/drivers/media/i2c/smiapp/smiapp-quirk.c +++ b/drivers/media/i2c/smiapp/smiapp-quirk.c @@ -71,7 +71,7 @@ static int jt8ew9_limits(struct smiapp_sensor *sensor) static int jt8ew9_post_poweron(struct smiapp_sensor *sensor) { - const struct smiapp_reg_8 regs[] = { + static const struct smiapp_reg_8 regs[] = { { 0x30a3, 0xd8 }, /* Output port control : LVDS ports only */ { 0x30ae, 0x00 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */ { 0x30af, 0xd0 }, /* 0x0307 pll_multiplier maximum value on PLL input 9.6MHz ( 19.2MHz is divided on pre_pll_div) */ @@ -115,7 +115,7 @@ const struct smiapp_quirk smiapp_jt8ew9_quirk = { static int imx125es_post_poweron(struct smiapp_sensor *sensor) { /* Taken from v02. No idea what the other two are. */ - const struct smiapp_reg_8 regs[] = { + static const struct smiapp_reg_8 regs[] = { /* * 0x3302: clk during frame blanking: * 0x00 - HS mode, 0x01 - LP11 @@ -145,7 +145,7 @@ static int jt8ev1_post_poweron(struct smiapp_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); int rval; - const struct smiapp_reg_8 regs[] = { + static const struct smiapp_reg_8 regs[] = { { 0x3031, 0xcd }, /* For digital binning (EQ_MONI) */ { 0x30a3, 0xd0 }, /* FLASH STROBE enable */ { 0x3237, 0x00 }, /* For control of pulse timing for ADC */ @@ -166,7 +166,7 @@ static int jt8ev1_post_poweron(struct smiapp_sensor *sensor) { 0x33cf, 0xec }, /* For Black sun */ { 0x3328, 0x80 }, /* Ugh. No idea what's this. */ }; - const struct smiapp_reg_8 regs_96[] = { + static const struct smiapp_reg_8 regs_96[] = { { 0x30ae, 0x00 }, /* For control of ADC clock */ { 0x30af, 0xd0 }, { 0x30b0, 0x01 }, -- cgit v1.2.3 From 5de35c9b8dcd10dcedba2917e2ab4c1f3ca28dc6 Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Thu, 13 Jul 2017 21:51:27 -0400 Subject: media: i2c: Add Omnivision OV5670 5M sensor support Provides single source pad with up to 2592x1944 pixels at 10-bit raw bayer format over MIPI CSI2 two lanes at 840Mbps/lane. The driver supports following features: - up to 30fps at 5M pixels - manual exposure - digital/analog gain - V-blank/H-blank - test pattern - media controller - runtime pm [mchehab@s-opensource.com: fix a trivial merge conflict at Makefile] Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/ov5670.c | 2588 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2601 insertions(+) create mode 100644 drivers/media/i2c/ov5670.c (limited to 'drivers') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 6add6ad53afe..b64c4ebd65eb 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -604,6 +604,18 @@ config VIDEO_OV6650 To compile this driver as a module, choose M here: the module will be called ov6650. +config VIDEO_OV5670 + tristate "OmniVision OV5670 sensor support" + depends on I2C && VIDEO_V4L2 + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV5670 camera. + + To compile this driver as a module, choose M here: the + module will be called ov5670. + config VIDEO_OV7640 tristate "OmniVision OV7640 sensor support" depends on I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index aefb3bcb1e81..84673c79e01a 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV5647) += ov5647.o +obj-$(CONFIG_VIDEO_OV5670) += ov5670.o obj-$(CONFIG_VIDEO_OV6650) += ov6650.o obj-$(CONFIG_VIDEO_OV7640) += ov7640.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c new file mode 100644 index 000000000000..7de80645dd6f --- /dev/null +++ b/drivers/media/i2c/ov5670.c @@ -0,0 +1,2588 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +#define OV5670_REG_CHIP_ID 0x300a +#define OV5670_CHIP_ID 0x005670 + +#define OV5670_REG_MODE_SELECT 0x0100 +#define OV5670_MODE_STANDBY 0x00 +#define OV5670_MODE_STREAMING 0x01 + +#define OV5670_REG_SOFTWARE_RST 0x0103 +#define OV5670_SOFTWARE_RST 0x01 + +/* vertical-timings from sensor */ +#define OV5670_REG_VTS 0x380e +#define OV5670_VTS_30FPS 0x0808 /* default for 30 fps */ +#define OV5670_VTS_MAX 0xffff +#define OV5670_VBLANK_MIN 56 + +/* horizontal-timings from sensor */ +#define OV5670_REG_HTS 0x380c +#define OV5670_DEF_PPL 3360 /* Default pixels per line */ + +/* Exposure controls from sensor */ +#define OV5670_REG_EXPOSURE 0x3500 +#define OV5670_EXPOSURE_MIN 4 +#define OV5670_EXPOSURE_STEP 1 + +/* Analog gain controls from sensor */ +#define OV5670_REG_ANALOG_GAIN 0x3508 +#define ANALOG_GAIN_MIN 0 +#define ANALOG_GAIN_MAX 8191 +#define ANALOG_GAIN_STEP 1 +#define ANALOG_GAIN_DEFAULT 128 + +/* Digital gain controls from sensor */ +#define OV5670_REG_R_DGTL_GAIN 0x5032 +#define OV5670_REG_G_DGTL_GAIN 0x5034 +#define OV5670_REG_B_DGTL_GAIN 0x5036 +#define OV5670_DGTL_GAIN_MIN 0 +#define OV5670_DGTL_GAIN_MAX 4095 +#define OV5670_DGTL_GAIN_STEP 1 +#define OV5670_DGTL_GAIN_DEFAULT 1024 + +/* Test Pattern Control */ +#define OV5670_REG_TEST_PATTERN 0x4303 +#define OV5670_TEST_PATTERN_ENABLE BIT(3) +#define OV5670_REG_TEST_PATTERN_CTRL 0x4320 + +#define OV5670_REG_VALUE_08BIT 1 +#define OV5670_REG_VALUE_16BIT 2 +#define OV5670_REG_VALUE_24BIT 3 + +/* Initial number of frames to skip to avoid possible garbage */ +#define OV5670_NUM_OF_SKIP_FRAMES 2 + +struct ov5670_reg { + u16 address; + u8 val; +}; + +struct ov5670_reg_list { + u32 num_of_regs; + const struct ov5670_reg *regs; +}; + +struct ov5670_link_freq_config { + u32 pixel_rate; + const struct ov5670_reg_list reg_list; +}; + +struct ov5670_mode { + /* Frame width in pixels */ + u32 width; + + /* Frame height in pixels */ + u32 height; + + /* Vertical timining size */ + u32 vts; + + /* Link frequency needed for this resolution */ + u32 link_freq_index; + + /* Sensor register settings for this resolution */ + const struct ov5670_reg_list reg_list; +}; + +static const struct ov5670_reg mipi_data_rate_840mbps[] = { + {0x0300, 0x04}, + {0x0301, 0x00}, + {0x0302, 0x84}, + {0x0303, 0x00}, + {0x0304, 0x03}, + {0x0305, 0x01}, + {0x0306, 0x01}, + {0x030a, 0x00}, + {0x030b, 0x00}, + {0x030c, 0x00}, + {0x030d, 0x26}, + {0x030e, 0x00}, + {0x030f, 0x06}, + {0x0312, 0x01}, + {0x3031, 0x0a}, +}; + +static const struct ov5670_reg mode_2592x1944_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x04}, + {0x3509, 0x00}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x00}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x10}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x84}, + {0x3821, 0x46}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x01}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x0d}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x40}, + {0x4503, 0x10}, + {0x4508, 0xaa}, + {0x4509, 0xaa}, + {0x450a, 0x00}, + {0x450b, 0x00}, + {0x4600, 0x01}, + {0x4601, 0x03}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x08}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x06}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x3503, 0x00} +}; + +static const struct ov5670_reg mode_1296x972_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x07}, + {0x3509, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x00}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x08}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x05}, + {0x3809, 0x10}, + {0x380a, 0x03}, + {0x380b, 0xcc}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x04}, + {0x3814, 0x03}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x94}, + {0x3821, 0x47}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x03}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x05}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x48}, + {0x4503, 0x10}, + {0x4508, 0x55}, + {0x4509, 0x55}, + {0x450a, 0x00}, + {0x450b, 0x00}, + {0x4600, 0x00}, + {0x4601, 0x81}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x10}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x3503, 0x00} +}; + +static const struct ov5670_reg mode_648x486_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x04}, + {0x3509, 0x00}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x04}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x08}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x02}, + {0x3809, 0x88}, + {0x380a, 0x01}, + {0x380b, 0xe6}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3814, 0x07}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x94}, + {0x3821, 0xc6}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x07}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x05}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x40}, + {0x4503, 0x10}, + {0x4508, 0x55}, + {0x4509, 0x55}, + {0x450a, 0x02}, + {0x450b, 0x00}, + {0x4600, 0x00}, + {0x4601, 0x40}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x10}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x06}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x3503, 0x00} +}; + +static const struct ov5670_reg mode_2560x1440_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x04}, + {0x3509, 0x00}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x00}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x10}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x0a}, + {0x3809, 0x00}, + {0x380a, 0x05}, + {0x380b, 0xa0}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x84}, + {0x3821, 0x46}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x01}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x0d}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x40}, + {0x4503, 0x10}, + {0x4508, 0xaa}, + {0x4509, 0xaa}, + {0x450a, 0x00}, + {0x450b, 0x00}, + {0x4600, 0x01}, + {0x4601, 0x00}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x08}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x06}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3} +}; + +static const struct ov5670_reg mode_1280x720_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x04}, + {0x3509, 0x00}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x00}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x08}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3814, 0x03}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x94}, + {0x3821, 0x47}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x03}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x05}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x48}, + {0x4503, 0x10}, + {0x4508, 0x55}, + {0x4509, 0x55}, + {0x450a, 0x00}, + {0x450b, 0x00}, + {0x4600, 0x00}, + {0x4601, 0x80}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x10}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x06}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x3503, 0x00} +}; + +static const struct ov5670_reg mode_640x360_regs[] = { + {0x3000, 0x00}, + {0x3002, 0x21}, + {0x3005, 0xf0}, + {0x3007, 0x00}, + {0x3015, 0x0f}, + {0x3018, 0x32}, + {0x301a, 0xf0}, + {0x301b, 0xf0}, + {0x301c, 0xf0}, + {0x301d, 0xf0}, + {0x301e, 0xf0}, + {0x3030, 0x00}, + {0x3031, 0x0a}, + {0x303c, 0xff}, + {0x303e, 0xff}, + {0x3040, 0xf0}, + {0x3041, 0x00}, + {0x3042, 0xf0}, + {0x3106, 0x11}, + {0x3500, 0x00}, + {0x3501, 0x80}, + {0x3502, 0x00}, + {0x3503, 0x04}, + {0x3504, 0x03}, + {0x3505, 0x83}, + {0x3508, 0x04}, + {0x3509, 0x00}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3601, 0xc8}, + {0x3610, 0x88}, + {0x3612, 0x48}, + {0x3614, 0x5b}, + {0x3615, 0x96}, + {0x3621, 0xd0}, + {0x3622, 0x00}, + {0x3623, 0x04}, + {0x3633, 0x13}, + {0x3634, 0x13}, + {0x3635, 0x13}, + {0x3636, 0x13}, + {0x3645, 0x13}, + {0x3646, 0x82}, + {0x3650, 0x00}, + {0x3652, 0xff}, + {0x3655, 0x20}, + {0x3656, 0xff}, + {0x365a, 0xff}, + {0x365e, 0xff}, + {0x3668, 0x00}, + {0x366a, 0x07}, + {0x366e, 0x08}, + {0x366d, 0x00}, + {0x366f, 0x80}, + {0x3700, 0x28}, + {0x3701, 0x10}, + {0x3702, 0x3a}, + {0x3703, 0x19}, + {0x3704, 0x10}, + {0x3705, 0x00}, + {0x3706, 0x66}, + {0x3707, 0x08}, + {0x3708, 0x34}, + {0x3709, 0x40}, + {0x370a, 0x01}, + {0x370b, 0x1b}, + {0x3714, 0x24}, + {0x371a, 0x3e}, + {0x3733, 0x00}, + {0x3734, 0x00}, + {0x373a, 0x05}, + {0x373b, 0x06}, + {0x373c, 0x0a}, + {0x373f, 0xa0}, + {0x3755, 0x00}, + {0x3758, 0x00}, + {0x375b, 0x0e}, + {0x3766, 0x5f}, + {0x3768, 0x00}, + {0x3769, 0x22}, + {0x3773, 0x08}, + {0x3774, 0x1f}, + {0x3776, 0x06}, + {0x37a0, 0x88}, + {0x37a1, 0x5c}, + {0x37a7, 0x88}, + {0x37a8, 0x70}, + {0x37aa, 0x88}, + {0x37ab, 0x48}, + {0x37b3, 0x66}, + {0x37c2, 0x04}, + {0x37c5, 0x00}, + {0x37c8, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x0c}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x33}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x02}, + {0x3809, 0x80}, + {0x380a, 0x01}, + {0x380b, 0x68}, + {0x380c, 0x06}, + {0x380d, 0x90}, + {0x380e, 0x08}, + {0x380f, 0x08}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3814, 0x07}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x94}, + {0x3821, 0xc6}, + {0x3822, 0x48}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382a, 0x07}, + {0x382b, 0x01}, + {0x3830, 0x08}, + {0x3836, 0x02}, + {0x3837, 0x00}, + {0x3838, 0x10}, + {0x3841, 0xff}, + {0x3846, 0x48}, + {0x3861, 0x00}, + {0x3862, 0x04}, + {0x3863, 0x06}, + {0x3a11, 0x01}, + {0x3a12, 0x78}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3c00, 0x89}, + {0x3c01, 0xab}, + {0x3c02, 0x01}, + {0x3c03, 0x00}, + {0x3c04, 0x00}, + {0x3c05, 0x03}, + {0x3c06, 0x00}, + {0x3c07, 0x05}, + {0x3c0c, 0x00}, + {0x3c0d, 0x00}, + {0x3c0e, 0x00}, + {0x3c0f, 0x00}, + {0x3c40, 0x00}, + {0x3c41, 0xa3}, + {0x3c43, 0x7d}, + {0x3c45, 0xd7}, + {0x3c47, 0xfc}, + {0x3c50, 0x05}, + {0x3c52, 0xaa}, + {0x3c54, 0x71}, + {0x3c56, 0x80}, + {0x3d85, 0x17}, + {0x3f03, 0x00}, + {0x3f0a, 0x00}, + {0x3f0b, 0x00}, + {0x4001, 0x60}, + {0x4009, 0x05}, + {0x4020, 0x00}, + {0x4021, 0x00}, + {0x4022, 0x00}, + {0x4023, 0x00}, + {0x4024, 0x00}, + {0x4025, 0x00}, + {0x4026, 0x00}, + {0x4027, 0x00}, + {0x4028, 0x00}, + {0x4029, 0x00}, + {0x402a, 0x00}, + {0x402b, 0x00}, + {0x402c, 0x00}, + {0x402d, 0x00}, + {0x402e, 0x00}, + {0x402f, 0x00}, + {0x4040, 0x00}, + {0x4041, 0x03}, + {0x4042, 0x00}, + {0x4043, 0x7A}, + {0x4044, 0x00}, + {0x4045, 0x7A}, + {0x4046, 0x00}, + {0x4047, 0x7A}, + {0x4048, 0x00}, + {0x4049, 0x7A}, + {0x4307, 0x30}, + {0x4500, 0x58}, + {0x4501, 0x04}, + {0x4502, 0x40}, + {0x4503, 0x10}, + {0x4508, 0x55}, + {0x4509, 0x55}, + {0x450a, 0x02}, + {0x450b, 0x00}, + {0x4600, 0x00}, + {0x4601, 0x40}, + {0x4700, 0xa4}, + {0x4800, 0x4c}, + {0x4816, 0x53}, + {0x481f, 0x40}, + {0x4837, 0x13}, + {0x5000, 0x56}, + {0x5001, 0x01}, + {0x5002, 0x28}, + {0x5004, 0x0c}, + {0x5006, 0x0c}, + {0x5007, 0xe0}, + {0x5008, 0x01}, + {0x5009, 0xb0}, + {0x5901, 0x00}, + {0x5a01, 0x00}, + {0x5a03, 0x00}, + {0x5a04, 0x0c}, + {0x5a05, 0xe0}, + {0x5a06, 0x09}, + {0x5a07, 0xb0}, + {0x5a08, 0x06}, + {0x5e00, 0x00}, + {0x3734, 0x40}, + {0x5b00, 0x01}, + {0x5b01, 0x10}, + {0x5b02, 0x01}, + {0x5b03, 0xdb}, + {0x3d8c, 0x71}, + {0x3d8d, 0xea}, + {0x4017, 0x10}, + {0x3618, 0x2a}, + {0x5780, 0x3e}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x06}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x3503, 0x00} +}; + +static const char * const ov5670_test_pattern_menu[] = { + "Disabled", + "Vertical Color Bar Type 1", +}; + +/* Supported link frequencies */ +#define OV5670_LINK_FREQ_420MHZ 420000000 +#define OV5670_LINK_FREQ_420MHZ_INDEX 0 +static const struct ov5670_link_freq_config link_freq_configs[] = { + { + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + .pixel_rate = (OV5670_LINK_FREQ_420MHZ * 2 * 2) / 10, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mipi_data_rate_840mbps), + .regs = mipi_data_rate_840mbps, + } + } +}; + +static const s64 link_freq_menu_items[] = { + OV5670_LINK_FREQ_420MHZ +}; + +/* + * OV5670 sensor supports following resolutions with full FOV: + * 4:3 ==> {2592x1944, 1296x972, 648x486} + * 16:9 ==> {2560x1440, 1280x720, 640x360} + */ +static const struct ov5670_mode supported_modes[] = { + { + .width = 2592, + .height = 1944, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs), + .regs = mode_2592x1944_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + }, + { + .width = 1296, + .height = 972, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_1296x972_regs), + .regs = mode_1296x972_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + }, + { + .width = 648, + .height = 486, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_648x486_regs), + .regs = mode_648x486_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + }, + { + .width = 2560, + .height = 1440, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_2560x1440_regs), + .regs = mode_2560x1440_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + }, + { + .width = 1280, + .height = 720, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_1280x720_regs), + .regs = mode_1280x720_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + }, + { + .width = 640, + .height = 360, + .vts = OV5670_VTS_30FPS, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_640x360_regs), + .regs = mode_640x360_regs, + }, + .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + } +}; + +struct ov5670 { + struct v4l2_subdev sd; + struct media_pad pad; + + struct v4l2_ctrl_handler ctrl_handler; + /* V4L2 Controls */ + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *exposure; + + /* Current mode */ + const struct ov5670_mode *cur_mode; + + /* To serialize asynchronus callbacks */ + struct mutex mutex; + + /* Streaming on/off */ + bool streaming; +}; + +#define to_ov5670(_sd) container_of(_sd, struct ov5670, sd) + +/* Read registers up to 4 at a time */ +static int ov5670_read_reg(struct ov5670 *ov5670, u16 reg, unsigned int len, + u32 *val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + struct i2c_msg msgs[2]; + u8 *data_be_p; + u32 data_be = 0; + u16 reg_addr_be = cpu_to_be16(reg); + int ret; + + if (len > 4) + return -EINVAL; + + data_be_p = (u8 *)&data_be; + /* Write register address */ + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = 2; + msgs[0].buf = (u8 *)®_addr_be; + + /* Read data from register */ + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = &data_be_p[4 - len]; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + *val = be32_to_cpu(data_be); + + return 0; +} + +/* Write registers up to 4 at a time */ +static int ov5670_write_reg(struct ov5670 *ov5670, u16 reg, unsigned int len, + u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + int buf_i; + int val_i; + u8 buf[6]; + u8 *val_p; + + if (len > 4) + return -EINVAL; + + buf[0] = reg >> 8; + buf[1] = reg & 0xff; + + val = cpu_to_be32(val); + val_p = (u8 *)&val; + buf_i = 2; + val_i = 4 - len; + + while (val_i < 4) + buf[buf_i++] = val_p[val_i++]; + + if (i2c_master_send(client, buf, len + 2) != len + 2) + return -EIO; + + return 0; +} + +/* Write a list of registers */ +static int ov5670_write_regs(struct ov5670 *ov5670, + const struct ov5670_reg *regs, unsigned int len) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + unsigned int i; + int ret; + + for (i = 0; i < len; i++) { + ret = ov5670_write_reg(ov5670, regs[i].address, 1, regs[i].val); + if (ret) { + dev_err_ratelimited( + &client->dev, + "Failed to write reg 0x%4.4x. error = %d\n", + regs[i].address, ret); + + return ret; + } + } + + return 0; +} + +static int ov5670_write_reg_list(struct ov5670 *ov5670, + const struct ov5670_reg_list *r_list) +{ + return ov5670_write_regs(ov5670, r_list->regs, r_list->num_of_regs); +} + +/* Open sub-device */ +static int ov5670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct ov5670 *ov5670 = to_ov5670(sd); + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->pad, 0); + + mutex_lock(&ov5670->mutex); + + /* Initialize try_fmt */ + try_fmt->width = ov5670->cur_mode->width; + try_fmt->height = ov5670->cur_mode->height; + try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; + try_fmt->field = V4L2_FIELD_NONE; + + /* No crop or compose */ + mutex_unlock(&ov5670->mutex); + + return 0; +} + +static int ov5670_update_digital_gain(struct ov5670 *ov5670, u32 d_gain) +{ + int ret; + + ret = ov5670_write_reg(ov5670, OV5670_REG_R_DGTL_GAIN, + OV5670_REG_VALUE_16BIT, d_gain); + if (ret) + return ret; + + ret = ov5670_write_reg(ov5670, OV5670_REG_G_DGTL_GAIN, + OV5670_REG_VALUE_16BIT, d_gain); + if (ret) + return ret; + + return ov5670_write_reg(ov5670, OV5670_REG_B_DGTL_GAIN, + OV5670_REG_VALUE_16BIT, d_gain); +} + +static int ov5670_enable_test_pattern(struct ov5670 *ov5670, u32 pattern) +{ + u32 val; + int ret; + + /* Set the bayer order that we support */ + ret = ov5670_write_reg(ov5670, OV5670_REG_TEST_PATTERN_CTRL, + OV5670_REG_VALUE_08BIT, 0); + if (ret) + return ret; + + ret = ov5670_read_reg(ov5670, OV5670_REG_TEST_PATTERN, + OV5670_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + if (pattern) + val |= OV5670_TEST_PATTERN_ENABLE; + else + val &= ~OV5670_TEST_PATTERN_ENABLE; + + return ov5670_write_reg(ov5670, OV5670_REG_TEST_PATTERN, + OV5670_REG_VALUE_08BIT, val); +} + +/* Initialize control handlers */ +static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov5670 *ov5670 = container_of(ctrl->handler, + struct ov5670, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + s64 max; + int ret = 0; + + /* Propagate change of current control to all related controls */ + switch (ctrl->id) { + case V4L2_CID_VBLANK: + /* Update max exposure while meeting expected vblanking */ + max = ov5670->cur_mode->height + ctrl->val - 8; + __v4l2_ctrl_modify_range(ov5670->exposure, + ov5670->exposure->minimum, max, + ov5670->exposure->step, max); + break; + } + + /* V4L2 controls values will be applied only when power is already up */ + if (pm_runtime_get_if_in_use(&client->dev) <= 0) + return 0; + + switch (ctrl->id) { + case V4L2_CID_ANALOGUE_GAIN: + ret = ov5670_write_reg(ov5670, OV5670_REG_ANALOG_GAIN, + OV5670_REG_VALUE_16BIT, ctrl->val); + break; + case V4L2_CID_DIGITAL_GAIN: + ret = ov5670_update_digital_gain(ov5670, ctrl->val); + break; + case V4L2_CID_EXPOSURE: + /* 4 least significant bits of expsoure are fractional part */ + ret = ov5670_write_reg(ov5670, OV5670_REG_EXPOSURE, + OV5670_REG_VALUE_24BIT, ctrl->val << 4); + break; + case V4L2_CID_VBLANK: + /* Update VTS that meets expected vertical blanking */ + ret = ov5670_write_reg(ov5670, OV5670_REG_VTS, + OV5670_REG_VALUE_16BIT, + ov5670->cur_mode->height + ctrl->val); + break; + case V4L2_CID_HBLANK: + /* Update HTS that meets expected horizontal blanking */ + ret = ov5670_write_reg(ov5670, OV5670_REG_HTS, + OV5670_REG_VALUE_16BIT, + (ov5670->cur_mode->width + + ctrl->val) / 2); + break; + case V4L2_CID_TEST_PATTERN: + ret = ov5670_enable_test_pattern(ov5670, ctrl->val); + break; + default: + dev_info(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", + __func__, ctrl->id, ctrl->val); + break; + }; + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops ov5670_ctrl_ops = { + .s_ctrl = ov5670_set_ctrl, +}; + +/* Initialize control handlers */ +static int ov5670_init_controls(struct ov5670 *ov5670) +{ + struct v4l2_ctrl_handler *ctrl_hdlr; + s64 vblank_max; + s64 vblank_def; + s64 exposure_max; + int ret; + + ctrl_hdlr = &ov5670->ctrl_handler; + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); + if (ret) + return ret; + + ctrl_hdlr->lock = &ov5670->mutex; + ov5670->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, + &ov5670_ctrl_ops, + V4L2_CID_LINK_FREQ, + 0, 0, link_freq_menu_items); + if (ov5670->link_freq) + ov5670->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + /* By default, V4L2_CID_PIXEL_RATE is read only */ + ov5670->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, + V4L2_CID_PIXEL_RATE, 0, + link_freq_configs[0].pixel_rate, + 1, + link_freq_configs[0].pixel_rate); + + vblank_max = OV5670_VTS_MAX - ov5670->cur_mode->height; + vblank_def = ov5670->cur_mode->vts - ov5670->cur_mode->height; + ov5670->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, + V4L2_CID_VBLANK, OV5670_VBLANK_MIN, + vblank_max, 1, vblank_def); + + ov5670->hblank = v4l2_ctrl_new_std( + ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_HBLANK, + OV5670_DEF_PPL - ov5670->cur_mode->width, + OV5670_DEF_PPL - ov5670->cur_mode->width, 1, + OV5670_DEF_PPL - ov5670->cur_mode->width); + + /* Get min, max, step, default from sensor */ + v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + ANALOG_GAIN_MIN, ANALOG_GAIN_MAX, ANALOG_GAIN_STEP, + ANALOG_GAIN_DEFAULT); + + /* Digital gain */ + v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + OV5670_DGTL_GAIN_MIN, OV5670_DGTL_GAIN_MAX, + OV5670_DGTL_GAIN_STEP, OV5670_DGTL_GAIN_DEFAULT); + + /* Get min, max, step, default from sensor */ + exposure_max = ov5670->cur_mode->vts - 8; + ov5670->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, + V4L2_CID_EXPOSURE, + OV5670_EXPOSURE_MIN, + exposure_max, OV5670_EXPOSURE_STEP, + exposure_max); + + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5670_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(ov5670_test_pattern_menu) - 1, + 0, 0, ov5670_test_pattern_menu); + + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; + goto error; + } + + ov5670->sd.ctrl_handler = ctrl_hdlr; + + return 0; + +error: + v4l2_ctrl_handler_free(ctrl_hdlr); + + return ret; +} + +static int ov5670_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + /* Only one bayer order GRBG is supported */ + if (code->index > 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; + + return 0; +} + +static int ov5670_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = fse->min_width; + fse->min_height = supported_modes[fse->index].height; + fse->max_height = fse->min_height; + + return 0; +} + +/* Calculate resolution distance */ +static int ov5670_get_reso_dist(const struct ov5670_mode *mode, + struct v4l2_mbus_framefmt *framefmt) +{ + return abs(mode->width - framefmt->width) + + abs(mode->height - framefmt->height); +} + +/* Find the closest supported resolution to the requested resolution */ +static const struct ov5670_mode *ov5670_find_best_fit( + struct ov5670 *ov5670, + struct v4l2_subdev_format *fmt) +{ + struct v4l2_mbus_framefmt *framefmt = &fmt->format; + int dist; + int cur_best_fit = 0; + int cur_best_fit_dist = -1; + int i; + + for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { + dist = ov5670_get_reso_dist(&supported_modes[i], framefmt); + if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { + cur_best_fit_dist = dist; + cur_best_fit = i; + } + } + + return &supported_modes[cur_best_fit]; +} + +static void ov5670_update_pad_format(const struct ov5670_mode *mode, + struct v4l2_subdev_format *fmt) +{ + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; + fmt->format.field = V4L2_FIELD_NONE; +} + +static int ov5670_do_get_pad_format(struct ov5670 *ov5670, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + fmt->format = *v4l2_subdev_get_try_format(&ov5670->sd, cfg, + fmt->pad); + else + ov5670_update_pad_format(ov5670->cur_mode, fmt); + + return 0; +} + +static int ov5670_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ov5670 *ov5670 = to_ov5670(sd); + int ret; + + mutex_lock(&ov5670->mutex); + ret = ov5670_do_get_pad_format(ov5670, cfg, fmt); + mutex_unlock(&ov5670->mutex); + + return ret; +} + +static int ov5670_set_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ov5670 *ov5670 = to_ov5670(sd); + const struct ov5670_mode *mode; + s32 vblank_def; + s32 h_blank; + + mutex_lock(&ov5670->mutex); + + fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; + + mode = ov5670_find_best_fit(ov5670, fmt); + ov5670_update_pad_format(mode, fmt); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + } else { + ov5670->cur_mode = mode; + __v4l2_ctrl_s_ctrl(ov5670->link_freq, mode->link_freq_index); + __v4l2_ctrl_s_ctrl_int64( + ov5670->pixel_rate, + link_freq_configs[mode->link_freq_index].pixel_rate); + /* Update limits and set FPS to default */ + vblank_def = ov5670->cur_mode->vts - ov5670->cur_mode->height; + __v4l2_ctrl_modify_range( + ov5670->vblank, OV5670_VBLANK_MIN, + OV5670_VTS_MAX - ov5670->cur_mode->height, 1, + vblank_def); + __v4l2_ctrl_s_ctrl(ov5670->vblank, vblank_def); + h_blank = OV5670_DEF_PPL - ov5670->cur_mode->width; + __v4l2_ctrl_modify_range(ov5670->hblank, h_blank, h_blank, 1, + h_blank); + } + + mutex_unlock(&ov5670->mutex); + + return 0; +} + +static int ov5670_get_skip_frames(struct v4l2_subdev *sd, u32 *frames) +{ + *frames = OV5670_NUM_OF_SKIP_FRAMES; + + return 0; +} + +/* Prepare streaming by writing default values and customized values */ +static int ov5670_start_streaming(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + const struct ov5670_reg_list *reg_list; + int link_freq_index; + int ret; + + /* Get out of from software reset */ + ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST, + OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST); + if (ret) { + dev_err(&client->dev, "%s failed to set powerup registers\n", + __func__); + return ret; + } + + /* Setup PLL */ + link_freq_index = ov5670->cur_mode->link_freq_index; + reg_list = &link_freq_configs[link_freq_index].reg_list; + ret = ov5670_write_reg_list(ov5670, reg_list); + if (ret) { + dev_err(&client->dev, "%s failed to set plls\n", __func__); + return ret; + } + + /* Apply default values of current mode */ + reg_list = &ov5670->cur_mode->reg_list; + ret = ov5670_write_reg_list(ov5670, reg_list); + if (ret) { + dev_err(&client->dev, "%s failed to set mode\n", __func__); + return ret; + } + + ret = __v4l2_ctrl_handler_setup(ov5670->sd.ctrl_handler); + if (ret) + return ret; + + /* Write stream on list */ + ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT, + OV5670_REG_VALUE_08BIT, OV5670_MODE_STREAMING); + if (ret) { + dev_err(&client->dev, "%s failed to set stream\n", __func__); + return ret; + } + + ov5670->streaming = true; + + return 0; +} + +static int ov5670_stop_streaming(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + int ret; + + ret = ov5670_write_reg(ov5670, OV5670_REG_MODE_SELECT, + OV5670_REG_VALUE_08BIT, OV5670_MODE_STANDBY); + if (ret) + dev_err(&client->dev, "%s failed to set stream\n", __func__); + + ov5670->streaming = false; + + /* Return success even if it was an error, as there is nothing the + * caller can do about it. + */ + return 0; +} + +static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ov5670 *ov5670 = to_ov5670(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = 0; + + mutex_lock(&ov5670->mutex); + if (ov5670->streaming == enable) + goto unlock_and_return; + + if (enable) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + + ret = ov5670_start_streaming(ov5670); + if (ret) + goto error; + } else { + ret = ov5670_stop_streaming(ov5670); + pm_runtime_put(&client->dev); + } + goto unlock_and_return; + +error: + pm_runtime_put(&client->dev); + +unlock_and_return: + mutex_unlock(&ov5670->mutex); + + return ret; +} + +static int __maybe_unused ov5670_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5670 *ov5670 = to_ov5670(sd); + + if (ov5670->streaming) + ov5670_stop_streaming(ov5670); + + return 0; +} + +static int __maybe_unused ov5670_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5670 *ov5670 = to_ov5670(sd); + int ret; + + if (ov5670->streaming) { + ret = ov5670_start_streaming(ov5670); + if (ret) { + ov5670_stop_streaming(ov5670); + return ret; + } + } + + return 0; +} + +/* Verify chip ID */ +static int ov5670_identify_module(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + int ret; + u32 val; + + ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID, + OV5670_REG_VALUE_24BIT, &val); + if (ret) + return ret; + + if (val != OV5670_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + OV5670_CHIP_ID, val); + return -ENXIO; + } + + return 0; +} + +static const struct v4l2_subdev_video_ops ov5670_video_ops = { + .s_stream = ov5670_set_stream, +}; + +static const struct v4l2_subdev_pad_ops ov5670_pad_ops = { + .enum_mbus_code = ov5670_enum_mbus_code, + .get_fmt = ov5670_get_pad_format, + .set_fmt = ov5670_set_pad_format, + .enum_frame_size = ov5670_enum_frame_size, +}; + +static const struct v4l2_subdev_sensor_ops ov5670_sensor_ops = { + .g_skip_frames = ov5670_get_skip_frames, +}; + +static const struct v4l2_subdev_ops ov5670_subdev_ops = { + .video = &ov5670_video_ops, + .pad = &ov5670_pad_ops, + .sensor = &ov5670_sensor_ops, +}; + +static const struct media_entity_operations ov5670_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct v4l2_subdev_internal_ops ov5670_internal_ops = { + .open = ov5670_open, +}; + +static int ov5670_probe(struct i2c_client *client) +{ + struct ov5670 *ov5670; + const char *err_msg; + u32 input_clk = 0; + int ret; + + device_property_read_u32(&client->dev, "clock-frequency", &input_clk); + if (input_clk != 19200000) + return -EINVAL; + + ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL); + if (!ov5670) { + ret = -ENOMEM; + err_msg = "devm_kzalloc() error"; + goto error_print; + } + + /* Initialize subdev */ + v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops); + + /* Check module identity */ + ret = ov5670_identify_module(ov5670); + if (ret) { + err_msg = "ov5670_identify_module() error"; + goto error_print; + } + + mutex_init(&ov5670->mutex); + + /* Set default mode to max resolution */ + ov5670->cur_mode = &supported_modes[0]; + + ret = ov5670_init_controls(ov5670); + if (ret) { + err_msg = "ov5670_init_controls() error"; + goto error_mutex_destroy; + } + + ov5670->sd.internal_ops = &ov5670_internal_ops; + ov5670->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + ov5670->sd.entity.ops = &ov5670_subdev_entity_ops; + ov5670->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + + /* Source pad initialization */ + ov5670->pad.flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&ov5670->sd.entity, 1, &ov5670->pad); + if (ret) { + err_msg = "media_entity_pads_init() error"; + goto error_handler_free; + } + + /* Async register for subdev */ + ret = v4l2_async_register_subdev(&ov5670->sd); + if (ret < 0) { + err_msg = "v4l2_async_register_subdev() error"; + goto error_entity_cleanup; + } + + ov5670->streaming = false; + + /* + * Device is already turned on by i2c-core with ACPI domain PM. + * Enable runtime PM and turn off the device. + */ + pm_runtime_get_noresume(&client->dev); + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_put(&client->dev); + + return 0; + +error_entity_cleanup: + media_entity_cleanup(&ov5670->sd.entity); + +error_handler_free: + v4l2_ctrl_handler_free(ov5670->sd.ctrl_handler); + +error_mutex_destroy: + mutex_destroy(&ov5670->mutex); + +error_print: + dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret); + + return ret; +} + +static int ov5670_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5670 *ov5670 = to_ov5670(sd); + + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + v4l2_ctrl_handler_free(sd->ctrl_handler); + mutex_destroy(&ov5670->mutex); + + /* + * Disable runtime PM but keep the device turned on. + * i2c-core with ACPI domain PM will turn off the device. + */ + pm_runtime_get_sync(&client->dev); + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); + + return 0; +} + +static const struct dev_pm_ops ov5670_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ov5670_suspend, ov5670_resume) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id ov5670_acpi_ids[] = { + {"INT3479"}, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(acpi, ov5670_acpi_ids); +#endif + +static struct i2c_driver ov5670_i2c_driver = { + .driver = { + .name = "ov5670", + .pm = &ov5670_pm_ops, + .acpi_match_table = ACPI_PTR(ov5670_acpi_ids), + }, + .probe_new = ov5670_probe, + .remove = ov5670_remove, +}; + +module_i2c_driver(ov5670_i2c_driver); + +MODULE_AUTHOR("Rapolu, Chiranjeevi "); +MODULE_AUTHOR("Yang, Hyungwoo "); +MODULE_DESCRIPTION("Omnivision ov5670 sensor driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From dd69a3c1ded8fe477febd3e728e312d9a555695d Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 29 Jun 2017 19:32:50 -0400 Subject: media: staging: atomisp: Remove unnecessary return statement in void function Return statement at the end of a void function is useless. The Coccinelle semantic patch used to make this change is as follows: // @@ identifier f; expression e; @@ void f(...) { <... - return e; ...> } // Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c index 05eeff58a229..de0426b0a1a4 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c @@ -640,7 +640,7 @@ void hmm_vunmap(ia_css_ptr virt) return; } - return hmm_bo_vunmap(bo); + hmm_bo_vunmap(bo); } int hmm_pool_register(unsigned int pool_size, -- cgit v1.2.3 From 6da2fa86e564cd3a7c1ebadcb8d0367857e8c369 Mon Sep 17 00:00:00 2001 From: "Guillermo O. Freschi" Date: Tue, 4 Jul 2017 16:46:43 -0400 Subject: media: staging: atomisp: gc2235: fix sparse warning: missing static Several local use structs were missing declarations. Added static qualifier to clean up Sparse warning. Signed-off-by: Guillermo O. Freschi Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/gc2235.c | 2 +- drivers/staging/media/atomisp/i2c/gc2235.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/gc2235.c b/drivers/staging/media/atomisp/i2c/gc2235.c index 50f431729b6c..04e69dd5fdb1 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.c +++ b/drivers/staging/media/atomisp/i2c/gc2235.c @@ -480,7 +480,7 @@ static const struct v4l2_ctrl_ops ctrl_ops = { .g_volatile_ctrl = gc2235_g_volatile_ctrl }; -struct v4l2_ctrl_config gc2235_controls[] = { +static struct v4l2_ctrl_config gc2235_controls[] = { { .ops = &ctrl_ops, .id = V4L2_CID_EXPOSURE_ABSOLUTE, diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index ccbc757045a5..ae8f09dbe5c7 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h @@ -530,7 +530,7 @@ static struct gc2235_reg const gc2235_1616_1216_30fps[] = { { GC2235_TOK_TERM, 0, 0 } }; -struct gc2235_resolution gc2235_res_preview[] = { +static struct gc2235_resolution gc2235_res_preview[] = { { .desc = "gc2235_1600_900_30fps", @@ -582,7 +582,7 @@ struct gc2235_resolution gc2235_res_preview[] = { }; #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview)) -struct gc2235_resolution gc2235_res_still[] = { +static struct gc2235_resolution gc2235_res_still[] = { { .desc = "gc2235_1600_900_30fps", .width = 1600, @@ -632,7 +632,7 @@ struct gc2235_resolution gc2235_res_still[] = { }; #define N_RES_STILL (ARRAY_SIZE(gc2235_res_still)) -struct gc2235_resolution gc2235_res_video[] = { +static struct gc2235_resolution gc2235_res_video[] = { { .desc = "gc2235_1296_736_30fps", .width = 1296, -- cgit v1.2.3 From 14c23a5141b1ba5d1f042d51406681e83dc75fe0 Mon Sep 17 00:00:00 2001 From: Ivan Menshykov Date: Wed, 5 Jul 2017 06:07:45 -0400 Subject: media: staging: atomisp: i2c: ov5693: Fix style a coding style issue Fix checkpath errors Signed-off-by: Ivan Menshykov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov5693/ov5693.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c index d6447398f5ef..3483a50dae2a 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c @@ -146,7 +146,7 @@ static int ov5693_read_reg(struct i2c_client *client, return -EINVAL; } - memset(msg, 0 , sizeof(msg)); + memset(msg, 0, sizeof(msg)); msg[0].addr = client->addr; msg[0].flags = 0; @@ -702,7 +702,7 @@ static long ov5693_s_exposure(struct v4l2_subdev *sd, } static int ov5693_read_otp_reg_array(struct i2c_client *client, u16 size, - u16 addr, u8 * buf) + u16 addr, u8 *buf) { u16 index; int ret; @@ -720,7 +720,7 @@ static int ov5693_read_otp_reg_array(struct i2c_client *client, u16 size, return 0; } -static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 * buf) +static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5693_device *dev = to_ov5693_sensor(sd); -- cgit v1.2.3 From 366633d3e244e6b7fc2b504b09ad4dad6ac60ace Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 11:56:29 -0400 Subject: media: staging: atomisp: lm3554: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 5347 1920 24 7291 1c7b drivers/staging/media/atomisp/i2c/lm3554.o File size After adding 'const': text data bss dec hex filename 5411 1856 24 7291 1c7b drivers/staging/media/atomisp/i2c/lm3554.o Signed-off-by: Arvind Yadav Acked-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/lm3554.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/lm3554.c b/drivers/staging/media/atomisp/i2c/lm3554.c index 2b170c07aaba..679176f7c542 100644 --- a/drivers/staging/media/atomisp/i2c/lm3554.c +++ b/drivers/staging/media/atomisp/i2c/lm3554.c @@ -974,7 +974,7 @@ static const struct dev_pm_ops lm3554_pm_ops = { .resume = lm3554_resume, }; -static struct acpi_device_id lm3554_acpi_match[] = { +static const struct acpi_device_id lm3554_acpi_match[] = { { "INTCF1C" }, {}, }; -- cgit v1.2.3 From e2d92111034fcdb984fb375805622af87963434f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:07:08 -0400 Subject: media: staging: atomisp: ov2680: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 12466 3120 8 15594 3cea drivers/staging/media/atomisp/i2c/ov2680.o File size After adding 'const': text data bss dec hex filename 12530 3056 8 15594 3cea drivers/staging/media/atomisp/i2c/ov2680.o Signed-off-by: Arvind Yadav Acked-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov2680.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov2680.c b/drivers/staging/media/atomisp/i2c/ov2680.c index 3cabfe54c669..8daf81dfabb7 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.c +++ b/drivers/staging/media/atomisp/i2c/ov2680.c @@ -1517,7 +1517,7 @@ out_free: return ret; } -static struct acpi_device_id ov2680_acpi_match[] = { +static const struct acpi_device_id ov2680_acpi_match[] = { {"XXOV2680"}, {"OVTI2680"}, {}, -- cgit v1.2.3 From 09571dfdfeb43188471d0b1bd1202a18fc3db3e4 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:14:36 -0400 Subject: media: staging: atomisp: ov8858: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 23804 8448 0 32252 7dfc drivers/staging/media/atomisp/i2c/ov8858.o File size After adding 'const': text data bss dec hex filename 23868 8384 0 32252 7dfc drivers/staging/media/atomisp/i2c/ov8858.o Signed-off-by: Arvind Yadav Acked-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov8858.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov8858.c b/drivers/staging/media/atomisp/i2c/ov8858.c index 9574bc49113c..43e1638fd674 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858.c +++ b/drivers/staging/media/atomisp/i2c/ov8858.c @@ -2189,7 +2189,7 @@ static const struct i2c_device_id ov8858_id[] = { MODULE_DEVICE_TABLE(i2c, ov8858_id); -static struct acpi_device_id ov8858_acpi_match[] = { +static const struct acpi_device_id ov8858_acpi_match[] = { {"INT3477"}, {}, }; -- cgit v1.2.3 From 83371ef2de398b2d1a545bea22325936e1d39f2d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:20:56 -0400 Subject: media: staging: atomisp: gc0310: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 10297 1888 0 12185 2f99 drivers/staging/media/atomisp/i2c/gc0310.o File size After adding 'const': text data bss dec hex filename 10361 1824 0 12185 2f99 drivers/staging/media/atomisp/i2c/gc0310.o Signed-off-by: Arvind Yadav Acked-by: Alan Cox Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/gc0310.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/gc0310.c b/drivers/staging/media/atomisp/i2c/gc0310.c index 350fd7fd5b86..0c3caed595f0 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.c +++ b/drivers/staging/media/atomisp/i2c/gc0310.c @@ -1453,7 +1453,7 @@ out_free: return ret; } -static struct acpi_device_id gc0310_acpi_match[] = { +static const struct acpi_device_id gc0310_acpi_match[] = { {"XXGC0310"}, {"INT0310"}, {}, -- cgit v1.2.3 From 22461d77c87b9a387fe5513fa985fa4ffd80525d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:30:47 -0400 Subject: media: staging: atomisp: ov2722: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 14771 1880 0 16651 410b drivers/staging/media/atomisp/i2c/ov2722.o File size After adding 'const': text data bss dec hex filename 14835 1816 0 16651 410b drivers/staging/media/atomisp/i2c/ov2722.o Signed-off-by: Arvind Yadav Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov2722.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov2722.c b/drivers/staging/media/atomisp/i2c/ov2722.c index b7afadebdf89..10094ac56561 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.c +++ b/drivers/staging/media/atomisp/i2c/ov2722.c @@ -1337,7 +1337,7 @@ out_free: MODULE_DEVICE_TABLE(i2c, ov2722_id); -static struct acpi_device_id ov2722_acpi_match[] = { +static const struct acpi_device_id ov2722_acpi_match[] = { { "INT33FB" }, {}, }; -- cgit v1.2.3 From 02cc60ca0c7598c015d3e6b1bde6257c613299e1 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:36:36 -0400 Subject: media: staging: atomisp: ov5693: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 20729 3264 0 23993 5db9 drivers/staging/media/atomisp/i2c/ov5693/ov5693.o File size After adding 'const': text data bss dec hex filename 20793 3200 0 23993 5db9 drivers/staging/media/atomisp/i2c/ov5693/ov5693.o Signed-off-by: Arvind Yadav Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov5693/ov5693.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c index 3483a50dae2a..d9f278bcf926 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c @@ -2032,7 +2032,7 @@ out_free: MODULE_DEVICE_TABLE(i2c, ov5693_id); -static struct acpi_device_id ov5693_acpi_match[] = { +static const struct acpi_device_id ov5693_acpi_match[] = { {"INT33BE"}, {}, }; -- cgit v1.2.3 From 3f9ae4b978759d0af56fe89b2b82e1d827684675 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:40:45 -0400 Subject: media: staging: atomisp: mt9m114: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 15148 2640 8 17796 4584 drivers/staging/media/atomisp/i2c/mt9m114.o File size After adding 'const': text data bss dec hex filename 15244 2512 8 17764 4564 drivers/staging/media/atomisp/i2c/mt9m114.o Signed-off-by: Arvind Yadav Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/mt9m114.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.c b/drivers/staging/media/atomisp/i2c/mt9m114.c index 3fa915313e53..448e072ca037 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/mt9m114.c @@ -1928,7 +1928,7 @@ static int mt9m114_probe(struct i2c_client *client, MODULE_DEVICE_TABLE(i2c, mt9m114_id); -static struct acpi_device_id mt9m114_acpi_match[] = { +static const struct acpi_device_id mt9m114_acpi_match[] = { { "INT33F0" }, { "CRMT1040" }, {}, -- cgit v1.2.3 From e9e8c1cd18dcc047ad9b9d640fa5b198a096df90 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 6 Jul 2017 12:43:52 -0400 Subject: media: staging: atomisp: gc2235: constify acpi_device_id acpi_device_id are not supposed to change at runtime. All functions working with acpi_device_id provided by work with const acpi_device_id. So mark the non-const structs as const. File size before: text data bss dec hex filename 10754 1360 4 12118 2f56 drivers/staging/media/atomisp/i2c/gc2235.o File size After adding 'const': text data bss dec hex filename 10818 1296 4 12118 2f56 drivers/staging/media/atomisp/i2c/gc2235.o Signed-off-by: Arvind Yadav Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/gc2235.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/gc2235.c b/drivers/staging/media/atomisp/i2c/gc2235.c index 04e69dd5fdb1..e43d31ea9676 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.c +++ b/drivers/staging/media/atomisp/i2c/gc2235.c @@ -1183,7 +1183,7 @@ out_free: return ret; } -static struct acpi_device_id gc2235_acpi_match[] = { +static const struct acpi_device_id gc2235_acpi_match[] = { { "INT33F8" }, {}, }; -- cgit v1.2.3 From e19902225473529c8b84579930fe66156cd1f258 Mon Sep 17 00:00:00 2001 From: Hari Prasath Date: Mon, 10 Jul 2017 02:17:00 -0400 Subject: media: staging: atomisp: use kstrdup to replace kmalloc and memcpy kstrdup kernel primitive can be used to replace kmalloc followed by string copy. This was reported by coccinelle tool. Signed-off-by: Hari Prasath Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c index eecd8cf71951..63582161050a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c @@ -131,14 +131,10 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi, struct ia if (bi->type == ia_css_isp_firmware || bi->type == ia_css_sp_firmware) { char *namebuffer; - int namelength = (int)strlen(name); - namebuffer = (char *) kmalloc(namelength + 1, GFP_KERNEL); - if (namebuffer == NULL) + namebuffer = kstrdup(name, GFP_KERNEL); + if (!namebuffer) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; - - memcpy(namebuffer, name, namelength + 1); - bd->name = fw_minibuffer[index].name = namebuffer; } else { bd->name = name; -- cgit v1.2.3 From 05f1d92f2b68386a66086b08fc6257c1c143b7ac Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Mon, 10 Jul 2017 15:27:28 -0400 Subject: media: staging: atomisp: Use kvfree() instead of kfree()/vfree() Conditionally calling kfree()/vfree() can be replaced by a call to kvfree() which handles both kmalloced memory and vmalloced memory. The resulting wrapper function has been replaced with direct calls to kvfree(). This change was made with the help of the following Coccinelle semantic patch: // @@ expression a; @@ - if(...) { vfree(a); } - else { kfree(a); } + kvfree(a); // Signed-off-by: Amitoj Kaur Chawla Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp2/atomisp_cmd.c | 19 +++---------------- .../staging/media/atomisp/pci/atomisp2/atomisp_cmd.h | 1 - .../media/atomisp/pci/atomisp2/atomisp_compat_css20.c | 4 ++-- .../media/atomisp/pci/atomisp2/atomisp_internal.h | 2 -- 4 files changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c index 97093baf28ac..7bf5dcd3a2d1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c @@ -111,19 +111,6 @@ void *atomisp_kernel_zalloc(size_t bytes, bool zero_mem) return ptr; } -/* - * Free buffer allocated with atomisp_kernel_malloc()/atomisp_kernel_zalloc - * helper - */ -void atomisp_kernel_free(void *ptr) -{ - /* Verify if buffer was allocated by vmalloc() or kmalloc() */ - if (is_vmalloc_addr(ptr)) - vfree(ptr); - else - kfree(ptr); -} - /* * get sensor:dis71430/ov2720 related info from v4l2_subdev->priv data field. * subdev->priv is set in mrst.c @@ -785,7 +772,7 @@ void atomisp_flush_params_queue(struct atomisp_video_pipe *pipe) struct atomisp_css_params_with_list, list); list_del(¶m->list); atomisp_free_css_parameters(¶m->params); - atomisp_kernel_free(param); + kvfree(param); } } @@ -1132,7 +1119,7 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, asd->params.dvs_6axis = NULL; atomisp_free_css_parameters( &pipe->frame_params[vb->i]->params); - atomisp_kernel_free(pipe->frame_params[vb->i]); + kvfree(pipe->frame_params[vb->i]); pipe->frame_params[vb->i] = NULL; } @@ -4375,7 +4362,7 @@ apply_parameter_failed: if (css_param) atomisp_free_css_parameters(css_param); if (param) - atomisp_kernel_free(param); + kvfree(param); return ret; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h index 8e6d9df7ad1a..1ccd91172f98 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h @@ -80,7 +80,6 @@ static inline void __iomem *atomisp_get_io_virt_addr(unsigned int address) */ void *atomisp_kernel_malloc(size_t bytes); void *atomisp_kernel_zalloc(size_t bytes, bool zero_mem); -void atomisp_kernel_free(void *ptr); /* * Interrupt functions diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c index ad2c610d2ce3..36f934d95651 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c @@ -1676,7 +1676,7 @@ int atomisp_alloc_metadata_output_buf(struct atomisp_sub_device *asd) stream_info.metadata_info.size); if (!asd->params.metadata_user[i]) { while (--i >= 0) { - atomisp_kernel_free(asd->params.metadata_user[i]); + kvfree(asd->params.metadata_user[i]); asd->params.metadata_user[i] = NULL; } return -ENOMEM; @@ -1692,7 +1692,7 @@ void atomisp_free_metadata_output_buf(struct atomisp_sub_device *asd) for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { if (asd->params.metadata_user[i]) { - atomisp_kernel_free(asd->params.metadata_user[i]); + kvfree(asd->params.metadata_user[i]); asd->params.metadata_user[i] = NULL; } } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h index d3667132851b..afced4f4eb6a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h @@ -312,8 +312,6 @@ extern struct device *atomisp_dev; extern void *atomisp_kernel_malloc(size_t bytes); -extern void atomisp_kernel_free(void *ptr); - #define atomisp_is_wdt_running(a) timer_pending(&(a)->wdt) #ifdef ISP2401 extern void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe, -- cgit v1.2.3 From cd31dae7e604621c3921699c930bb6f5e6bedb5d Mon Sep 17 00:00:00 2001 From: Philipp Guendisch Date: Thu, 13 Jul 2017 02:55:42 -0400 Subject: media: staging: atomisp: hmm: Fixed comment style This patch fixed comment style. Semantic should not be affected. There are also two warnings left about too long lines, which reduce readability if changed. Signed-off-by: Philipp Guendisch Signed-off-by: Chris Baller Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp2/hmm/hmm.c | 44 +++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c index de0426b0a1a4..b345025f3e37 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c @@ -46,10 +46,12 @@ static ia_css_ptr dummy_ptr; static bool hmm_initialized; struct _hmm_mem_stat hmm_mem_stat; -/* p: private - s: shared - u: user - i: ion */ +/* + * p: private + * s: shared + * u: user + * i: ion + */ static const char hmm_bo_type_string[] = "psui"; static ssize_t bo_show(struct device *dev, struct device_attribute *attr, @@ -213,9 +215,7 @@ void hmm_cleanup(void) { sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group); - /* - * free dummy memory first - */ + /* free dummy memory first */ hmm_free(dummy_ptr); dummy_ptr = 0; @@ -230,22 +230,24 @@ ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type, struct hmm_buffer_object *bo; int ret; - /* Check if we are initialized. In the ideal world we wouldn't need - this but we can tackle it once the driver is a lot cleaner */ + /* + * Check if we are initialized. In the ideal world we wouldn't need + * this but we can tackle it once the driver is a lot cleaner + */ if (!hmm_initialized) hmm_init(); - /*Get page number from size*/ + /* Get page number from size */ pgnr = size_to_pgnr_ceil(bytes); - /*Buffer object structure init*/ + /* Buffer object structure init */ bo = hmm_bo_alloc(&bo_device, pgnr); if (!bo) { dev_err(atomisp_dev, "hmm_bo_create failed.\n"); goto create_bo_err; } - /*Allocate pages for memory*/ + /* Allocate pages for memory */ ret = hmm_bo_alloc_pages(bo, type, from_highmem, userptr, cached); if (ret) { dev_err(atomisp_dev, @@ -253,7 +255,7 @@ ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type, goto alloc_page_err; } - /*Combind the virtual address and pages togather*/ + /* Combind the virtual address and pages togather */ ret = hmm_bo_bind(bo); if (ret) { dev_err(atomisp_dev, "hmm_bo_bind failed.\n"); @@ -319,7 +321,7 @@ static inline int hmm_check_bo(struct hmm_buffer_object *bo, unsigned int ptr) return 0; } -/*Read function in ISP memory management*/ +/* Read function in ISP memory management */ static int load_and_flush_by_kmap(ia_css_ptr virt, void *data, unsigned int bytes) { struct hmm_buffer_object *bo; @@ -362,7 +364,7 @@ static int load_and_flush_by_kmap(ia_css_ptr virt, void *data, unsigned int byte return 0; } -/*Read function in ISP memory management*/ +/* Read function in ISP memory management */ static int load_and_flush(ia_css_ptr virt, void *data, unsigned int bytes) { struct hmm_buffer_object *bo; @@ -397,7 +399,7 @@ static int load_and_flush(ia_css_ptr virt, void *data, unsigned int bytes) return 0; } -/*Read function in ISP memory management*/ +/* Read function in ISP memory management */ int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes) { if (!data) { @@ -408,13 +410,13 @@ int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes) return load_and_flush(virt, data, bytes); } -/*Flush hmm data from the data cache*/ +/* Flush hmm data from the data cache */ int hmm_flush(ia_css_ptr virt, unsigned int bytes) { return load_and_flush(virt, NULL, bytes); } -/*Write function in ISP memory management*/ +/* Write function in ISP memory management */ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes) { struct hmm_buffer_object *bo; @@ -496,7 +498,7 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes) return 0; } -/*memset function in ISP memory management*/ +/* memset function in ISP memory management */ int hmm_set(ia_css_ptr virt, int c, unsigned int bytes) { struct hmm_buffer_object *bo; @@ -556,7 +558,7 @@ int hmm_set(ia_css_ptr virt, int c, unsigned int bytes) return 0; } -/*Virtual address to physical address convert*/ +/* Virtual address to physical address convert */ phys_addr_t hmm_virt_to_phys(ia_css_ptr virt) { unsigned int idx, offset; @@ -591,7 +593,7 @@ int hmm_mmap(struct vm_area_struct *vma, ia_css_ptr virt) return hmm_bo_mmap(vma, bo); } -/*Map ISP virtual address into IA virtual address*/ +/* Map ISP virtual address into IA virtual address */ void *hmm_vmap(ia_css_ptr virt, bool cached) { struct hmm_buffer_object *bo; -- cgit v1.2.3 From 8d21af813fe3c03e58845cdf0b8b2d4e781c42bc Mon Sep 17 00:00:00 2001 From: Philipp Guendisch Date: Thu, 13 Jul 2017 02:55:43 -0400 Subject: media: staging: atomisp: hmm: Alignment code (rebased) This patch fixed code alignment to open paranthesis. Semantic should not be affected by this patch. It has been rebased on top of media_tree atomisp branch Signed-off-by: Philipp Guendisch Signed-off-by: Chris Baller Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp2/hmm/hmm.c | 93 +++++++++++----------- 1 file changed, 45 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c index b345025f3e37..b8aae4ba5a78 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c @@ -55,7 +55,7 @@ struct _hmm_mem_stat hmm_mem_stat; static const char hmm_bo_type_string[] = "psui"; static ssize_t bo_show(struct device *dev, struct device_attribute *attr, - char *buf, struct list_head *bo_list, bool active) + char *buf, struct list_head *bo_list, bool active) { ssize_t ret = 0; struct hmm_buffer_object *bo; @@ -75,10 +75,10 @@ static ssize_t bo_show(struct device *dev, struct device_attribute *attr, spin_lock_irqsave(&bo_device.list_lock, flags); list_for_each_entry(bo, bo_list, list) { if ((active && (bo->status & HMM_BO_ALLOCED)) || - (!active && !(bo->status & HMM_BO_ALLOCED))) { + (!active && !(bo->status & HMM_BO_ALLOCED))) { ret = scnprintf(buf + index1, PAGE_SIZE - index1, - "%c %d\n", - hmm_bo_type_string[bo->type], bo->pgnr); + "%c %d\n", + hmm_bo_type_string[bo->type], bo->pgnr); total[bo->type] += bo->pgnr; count[bo->type]++; @@ -91,9 +91,10 @@ static ssize_t bo_show(struct device *dev, struct device_attribute *attr, for (i = 0; i < HMM_BO_LAST; i++) { if (count[i]) { ret = scnprintf(buf + index1 + index2, - PAGE_SIZE - index1 - index2, - "%ld %c buffer objects: %ld KB\n", - count[i], hmm_bo_type_string[i], total[i] * 4); + PAGE_SIZE - index1 - index2, + "%ld %c buffer objects: %ld KB\n", + count[i], hmm_bo_type_string[i], + total[i] * 4); if (ret > 0) index2 += ret; } @@ -103,23 +104,21 @@ static ssize_t bo_show(struct device *dev, struct device_attribute *attr, return index1 + index2 + 1; } -static ssize_t active_bo_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t active_bo_show(struct device *dev, struct device_attribute *attr, + char *buf) { return bo_show(dev, attr, buf, &bo_device.entire_bo_list, true); } -static ssize_t free_bo_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t free_bo_show(struct device *dev, struct device_attribute *attr, + char *buf) { return bo_show(dev, attr, buf, &bo_device.entire_bo_list, false); } static ssize_t reserved_pool_show(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { ssize_t ret = 0; @@ -131,7 +130,7 @@ static ssize_t reserved_pool_show(struct device *dev, spin_lock_irqsave(&pinfo->list_lock, flags); ret = scnprintf(buf, PAGE_SIZE, "%d out of %d pages available\n", - pinfo->index, pinfo->pgnr); + pinfo->index, pinfo->pgnr); spin_unlock_irqrestore(&pinfo->list_lock, flags); if (ret > 0) @@ -141,8 +140,8 @@ static ssize_t reserved_pool_show(struct device *dev, }; static ssize_t dynamic_pool_show(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { ssize_t ret = 0; @@ -154,7 +153,7 @@ static ssize_t dynamic_pool_show(struct device *dev, spin_lock_irqsave(&pinfo->list_lock, flags); ret = scnprintf(buf, PAGE_SIZE, "%d (max %d) pages available\n", - pinfo->pgnr, pinfo->pool_size); + pinfo->pgnr, pinfo->pool_size); spin_unlock_irqrestore(&pinfo->list_lock, flags); if (ret > 0) @@ -202,7 +201,7 @@ int hmm_init(void) if (!ret) { ret = sysfs_create_group(&atomisp_dev->kobj, - atomisp_attribute_group); + atomisp_attribute_group); if (ret) dev_err(atomisp_dev, "%s Failed to create sysfs\n", __func__); @@ -224,7 +223,7 @@ void hmm_cleanup(void) } ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type, - int from_highmem, void *userptr, bool cached) + int from_highmem, void *userptr, bool cached) { unsigned int pgnr; struct hmm_buffer_object *bo; @@ -250,8 +249,7 @@ ia_css_ptr hmm_alloc(size_t bytes, enum hmm_bo_type type, /* Allocate pages for memory */ ret = hmm_bo_alloc_pages(bo, type, from_highmem, userptr, cached); if (ret) { - dev_err(atomisp_dev, - "hmm_bo_alloc_pages failed.\n"); + dev_err(atomisp_dev, "hmm_bo_alloc_pages failed.\n"); goto alloc_page_err; } @@ -284,8 +282,8 @@ void hmm_free(ia_css_ptr virt) if (!bo) { dev_err(atomisp_dev, - "can not find buffer object start with " - "address 0x%x\n", (unsigned int)virt); + "can not find buffer object start with address 0x%x\n", + (unsigned int)virt); return; } @@ -300,21 +298,20 @@ static inline int hmm_check_bo(struct hmm_buffer_object *bo, unsigned int ptr) { if (!bo) { dev_err(atomisp_dev, - "can not find buffer object contains " - "address 0x%x\n", ptr); + "can not find buffer object contains address 0x%x\n", + ptr); return -EINVAL; } if (!hmm_bo_page_allocated(bo)) { dev_err(atomisp_dev, - "buffer object has no page allocated.\n"); + "buffer object has no page allocated.\n"); return -EINVAL; } if (!hmm_bo_allocated(bo)) { dev_err(atomisp_dev, - "buffer object has no virtual address" - " space allocated.\n"); + "buffer object has no virtual address space allocated.\n"); return -EINVAL; } @@ -322,7 +319,8 @@ static inline int hmm_check_bo(struct hmm_buffer_object *bo, unsigned int ptr) } /* Read function in ISP memory management */ -static int load_and_flush_by_kmap(ia_css_ptr virt, void *data, unsigned int bytes) +static int load_and_flush_by_kmap(ia_css_ptr virt, void *data, + unsigned int bytes) { struct hmm_buffer_object *bo; unsigned int idx, offset, len; @@ -404,7 +402,7 @@ int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes) { if (!data) { dev_err(atomisp_dev, - "hmm_load NULL argument\n"); + "hmm_load NULL argument\n"); return -EINVAL; } return load_and_flush(virt, data, bytes); @@ -462,8 +460,8 @@ int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes) if (!des) { dev_err(atomisp_dev, - "kmap buffer object page failed: " - "pg_idx = %d\n", idx); + "kmap buffer object page failed: pg_idx = %d\n", + idx); return -EINVAL; } @@ -602,8 +600,8 @@ void *hmm_vmap(ia_css_ptr virt, bool cached) bo = hmm_bo_device_search_in_range(&bo_device, virt); if (!bo) { dev_err(atomisp_dev, - "can not find buffer object contains address 0x%x\n", - virt); + "can not find buffer object contains address 0x%x\n", + virt); return NULL; } @@ -622,8 +620,8 @@ void hmm_flush_vmap(ia_css_ptr virt) bo = hmm_bo_device_search_in_range(&bo_device, virt); if (!bo) { dev_warn(atomisp_dev, - "can not find buffer object contains address 0x%x\n", - virt); + "can not find buffer object contains address 0x%x\n", + virt); return; } @@ -637,26 +635,25 @@ void hmm_vunmap(ia_css_ptr virt) bo = hmm_bo_device_search_in_range(&bo_device, virt); if (!bo) { dev_warn(atomisp_dev, - "can not find buffer object contains address 0x%x\n", - virt); + "can not find buffer object contains address 0x%x\n", + virt); return; } hmm_bo_vunmap(bo); } -int hmm_pool_register(unsigned int pool_size, - enum hmm_pool_type pool_type) +int hmm_pool_register(unsigned int pool_size, enum hmm_pool_type pool_type) { switch (pool_type) { case HMM_POOL_TYPE_RESERVED: reserved_pool.pops = &reserved_pops; return reserved_pool.pops->pool_init(&reserved_pool.pool_info, - pool_size); + pool_size); case HMM_POOL_TYPE_DYNAMIC: dynamic_pool.pops = &dynamic_pops; return dynamic_pool.pops->pool_init(&dynamic_pool.pool_info, - pool_size); + pool_size); default: dev_err(atomisp_dev, "invalid pool type.\n"); return -EINVAL; @@ -705,10 +702,10 @@ ia_css_ptr hmm_host_vaddr_to_hrt_vaddr(const void *ptr) void hmm_show_mem_stat(const char *func, const int line) { trace_printk("tol_cnt=%d usr_size=%d res_size=%d res_cnt=%d sys_size=%d dyc_thr=%d dyc_size=%d.\n", - hmm_mem_stat.tol_cnt, - hmm_mem_stat.usr_size, hmm_mem_stat.res_size, - hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size, - hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size); + hmm_mem_stat.tol_cnt, + hmm_mem_stat.usr_size, hmm_mem_stat.res_size, + hmm_mem_stat.res_cnt, hmm_mem_stat.sys_size, + hmm_mem_stat.dyc_thr, hmm_mem_stat.dyc_size); } void hmm_init_mem_stat(int res_pgnr, int dyc_en, int dyc_pgnr) -- cgit v1.2.3 From 54d71c26e319cceee99c302caad6f45ec0c9a587 Mon Sep 17 00:00:00 2001 From: Shy More Date: Sun, 16 Jul 2017 19:35:34 -0400 Subject: media: staging: atomisp: fixed trivial coding style warning Below was the trivial wanrning flagged by checkpatch.pl WARNING: Block comments use * on subsequent lines Signed-off-by: Shy More Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../css2400/runtime/isys/src/ibuf_ctrl_rmgr.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c index 76d9142fd37e..bb9f5cd6b2af 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c @@ -14,18 +14,18 @@ */ #else /** -Support for Intel Camera Imaging ISP subsystem. -Copyright (c) 2010 - 2015, Intel Corporation. - -This program is free software; you can redistribute it and/or modify it -under the terms and conditions of the GNU General Public License, -version 2, as published by the Free Software Foundation. - -This program is distributed in the hope it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. -*/ + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ #endif #include "system_global.h" -- cgit v1.2.3 From 6d78cf7a60fd39fff6d07075adc28b5748607ab0 Mon Sep 17 00:00:00 2001 From: Shy More Date: Mon, 17 Jul 2017 00:10:57 -0400 Subject: media: staging: atomisp: fixed trivial coding style issue Below was the trival error flagged by checkpatch.pl: ERROR: space prohibited after that open parenthesis '(' Signed-off-by: Shy More Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c index bb9f5cd6b2af..faef97672eac 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isys/src/ibuf_ctrl_rmgr.c @@ -130,8 +130,7 @@ void ia_css_isys_ibuf_rmgr_release( for (i = 0; i < ibuf_rsrc.num_allocated; i++) { handle = getHandle(i); - if ((handle->start_addr == *start_addr) - && ( true == handle->active)) { + if (handle->active && handle->start_addr == *start_addr) { handle->active = false; ibuf_rsrc.num_active--; break; -- cgit v1.2.3 From 3e89586a64dfd2860d596db0c84ec999d2eb5591 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Thu, 6 Jul 2017 07:01:16 -0400 Subject: media: i2c: adv748x: add adv748x driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide support for the ADV7481 and ADV7482. The driver is modelled with 4 subdevices to allow simultaneous streaming from the AFE (Analog front end) and HDMI inputs though two CSI TX entities. The HDMI entity is linked to the TXA CSI bus, whilst the AFE is linked to the TXB CSI bus. The driver is based on a prototype by Koji Matsuoka in the Renesas BSP, and an earlier rework by Niklas Söderlund. Signed-off-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/adv748x/Makefile | 7 + drivers/media/i2c/adv748x/adv748x-afe.c | 552 ++++++++++++++++++++ drivers/media/i2c/adv748x/adv748x-core.c | 832 +++++++++++++++++++++++++++++++ drivers/media/i2c/adv748x/adv748x-csi2.c | 327 ++++++++++++ drivers/media/i2c/adv748x/adv748x-hdmi.c | 768 ++++++++++++++++++++++++++++ drivers/media/i2c/adv748x/adv748x.h | 425 ++++++++++++++++ 8 files changed, 2924 insertions(+) create mode 100644 drivers/media/i2c/adv748x/Makefile create mode 100644 drivers/media/i2c/adv748x/adv748x-afe.c create mode 100644 drivers/media/i2c/adv748x/adv748x-core.c create mode 100644 drivers/media/i2c/adv748x/adv748x-csi2.c create mode 100644 drivers/media/i2c/adv748x/adv748x-hdmi.c create mode 100644 drivers/media/i2c/adv748x/adv748x.h (limited to 'drivers') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index b64c4ebd65eb..a05e40ecba7c 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -204,6 +204,18 @@ config VIDEO_ADV7183 To compile this driver as a module, choose M here: the module will be called adv7183. +config VIDEO_ADV748X + tristate "Analog Devices ADV748x decoder" + depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + depends on OF + select REGMAP_I2C + ---help--- + V4L2 subdevice driver for the Analog Devices + ADV7481 and ADV7482 HDMI/Analog video decoders. + + To compile this driver as a module, choose M here: the + module will be called adv748x. + config VIDEO_ADV7604 tristate "Analog Devices ADV7604 decoder" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 84673c79e01a..c843c181dfb9 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o +obj-$(CONFIG_VIDEO_ADV748X) += adv748x/ obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o diff --git a/drivers/media/i2c/adv748x/Makefile b/drivers/media/i2c/adv748x/Makefile new file mode 100644 index 000000000000..c0711e076f1d --- /dev/null +++ b/drivers/media/i2c/adv748x/Makefile @@ -0,0 +1,7 @@ +adv748x-objs := \ + adv748x-afe.o \ + adv748x-core.o \ + adv748x-csi2.o \ + adv748x-hdmi.o + +obj-$(CONFIG_VIDEO_ADV748X) += adv748x.o diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c new file mode 100644 index 000000000000..b33ccfc08708 --- /dev/null +++ b/drivers/media/i2c/adv748x/adv748x-afe.c @@ -0,0 +1,552 @@ +/* + * Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver + * with standard definition processor (SDP) + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "adv748x.h" + +/* ----------------------------------------------------------------------------- + * SDP + */ + +#define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM 0x0 +#define ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM_PED 0x1 +#define ADV748X_AFE_STD_AD_PAL_N_NTSC_J_SECAM 0x2 +#define ADV748X_AFE_STD_AD_PAL_N_NTSC_M_SECAM 0x3 +#define ADV748X_AFE_STD_NTSC_J 0x4 +#define ADV748X_AFE_STD_NTSC_M 0x5 +#define ADV748X_AFE_STD_PAL60 0x6 +#define ADV748X_AFE_STD_NTSC_443 0x7 +#define ADV748X_AFE_STD_PAL_BG 0x8 +#define ADV748X_AFE_STD_PAL_N 0x9 +#define ADV748X_AFE_STD_PAL_M 0xa +#define ADV748X_AFE_STD_PAL_M_PED 0xb +#define ADV748X_AFE_STD_PAL_COMB_N 0xc +#define ADV748X_AFE_STD_PAL_COMB_N_PED 0xd +#define ADV748X_AFE_STD_PAL_SECAM 0xe +#define ADV748X_AFE_STD_PAL_SECAM_PED 0xf + +static int adv748x_afe_read_ro_map(struct adv748x_state *state, u8 reg) +{ + int ret; + + /* Select SDP Read-Only Main Map */ + ret = sdp_write(state, ADV748X_SDP_MAP_SEL, + ADV748X_SDP_MAP_SEL_RO_MAIN); + if (ret < 0) + return ret; + + return sdp_read(state, reg); +} + +static int adv748x_afe_status(struct adv748x_afe *afe, u32 *signal, + v4l2_std_id *std) +{ + struct adv748x_state *state = adv748x_afe_to_state(afe); + int info; + + /* Read status from reg 0x10 of SDP RO Map */ + info = adv748x_afe_read_ro_map(state, ADV748X_SDP_RO_10); + if (info < 0) + return info; + + if (signal) + *signal = info & ADV748X_SDP_RO_10_IN_LOCK ? + 0 : V4L2_IN_ST_NO_SIGNAL; + + if (!std) + return 0; + + /* Standard not valid if there is no signal */ + if (!(info & ADV748X_SDP_RO_10_IN_LOCK)) { + *std = V4L2_STD_UNKNOWN; + return 0; + } + + switch (info & 0x70) { + case 0x00: + *std = V4L2_STD_NTSC; + break; + case 0x10: + *std = V4L2_STD_NTSC_443; + break; + case 0x20: + *std = V4L2_STD_PAL_M; + break; + case 0x30: + *std = V4L2_STD_PAL_60; + break; + case 0x40: + *std = V4L2_STD_PAL; + break; + case 0x50: + *std = V4L2_STD_SECAM; + break; + case 0x60: + *std = V4L2_STD_PAL_Nc | V4L2_STD_PAL_N; + break; + case 0x70: + *std = V4L2_STD_SECAM; + break; + default: + *std = V4L2_STD_UNKNOWN; + break; + } + + return 0; +} + +static void adv748x_afe_fill_format(struct adv748x_afe *afe, + struct v4l2_mbus_framefmt *fmt) +{ + memset(fmt, 0, sizeof(*fmt)); + + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->field = V4L2_FIELD_ALTERNATE; + + fmt->width = 720; + fmt->height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576; + + /* Field height */ + fmt->height /= 2; +} + +static int adv748x_afe_std(v4l2_std_id std) +{ + if (std == V4L2_STD_PAL_60) + return ADV748X_AFE_STD_PAL60; + if (std == V4L2_STD_NTSC_443) + return ADV748X_AFE_STD_NTSC_443; + if (std == V4L2_STD_PAL_N) + return ADV748X_AFE_STD_PAL_N; + if (std == V4L2_STD_PAL_M) + return ADV748X_AFE_STD_PAL_M; + if (std == V4L2_STD_PAL_Nc) + return ADV748X_AFE_STD_PAL_COMB_N; + if (std & V4L2_STD_NTSC) + return ADV748X_AFE_STD_NTSC_M; + if (std & V4L2_STD_PAL) + return ADV748X_AFE_STD_PAL_BG; + if (std & V4L2_STD_SECAM) + return ADV748X_AFE_STD_PAL_SECAM; + + return -EINVAL; +} + +static void adv748x_afe_set_video_standard(struct adv748x_state *state, + int sdpstd) +{ + sdp_clrset(state, ADV748X_SDP_VID_SEL, ADV748X_SDP_VID_SEL_MASK, + (sdpstd & 0xf) << ADV748X_SDP_VID_SEL_SHIFT); +} + +static int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input) +{ + struct adv748x_state *state = adv748x_afe_to_state(afe); + + return sdp_write(state, ADV748X_SDP_INSEL, input); +} + +static int adv748x_afe_g_pixelaspect(struct v4l2_subdev *sd, + struct v4l2_fract *aspect) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + + if (afe->curr_norm & V4L2_STD_525_60) { + aspect->numerator = 11; + aspect->denominator = 10; + } else { + aspect->numerator = 54; + aspect->denominator = 59; + } + + return 0; +} + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_video_ops + */ + +static int adv748x_afe_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + + *norm = afe->curr_norm; + + return 0; +} + +static int adv748x_afe_s_std(struct v4l2_subdev *sd, v4l2_std_id std) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + struct adv748x_state *state = adv748x_afe_to_state(afe); + int afe_std = adv748x_afe_std(std); + + if (afe_std < 0) + return afe_std; + + mutex_lock(&state->mutex); + + adv748x_afe_set_video_standard(state, afe_std); + afe->curr_norm = std; + + mutex_unlock(&state->mutex); + + return 0; +} + +static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + struct adv748x_state *state = adv748x_afe_to_state(afe); + int ret; + + mutex_lock(&state->mutex); + + if (afe->streaming) { + ret = -EBUSY; + goto unlock; + } + + /* Set auto detect mode */ + adv748x_afe_set_video_standard(state, + ADV748X_AFE_STD_AD_PAL_BG_NTSC_J_SECAM); + + msleep(100); + + /* Read detected standard */ + ret = adv748x_afe_status(afe, NULL, std); + + /* Restore original state */ + adv748x_afe_set_video_standard(state, afe->curr_norm); + +unlock: + mutex_unlock(&state->mutex); + + return ret; +} + +static int adv748x_afe_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) +{ + *norm = V4L2_STD_ALL; + + return 0; +} + +static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + struct adv748x_state *state = adv748x_afe_to_state(afe); + int ret; + + mutex_lock(&state->mutex); + + ret = adv748x_afe_status(afe, status, NULL); + + mutex_unlock(&state->mutex); + return ret; +} + +static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + struct adv748x_state *state = adv748x_afe_to_state(afe); + int ret, signal = V4L2_IN_ST_NO_SIGNAL; + + mutex_lock(&state->mutex); + + if (enable) { + ret = adv748x_afe_s_input(afe, afe->input); + if (ret) + goto unlock; + } + + ret = adv748x_txb_power(state, enable); + if (ret) + goto unlock; + + afe->streaming = enable; + + adv748x_afe_status(afe, &signal, NULL); + if (signal != V4L2_IN_ST_NO_SIGNAL) + adv_dbg(state, "Detected SDP signal\n"); + else + adv_dbg(state, "Couldn't detect SDP video signal\n"); + +unlock: + mutex_unlock(&state->mutex); + + return ret; +} + +static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = { + .g_std = adv748x_afe_g_std, + .s_std = adv748x_afe_s_std, + .querystd = adv748x_afe_querystd, + .g_tvnorms = adv748x_afe_g_tvnorms, + .g_input_status = adv748x_afe_g_input_status, + .s_stream = adv748x_afe_s_stream, + .g_pixelaspect = adv748x_afe_g_pixelaspect, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_pad_ops + */ + +static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe) +{ + struct v4l2_subdev *tx; + unsigned int width, height, fps; + + tx = adv748x_get_remote_sd(&afe->pads[ADV748X_AFE_SOURCE]); + if (!tx) + return -ENOLINK; + + width = 720; + height = afe->curr_norm & V4L2_STD_525_60 ? 480 : 576; + fps = afe->curr_norm & V4L2_STD_525_60 ? 30 : 25; + + return adv748x_csi2_set_pixelrate(tx, width * height * fps); +} + +static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index != 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_UYVY8_2X8; + + return 0; +} + +static int adv748x_afe_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct adv748x_afe *afe = adv748x_sd_to_afe(sd); + struct v4l2_mbus_framefmt *mbusformat; + + /* It makes no sense to get the format of the analog sink pads */ + if (sdformat->pad != ADV748X_AFE_SOURCE) + return -EINVAL; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { + mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + sdformat->format = *mbusformat; + } else { + adv748x_afe_fill_format(afe, &sdformat->format); + adv748x_afe_propagate_pixelrate(afe); + } + + return 0; +} + +static int adv748x_afe_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct v4l2_mbus_framefmt *mbusformat; + + /* It makes no sense to get the format of the analog sink pads */ + if (sdformat->pad != ADV748X_AFE_SOURCE) + return -EINVAL; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return adv748x_afe_get_format(sd, cfg, sdformat); + + mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + *mbusformat = sdformat->format; + + return 0; +} + +static const struct v4l2_subdev_pad_ops adv748x_afe_pad_ops = { + .enum_mbus_code = adv748x_afe_enum_mbus_code, + .set_fmt = adv748x_afe_set_format, + .get_fmt = adv748x_afe_get_format, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_ops + */ + +static const struct v4l2_subdev_ops adv748x_afe_ops = { + .video = &adv748x_afe_video_ops, + .pad = &adv748x_afe_pad_ops, +}; + +/* ----------------------------------------------------------------------------- + * Controls + */ + +static const char * const afe_ctrl_frp_menu[] = { + "Disabled", + "Solid Blue", + "Color Bars", + "Grey Ramp", + "Cb Ramp", + "Cr Ramp", + "Boundary" +}; + +static int adv748x_afe_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct adv748x_afe *afe = adv748x_ctrl_to_afe(ctrl); + struct adv748x_state *state = adv748x_afe_to_state(afe); + bool enable; + int ret; + + ret = sdp_write(state, 0x0e, 0x00); + if (ret < 0) + return ret; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ret = sdp_write(state, ADV748X_SDP_BRI, ctrl->val); + break; + case V4L2_CID_HUE: + /* Hue is inverted according to HSL chart */ + ret = sdp_write(state, ADV748X_SDP_HUE, -ctrl->val); + break; + case V4L2_CID_CONTRAST: + ret = sdp_write(state, ADV748X_SDP_CON, ctrl->val); + break; + case V4L2_CID_SATURATION: + ret = sdp_write(state, ADV748X_SDP_SD_SAT_U, ctrl->val); + if (ret) + break; + ret = sdp_write(state, ADV748X_SDP_SD_SAT_V, ctrl->val); + break; + case V4L2_CID_TEST_PATTERN: + enable = !!ctrl->val; + + /* Enable/Disable Color bar test patterns */ + ret = sdp_clrset(state, ADV748X_SDP_DEF, ADV748X_SDP_DEF_VAL_EN, + enable); + if (ret) + break; + ret = sdp_clrset(state, ADV748X_SDP_FRP, ADV748X_SDP_FRP_MASK, + enable ? ctrl->val - 1 : 0); + break; + default: + return -EINVAL; + } + + return ret; +} + +static const struct v4l2_ctrl_ops adv748x_afe_ctrl_ops = { + .s_ctrl = adv748x_afe_s_ctrl, +}; + +static int adv748x_afe_init_controls(struct adv748x_afe *afe) +{ + struct adv748x_state *state = adv748x_afe_to_state(afe); + + v4l2_ctrl_handler_init(&afe->ctrl_hdl, 5); + + /* Use our mutex for the controls */ + afe->ctrl_hdl.lock = &state->mutex; + + v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, + V4L2_CID_BRIGHTNESS, ADV748X_SDP_BRI_MIN, + ADV748X_SDP_BRI_MAX, 1, ADV748X_SDP_BRI_DEF); + v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, + V4L2_CID_CONTRAST, ADV748X_SDP_CON_MIN, + ADV748X_SDP_CON_MAX, 1, ADV748X_SDP_CON_DEF); + v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, + V4L2_CID_SATURATION, ADV748X_SDP_SAT_MIN, + ADV748X_SDP_SAT_MAX, 1, ADV748X_SDP_SAT_DEF); + v4l2_ctrl_new_std(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, + V4L2_CID_HUE, ADV748X_SDP_HUE_MIN, + ADV748X_SDP_HUE_MAX, 1, ADV748X_SDP_HUE_DEF); + + v4l2_ctrl_new_std_menu_items(&afe->ctrl_hdl, &adv748x_afe_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(afe_ctrl_frp_menu) - 1, + 0, 0, afe_ctrl_frp_menu); + + afe->sd.ctrl_handler = &afe->ctrl_hdl; + if (afe->ctrl_hdl.error) { + v4l2_ctrl_handler_free(&afe->ctrl_hdl); + return afe->ctrl_hdl.error; + } + + return v4l2_ctrl_handler_setup(&afe->ctrl_hdl); +} + +int adv748x_afe_init(struct adv748x_afe *afe) +{ + struct adv748x_state *state = adv748x_afe_to_state(afe); + int ret; + unsigned int i; + + afe->input = 0; + afe->streaming = false; + afe->curr_norm = V4L2_STD_NTSC_M; + + adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops, + MEDIA_ENT_F_ATV_DECODER, "afe"); + + /* Identify the first connector found as a default input if set */ + for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) { + /* Inputs and ports are 1-indexed to match the data sheet */ + if (state->endpoints[i]) { + afe->input = i; + break; + } + } + + adv748x_afe_s_input(afe, afe->input); + + adv_dbg(state, "AFE Default input set to %d\n", afe->input); + + /* Entity pads and sinks are 0-indexed to match the pads */ + for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++) + afe->pads[i].flags = MEDIA_PAD_FL_SINK; + + afe->pads[ADV748X_AFE_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&afe->sd.entity, ADV748X_AFE_NR_PADS, + afe->pads); + if (ret) + return ret; + + ret = adv748x_afe_init_controls(afe); + if (ret) + goto error; + + return 0; + +error: + media_entity_cleanup(&afe->sd.entity); + + return ret; +} + +void adv748x_afe_cleanup(struct adv748x_afe *afe) +{ + v4l2_device_unregister_subdev(&afe->sd); + media_entity_cleanup(&afe->sd.entity); + v4l2_ctrl_handler_free(&afe->ctrl_hdl); +} diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c new file mode 100644 index 000000000000..aeb6ae80cb18 --- /dev/null +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -0,0 +1,832 @@ +/* + * Driver for Analog Devices ADV748X HDMI receiver with AFE + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Authors: + * Koji Matsuoka + * Niklas Söderlund + * Kieran Bingham + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "adv748x.h" + +/* ----------------------------------------------------------------------------- + * Register manipulation + */ + +static const struct regmap_config adv748x_regmap_cnf[] = { + { + .name = "io", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "dpll", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "cp", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "hdmi", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "edid", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "repeater", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "infoframe", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "cec", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "sdp", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + + { + .name = "txb", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, + { + .name = "txa", + .reg_bits = 8, + .val_bits = 8, + + .max_register = 0xff, + .cache_type = REGCACHE_NONE, + }, +}; + +static int adv748x_configure_regmap(struct adv748x_state *state, int region) +{ + int err; + + if (!state->i2c_clients[region]) + return -ENODEV; + + state->regmap[region] = + devm_regmap_init_i2c(state->i2c_clients[region], + &adv748x_regmap_cnf[region]); + + if (IS_ERR(state->regmap[region])) { + err = PTR_ERR(state->regmap[region]); + adv_err(state, + "Error initializing regmap %d with error %d\n", + region, err); + return -EINVAL; + } + + return 0; +} + +/* Default addresses for the I2C pages */ +static int adv748x_i2c_addresses[ADV748X_PAGE_MAX] = { + ADV748X_I2C_IO, + ADV748X_I2C_DPLL, + ADV748X_I2C_CP, + ADV748X_I2C_HDMI, + ADV748X_I2C_EDID, + ADV748X_I2C_REPEATER, + ADV748X_I2C_INFOFRAME, + ADV748X_I2C_CEC, + ADV748X_I2C_SDP, + ADV748X_I2C_TXB, + ADV748X_I2C_TXA, +}; + +static int adv748x_read_check(struct adv748x_state *state, + int client_page, u8 reg) +{ + struct i2c_client *client = state->i2c_clients[client_page]; + int err; + unsigned int val; + + err = regmap_read(state->regmap[client_page], reg, &val); + + if (err) { + adv_err(state, "error reading %02x, %02x\n", + client->addr, reg); + return err; + } + + return val; +} + +int adv748x_read(struct adv748x_state *state, u8 page, u8 reg) +{ + return adv748x_read_check(state, page, reg); +} + +int adv748x_write(struct adv748x_state *state, u8 page, u8 reg, u8 value) +{ + return regmap_write(state->regmap[page], reg, value); +} + +/* adv748x_write_block(): Write raw data with a maximum of I2C_SMBUS_BLOCK_MAX + * size to one or more registers. + * + * A value of zero will be returned on success, a negative errno will + * be returned in error cases. + */ +int adv748x_write_block(struct adv748x_state *state, int client_page, + unsigned int init_reg, const void *val, + size_t val_len) +{ + struct regmap *regmap = state->regmap[client_page]; + + if (val_len > I2C_SMBUS_BLOCK_MAX) + val_len = I2C_SMBUS_BLOCK_MAX; + + return regmap_raw_write(regmap, init_reg, val, val_len); +} + +static struct i2c_client *adv748x_dummy_client(struct adv748x_state *state, + u8 addr, u8 io_reg) +{ + struct i2c_client *client = state->client; + + if (addr) + io_write(state, io_reg, addr << 1); + + return i2c_new_dummy(client->adapter, io_read(state, io_reg) >> 1); +} + +static void adv748x_unregister_clients(struct adv748x_state *state) +{ + unsigned int i; + + for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) { + if (state->i2c_clients[i]) + i2c_unregister_device(state->i2c_clients[i]); + } +} + +static int adv748x_initialise_clients(struct adv748x_state *state) +{ + int i; + int ret; + + for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { + state->i2c_clients[i] = + adv748x_dummy_client(state, adv748x_i2c_addresses[i], + ADV748X_IO_SLAVE_ADDR_BASE + i); + if (state->i2c_clients[i] == NULL) { + adv_err(state, "failed to create i2c client %u\n", i); + return -ENOMEM; + } + + ret = adv748x_configure_regmap(state, i); + if (ret) + return ret; + } + + return 0; +} + +/** + * struct adv748x_reg_value - Register write instruction + * @page: Regmap page identifier + * @reg: I2C register + * @value: value to write to @page at @reg + */ +struct adv748x_reg_value { + u8 page; + u8 reg; + u8 value; +}; + +static int adv748x_write_regs(struct adv748x_state *state, + const struct adv748x_reg_value *regs) +{ + int ret; + + while (regs->page != ADV748X_PAGE_EOR) { + if (regs->page == ADV748X_PAGE_WAIT) { + msleep(regs->value); + } else { + ret = adv748x_write(state, regs->page, regs->reg, + regs->value); + if (ret < 0) { + adv_err(state, + "Error regs page: 0x%02x reg: 0x%02x\n", + regs->page, regs->reg); + return ret; + } + } + regs++; + } + + return 0; +} + +/* ----------------------------------------------------------------------------- + * TXA and TXB + */ + +static const struct adv748x_reg_value adv748x_power_up_txa_4lane[] = { + + {ADV748X_PAGE_TXA, 0x00, 0x84}, /* Enable 4-lane MIPI */ + {ADV748X_PAGE_TXA, 0x00, 0xa4}, /* Set Auto DPHY Timing */ + + {ADV748X_PAGE_TXA, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x1e, 0x40}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + {ADV748X_PAGE_WAIT, 0x00, 0x02},/* delay 2 */ + {ADV748X_PAGE_TXA, 0x00, 0x24 },/* Power-up CSI-TX */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXA, 0xc1, 0x2b}, /* ADI Required Write */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXA, 0x31, 0x80}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +static const struct adv748x_reg_value adv748x_power_down_txa_4lane[] = { + + {ADV748X_PAGE_TXA, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x1e, 0x00}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x00, 0x84}, /* Enable 4-lane MIPI */ + {ADV748X_PAGE_TXA, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + {ADV748X_PAGE_TXA, 0xc1, 0x3b}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +static const struct adv748x_reg_value adv748x_power_up_txb_1lane[] = { + + {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */ + {ADV748X_PAGE_TXB, 0x00, 0xa1}, /* Set Auto DPHY Timing */ + + {ADV748X_PAGE_TXB, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x1e, 0x40}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + {ADV748X_PAGE_WAIT, 0x00, 0x02},/* delay 2 */ + {ADV748X_PAGE_TXB, 0x00, 0x21 },/* Power-up CSI-TX */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXB, 0xc1, 0x2b}, /* ADI Required Write */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXB, 0x31, 0x80}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +static const struct adv748x_reg_value adv748x_power_down_txb_1lane[] = { + + {ADV748X_PAGE_TXB, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x1e, 0x00}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 4-lane MIPI */ + {ADV748X_PAGE_TXB, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + {ADV748X_PAGE_TXB, 0xc1, 0x3b}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +int adv748x_txa_power(struct adv748x_state *state, bool on) +{ + int val; + + val = txa_read(state, ADV748X_CSI_FS_AS_LS); + if (val < 0) + return val; + + /* + * This test against BIT(6) is not documented by the datasheet, but was + * specified in the downstream driver. + * Track with a WARN_ONCE to determine if it is ever set by HW. + */ + WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN), + "Enabling with unknown bit set"); + + if (on) + return adv748x_write_regs(state, adv748x_power_up_txa_4lane); + + return adv748x_write_regs(state, adv748x_power_down_txa_4lane); +} + +int adv748x_txb_power(struct adv748x_state *state, bool on) +{ + int val; + + val = txb_read(state, ADV748X_CSI_FS_AS_LS); + if (val < 0) + return val; + + /* + * This test against BIT(6) is not documented by the datasheet, but was + * specified in the downstream driver. + * Track with a WARN_ONCE to determine if it is ever set by HW. + */ + WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN), + "Enabling with unknown bit set"); + + if (on) + return adv748x_write_regs(state, adv748x_power_up_txb_1lane); + + return adv748x_write_regs(state, adv748x_power_down_txb_1lane); +} + +/* ----------------------------------------------------------------------------- + * Media Operations + */ + +static const struct media_entity_operations adv748x_media_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +/* ----------------------------------------------------------------------------- + * HW setup + */ + +static const struct adv748x_reg_value adv748x_sw_reset[] = { + + {ADV748X_PAGE_IO, 0xff, 0xff}, /* SW reset */ + {ADV748X_PAGE_WAIT, 0x00, 0x05},/* delay 5 */ + {ADV748X_PAGE_IO, 0x01, 0x76}, /* ADI Required Write */ + {ADV748X_PAGE_IO, 0xf2, 0x01}, /* Enable I2C Read Auto-Increment */ + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +static const struct adv748x_reg_value adv748x_set_slave_address[] = { + {ADV748X_PAGE_IO, 0xf3, ADV748X_I2C_DPLL << 1}, + {ADV748X_PAGE_IO, 0xf4, ADV748X_I2C_CP << 1}, + {ADV748X_PAGE_IO, 0xf5, ADV748X_I2C_HDMI << 1}, + {ADV748X_PAGE_IO, 0xf6, ADV748X_I2C_EDID << 1}, + {ADV748X_PAGE_IO, 0xf7, ADV748X_I2C_REPEATER << 1}, + {ADV748X_PAGE_IO, 0xf8, ADV748X_I2C_INFOFRAME << 1}, + {ADV748X_PAGE_IO, 0xfa, ADV748X_I2C_CEC << 1}, + {ADV748X_PAGE_IO, 0xfb, ADV748X_I2C_SDP << 1}, + {ADV748X_PAGE_IO, 0xfc, ADV748X_I2C_TXB << 1}, + {ADV748X_PAGE_IO, 0xfd, ADV748X_I2C_TXA << 1}, + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +/* Supported Formats For Script Below */ +/* - 01-29 HDMI to MIPI TxA CSI 4-Lane - RGB888: */ +static const struct adv748x_reg_value adv748x_init_txa_4lane[] = { + /* Disable chip powerdown & Enable HDMI Rx block */ + {ADV748X_PAGE_IO, 0x00, 0x40}, + + {ADV748X_PAGE_REPEATER, 0x40, 0x83}, /* Enable HDCP 1.1 */ + + {ADV748X_PAGE_HDMI, 0x00, 0x08},/* Foreground Channel = A */ + {ADV748X_PAGE_HDMI, 0x98, 0xff},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x99, 0xa3},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x9a, 0x00},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x9b, 0x0a},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x9d, 0x40},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0xcb, 0x09},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x3d, 0x10},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x3e, 0x7b},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x3f, 0x5e},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x4e, 0xfe},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x4f, 0x18},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x57, 0xa3},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x58, 0x04},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0x85, 0x10},/* ADI Required Write */ + + {ADV748X_PAGE_HDMI, 0x83, 0x00},/* Enable All Terminations */ + {ADV748X_PAGE_HDMI, 0xa3, 0x01},/* ADI Required Write */ + {ADV748X_PAGE_HDMI, 0xbe, 0x00},/* ADI Required Write */ + + {ADV748X_PAGE_HDMI, 0x6c, 0x01},/* HPA Manual Enable */ + {ADV748X_PAGE_HDMI, 0xf8, 0x01},/* HPA Asserted */ + {ADV748X_PAGE_HDMI, 0x0f, 0x00},/* Audio Mute Speed Set to Fastest */ + /* (Smallest Step Size) */ + + {ADV748X_PAGE_IO, 0x04, 0x02}, /* RGB Out of CP */ + {ADV748X_PAGE_IO, 0x12, 0xf0}, /* CSC Depends on ip Packets, SDR 444 */ + {ADV748X_PAGE_IO, 0x17, 0x80}, /* Luma & Chroma can reach 254d */ + {ADV748X_PAGE_IO, 0x03, 0x86}, /* CP-Insert_AV_Code */ + + {ADV748X_PAGE_CP, 0x7c, 0x00}, /* ADI Required Write */ + + {ADV748X_PAGE_IO, 0x0c, 0xe0}, /* Enable LLC_DLL & Double LLC Timing */ + {ADV748X_PAGE_IO, 0x0e, 0xdd}, /* LLC/PIX/SPI PINS TRISTATED AUD */ + /* Outputs Enabled */ + {ADV748X_PAGE_IO, 0x10, 0xa0}, /* Enable 4-lane CSI Tx & Pixel Port */ + + {ADV748X_PAGE_TXA, 0x00, 0x84}, /* Enable 4-lane MIPI */ + {ADV748X_PAGE_TXA, 0x00, 0xa4}, /* Set Auto DPHY Timing */ + {ADV748X_PAGE_TXA, 0xdb, 0x10}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0xd6, 0x07}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0xc4, 0x0a}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x71, 0x33}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x72, 0x11}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0xf0, 0x00}, /* i2c_dphy_pwdn - 1'b0 */ + + {ADV748X_PAGE_TXA, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0x1e, 0x40}, /* ADI Required Write */ + {ADV748X_PAGE_TXA, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + {ADV748X_PAGE_WAIT, 0x00, 0x02},/* delay 2 */ + {ADV748X_PAGE_TXA, 0x00, 0x24 },/* Power-up CSI-TX */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXA, 0xc1, 0x2b}, /* ADI Required Write */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXA, 0x31, 0x80}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +/* 02-01 Analog CVBS to MIPI TX-B CSI 1-Lane - */ +/* Autodetect CVBS Single Ended In Ain 1 - MIPI Out */ +static const struct adv748x_reg_value adv748x_init_txb_1lane[] = { + + {ADV748X_PAGE_IO, 0x00, 0x30}, /* Disable chip powerdown Rx */ + {ADV748X_PAGE_IO, 0xf2, 0x01}, /* Enable I2C Read Auto-Increment */ + + {ADV748X_PAGE_IO, 0x0e, 0xff}, /* LLC/PIX/AUD/SPI PINS TRISTATED */ + + {ADV748X_PAGE_SDP, 0x0f, 0x00}, /* Exit Power Down Mode */ + {ADV748X_PAGE_SDP, 0x52, 0xcd}, /* ADI Required Write */ + + {ADV748X_PAGE_SDP, 0x0e, 0x80}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0x9c, 0x00}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0x9c, 0xff}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0x0e, 0x00}, /* ADI Required Write */ + + /* ADI recommended writes for improved video quality */ + {ADV748X_PAGE_SDP, 0x80, 0x51}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0x81, 0x51}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0x82, 0x68}, /* ADI Required Write */ + + {ADV748X_PAGE_SDP, 0x03, 0x42}, /* Tri-S Output , PwrDwn 656 pads */ + {ADV748X_PAGE_SDP, 0x04, 0xb5}, /* ITU-R BT.656-4 compatible */ + {ADV748X_PAGE_SDP, 0x13, 0x00}, /* ADI Required Write */ + + {ADV748X_PAGE_SDP, 0x17, 0x41}, /* Select SH1 */ + {ADV748X_PAGE_SDP, 0x31, 0x12}, /* ADI Required Write */ + {ADV748X_PAGE_SDP, 0xe6, 0x4f}, /* V bit end pos manually in NTSC */ + + /* Enable 1-Lane MIPI Tx, */ + /* enable pixel output and route SD through Pixel port */ + {ADV748X_PAGE_IO, 0x10, 0x70}, + + {ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */ + {ADV748X_PAGE_TXB, 0x00, 0xa1}, /* Set Auto DPHY Timing */ + {ADV748X_PAGE_TXB, 0xd2, 0x40}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0xc4, 0x0a}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x71, 0x33}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x72, 0x11}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0xf0, 0x00}, /* i2c_dphy_pwdn - 1'b0 */ + {ADV748X_PAGE_TXB, 0x31, 0x82}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0x1e, 0x40}, /* ADI Required Write */ + {ADV748X_PAGE_TXB, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */ + + {ADV748X_PAGE_WAIT, 0x00, 0x02},/* delay 2 */ + {ADV748X_PAGE_TXB, 0x00, 0x21 },/* Power-up CSI-TX */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXB, 0xc1, 0x2b}, /* ADI Required Write */ + {ADV748X_PAGE_WAIT, 0x00, 0x01},/* delay 1 */ + {ADV748X_PAGE_TXB, 0x31, 0x80}, /* ADI Required Write */ + + {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ +}; + +static int adv748x_reset(struct adv748x_state *state) +{ + int ret; + + ret = adv748x_write_regs(state, adv748x_sw_reset); + if (ret < 0) + return ret; + + ret = adv748x_write_regs(state, adv748x_set_slave_address); + if (ret < 0) + return ret; + + /* Init and power down TXA */ + ret = adv748x_write_regs(state, adv748x_init_txa_4lane); + if (ret) + return ret; + + adv748x_txa_power(state, 0); + + /* Init and power down TXB */ + ret = adv748x_write_regs(state, adv748x_init_txb_1lane); + if (ret) + return ret; + + adv748x_txb_power(state, 0); + + /* Disable chip powerdown & Enable HDMI Rx block */ + io_write(state, ADV748X_IO_PD, ADV748X_IO_PD_RX_EN); + + /* Enable 4-lane CSI Tx & Pixel Port */ + io_write(state, ADV748X_IO_10, ADV748X_IO_10_CSI4_EN | + ADV748X_IO_10_CSI1_EN | + ADV748X_IO_10_PIX_OUT_EN); + + /* Use vid_std and v_freq as freerun resolution for CP */ + cp_clrset(state, ADV748X_CP_CLMP_POS, ADV748X_CP_CLMP_POS_DIS_AUTO, + ADV748X_CP_CLMP_POS_DIS_AUTO); + + return 0; +} + +static int adv748x_identify_chip(struct adv748x_state *state) +{ + int msb, lsb; + + lsb = io_read(state, ADV748X_IO_CHIP_REV_ID_1); + msb = io_read(state, ADV748X_IO_CHIP_REV_ID_2); + + if (lsb < 0 || msb < 0) { + adv_err(state, "Failed to read chip revision\n"); + return -EIO; + } + + adv_info(state, "chip found @ 0x%02x revision %02x%02x\n", + state->client->addr << 1, lsb, msb); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * i2c driver + */ + +void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state, + const struct v4l2_subdev_ops *ops, u32 function, + const char *ident) +{ + v4l2_subdev_init(sd, ops); + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + + /* the owner is the same as the i2c_client's driver owner */ + sd->owner = state->dev->driver->owner; + sd->dev = state->dev; + + v4l2_set_subdevdata(sd, state); + + /* initialize name */ + snprintf(sd->name, sizeof(sd->name), "%s %d-%04x %s", + state->dev->driver->name, + i2c_adapter_id(state->client->adapter), + state->client->addr, ident); + + sd->entity.function = function; + sd->entity.ops = &adv748x_media_ops; +} + +static int adv748x_parse_dt(struct adv748x_state *state) +{ + struct device_node *ep_np = NULL; + struct of_endpoint ep; + bool found = false; + + for_each_endpoint_of_node(state->dev->of_node, ep_np) { + of_graph_parse_endpoint(ep_np, &ep); + adv_info(state, "Endpoint %s on port %d", + of_node_full_name(ep.local_node), + ep.port); + + if (ep.port >= ADV748X_PORT_MAX) { + adv_err(state, "Invalid endpoint %s on port %d", + of_node_full_name(ep.local_node), + ep.port); + + continue; + } + + if (state->endpoints[ep.port]) { + adv_err(state, + "Multiple port endpoints are not supported"); + continue; + } + + of_node_get(ep_np); + state->endpoints[ep.port] = ep_np; + + found = true; + } + + return found ? 0 : -ENODEV; +} + +static void adv748x_dt_cleanup(struct adv748x_state *state) +{ + unsigned int i; + + for (i = 0; i < ADV748X_PORT_MAX; i++) + of_node_put(state->endpoints[i]); +} + +static int adv748x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adv748x_state *state; + int ret; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + state = kzalloc(sizeof(struct adv748x_state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + mutex_init(&state->mutex); + + state->dev = &client->dev; + state->client = client; + state->i2c_clients[ADV748X_PAGE_IO] = client; + i2c_set_clientdata(client, state); + + /* Discover and process ports declared by the Device tree endpoints */ + ret = adv748x_parse_dt(state); + if (ret) { + adv_err(state, "Failed to parse device tree"); + goto err_free_mutex; + } + + /* Configure IO Regmap region */ + ret = adv748x_configure_regmap(state, ADV748X_PAGE_IO); + if (ret) { + adv_err(state, "Error configuring IO regmap region"); + goto err_cleanup_dt; + } + + ret = adv748x_identify_chip(state); + if (ret) { + adv_err(state, "Failed to identify chip"); + goto err_cleanup_clients; + } + + /* Configure remaining pages as I2C clients with regmap access */ + ret = adv748x_initialise_clients(state); + if (ret) { + adv_err(state, "Failed to setup client regmap pages"); + goto err_cleanup_clients; + } + + /* SW reset ADV748X to its default values */ + ret = adv748x_reset(state); + if (ret) { + adv_err(state, "Failed to reset hardware"); + goto err_cleanup_clients; + } + + /* Initialise HDMI */ + ret = adv748x_hdmi_init(&state->hdmi); + if (ret) { + adv_err(state, "Failed to probe HDMI"); + goto err_cleanup_clients; + } + + /* Initialise AFE */ + ret = adv748x_afe_init(&state->afe); + if (ret) { + adv_err(state, "Failed to probe AFE"); + goto err_cleanup_hdmi; + } + + /* Initialise TXA */ + ret = adv748x_csi2_init(state, &state->txa); + if (ret) { + adv_err(state, "Failed to probe TXA"); + goto err_cleanup_afe; + } + + /* Initialise TXB */ + ret = adv748x_csi2_init(state, &state->txb); + if (ret) { + adv_err(state, "Failed to probe TXB"); + goto err_cleanup_txa; + } + + return 0; + +err_cleanup_txa: + adv748x_csi2_cleanup(&state->txa); +err_cleanup_afe: + adv748x_afe_cleanup(&state->afe); +err_cleanup_hdmi: + adv748x_hdmi_cleanup(&state->hdmi); +err_cleanup_clients: + adv748x_unregister_clients(state); +err_cleanup_dt: + adv748x_dt_cleanup(state); +err_free_mutex: + mutex_destroy(&state->mutex); + kfree(state); + + return ret; +} + +static int adv748x_remove(struct i2c_client *client) +{ + struct adv748x_state *state = i2c_get_clientdata(client); + + adv748x_afe_cleanup(&state->afe); + adv748x_hdmi_cleanup(&state->hdmi); + + adv748x_csi2_cleanup(&state->txa); + adv748x_csi2_cleanup(&state->txb); + + adv748x_unregister_clients(state); + adv748x_dt_cleanup(state); + mutex_destroy(&state->mutex); + + kfree(state); + + return 0; +} + +static const struct i2c_device_id adv748x_id[] = { + { "adv7481", 0 }, + { "adv7482", 0 }, + { }, +}; + +static const struct of_device_id adv748x_of_table[] = { + { .compatible = "adi,adv7481", }, + { .compatible = "adi,adv7482", }, + { } +}; +MODULE_DEVICE_TABLE(of, adv748x_of_table); + +static struct i2c_driver adv748x_driver = { + .driver = { + .name = "adv748x", + .of_match_table = adv748x_of_table, + }, + .probe = adv748x_probe, + .remove = adv748x_remove, + .id_table = adv748x_id, +}; + +module_i2c_driver(adv748x_driver); + +MODULE_AUTHOR("Kieran Bingham "); +MODULE_DESCRIPTION("ADV748X video decoder"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c new file mode 100644 index 000000000000..b4fee7f52d6a --- /dev/null +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -0,0 +1,327 @@ +/* + * Driver for Analog Devices ADV748X CSI-2 Transmitter + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include +#include + +#include "adv748x.h" + +static bool is_txa(struct adv748x_csi2 *tx) +{ + return tx == &tx->state->txa; +} + +static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, + unsigned int vc) +{ + return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT); +} + +/** + * adv748x_csi2_register_link : Register and link internal entities + * + * @tx: CSI2 private entity + * @v4l2_dev: Video registration device + * @src: Source subdevice to establish link + * @src_pad: Pad number of source to link to this @tx + * + * Ensure that the subdevice is registered against the v4l2_device, and link the + * source pad to the sink pad of the CSI2 bus entity. + */ +static int adv748x_csi2_register_link(struct adv748x_csi2 *tx, + struct v4l2_device *v4l2_dev, + struct v4l2_subdev *src, + unsigned int src_pad) +{ + int enabled = MEDIA_LNK_FL_ENABLED; + int ret; + + /* + * Dynamic linking of the AFE is not supported. + * Register the links as immutable. + */ + enabled |= MEDIA_LNK_FL_IMMUTABLE; + + if (!src->v4l2_dev) { + ret = v4l2_device_register_subdev(v4l2_dev, src); + if (ret) + return ret; + } + + return media_create_pad_link(&src->entity, src_pad, + &tx->sd.entity, ADV748X_CSI2_SINK, + enabled); +} + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_internal_ops + * + * We use the internal registered operation to be able to ensure that our + * incremental subdevices (not connected in the forward path) can be registered + * against the resulting video path and media device. + */ + +static int adv748x_csi2_registered(struct v4l2_subdev *sd) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct adv748x_state *state = tx->state; + + adv_dbg(state, "Registered %s (%s)", is_txa(tx) ? "TXA":"TXB", + sd->name); + + /* + * The adv748x hardware allows the AFE to route through the TXA, however + * this is not currently supported in this driver. + * + * Link HDMI->TXA, and AFE->TXB directly. + */ + if (is_txa(tx)) { + return adv748x_csi2_register_link(tx, sd->v4l2_dev, + &state->hdmi.sd, + ADV748X_HDMI_SOURCE); + } else { + return adv748x_csi2_register_link(tx, sd->v4l2_dev, + &state->afe.sd, + ADV748X_AFE_SOURCE); + } +} + +static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = { + .registered = adv748x_csi2_registered, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_video_ops + */ + +static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct v4l2_subdev *src; + + src = adv748x_get_remote_sd(&tx->pads[ADV748X_CSI2_SINK]); + if (!src) + return -EPIPE; + + return v4l2_subdev_call(src, video, s_stream, enable); +} + +static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = { + .s_stream = adv748x_csi2_s_stream, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_pad_ops + * + * The CSI2 bus pads are ignorant to the data sizes or formats. + * But we must support setting the pad formats for format propagation. + */ + +static struct v4l2_mbus_framefmt * +adv748x_csi2_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, u32 which) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(sd, cfg, pad); + + return &tx->format; +} + +static int adv748x_csi2_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct adv748x_state *state = tx->state; + struct v4l2_mbus_framefmt *mbusformat; + + mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, + sdformat->which); + if (!mbusformat) + return -EINVAL; + + mutex_lock(&state->mutex); + + sdformat->format = *mbusformat; + + mutex_unlock(&state->mutex); + + return 0; +} + +static int adv748x_csi2_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct adv748x_state *state = tx->state; + struct v4l2_mbus_framefmt *mbusformat; + int ret = 0; + + mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, + sdformat->which); + if (!mbusformat) + return -EINVAL; + + mutex_lock(&state->mutex); + + if (sdformat->pad == ADV748X_CSI2_SOURCE) { + const struct v4l2_mbus_framefmt *sink_fmt; + + sink_fmt = adv748x_csi2_get_pad_format(sd, cfg, + ADV748X_CSI2_SINK, + sdformat->which); + + if (!sink_fmt) { + ret = -EINVAL; + goto unlock; + } + + sdformat->format = *sink_fmt; + } + + *mbusformat = sdformat->format; + +unlock: + mutex_unlock(&state->mutex); + + return ret; +} + +static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { + .get_fmt = adv748x_csi2_get_format, + .set_fmt = adv748x_csi2_set_format, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_ops + */ + +static const struct v4l2_subdev_ops adv748x_csi2_ops = { + .video = &adv748x_csi2_video_ops, + .pad = &adv748x_csi2_pad_ops, +}; + +/* ----------------------------------------------------------------------------- + * Subdev module and controls + */ + +int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate) +{ + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE); + if (!ctrl) + return -EINVAL; + + return v4l2_ctrl_s_ctrl_int64(ctrl, rate); +} + +static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_PIXEL_RATE: + return 0; + default: + return -EINVAL; + } +} + +static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = { + .s_ctrl = adv748x_csi2_s_ctrl, +}; + +static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) +{ + struct v4l2_ctrl *ctrl; + + v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1); + + ctrl = v4l2_ctrl_new_std(&tx->ctrl_hdl, &adv748x_csi2_ctrl_ops, + V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); + + tx->sd.ctrl_handler = &tx->ctrl_hdl; + if (tx->ctrl_hdl.error) { + v4l2_ctrl_handler_free(&tx->ctrl_hdl); + return tx->ctrl_hdl.error; + } + + return v4l2_ctrl_handler_setup(&tx->ctrl_hdl); +} + +int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) +{ + struct device_node *ep; + int ret; + + /* We can not use container_of to get back to the state with two TXs */ + tx->state = state; + tx->page = is_txa(tx) ? ADV748X_PAGE_TXA : ADV748X_PAGE_TXB; + + ep = state->endpoints[is_txa(tx) ? ADV748X_PORT_TXA : ADV748X_PORT_TXB]; + if (!ep) { + adv_err(state, "No endpoint found for %s\n", + is_txa(tx) ? "txa" : "txb"); + return -ENODEV; + } + + /* Initialise the virtual channel */ + adv748x_csi2_set_virtual_channel(tx, 0); + + adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, + MEDIA_ENT_F_UNKNOWN, + is_txa(tx) ? "txa" : "txb"); + + /* Ensure that matching is based upon the endpoint fwnodes */ + tx->sd.fwnode = of_fwnode_handle(ep); + + /* Register internal ops for incremental subdev registration */ + tx->sd.internal_ops = &adv748x_csi2_internal_ops; + + tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; + tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS, + tx->pads); + if (ret) + return ret; + + ret = adv748x_csi2_init_controls(tx); + if (ret) + goto err_free_media; + + ret = v4l2_async_register_subdev(&tx->sd); + if (ret) + goto err_free_ctrl; + + return 0; + +err_free_ctrl: + v4l2_ctrl_handler_free(&tx->ctrl_hdl); +err_free_media: + media_entity_cleanup(&tx->sd.entity); + + return ret; +} + +void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) +{ + v4l2_async_unregister_subdev(&tx->sd); + media_entity_cleanup(&tx->sd.entity); + v4l2_ctrl_handler_free(&tx->ctrl_hdl); +} diff --git a/drivers/media/i2c/adv748x/adv748x-hdmi.c b/drivers/media/i2c/adv748x/adv748x-hdmi.c new file mode 100644 index 000000000000..4da4253553fc --- /dev/null +++ b/drivers/media/i2c/adv748x/adv748x-hdmi.c @@ -0,0 +1,768 @@ +/* + * Driver for Analog Devices ADV748X HDMI receiver and Component Processor (CP) + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "adv748x.h" + +/* ----------------------------------------------------------------------------- + * HDMI and CP + */ + +#define ADV748X_HDMI_MIN_WIDTH 640 +#define ADV748X_HDMI_MAX_WIDTH 1920 +#define ADV748X_HDMI_MIN_HEIGHT 480 +#define ADV748X_HDMI_MAX_HEIGHT 1200 + +/* V4L2_DV_BT_CEA_720X480I59_94 - 0.5 MHz */ +#define ADV748X_HDMI_MIN_PIXELCLOCK 13000000 +/* V4L2_DV_BT_DMT_1600X1200P60 */ +#define ADV748X_HDMI_MAX_PIXELCLOCK 162000000 + +static const struct v4l2_dv_timings_cap adv748x_hdmi_timings_cap = { + .type = V4L2_DV_BT_656_1120, + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + + V4L2_INIT_BT_TIMINGS(ADV748X_HDMI_MIN_WIDTH, ADV748X_HDMI_MAX_WIDTH, + ADV748X_HDMI_MIN_HEIGHT, ADV748X_HDMI_MAX_HEIGHT, + ADV748X_HDMI_MIN_PIXELCLOCK, + ADV748X_HDMI_MAX_PIXELCLOCK, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT, + V4L2_DV_BT_CAP_PROGRESSIVE) +}; + +struct adv748x_hdmi_video_standards { + struct v4l2_dv_timings timings; + u8 vid_std; + u8 v_freq; +}; + +static const struct adv748x_hdmi_video_standards +adv748x_hdmi_video_standards[] = { + { V4L2_DV_BT_CEA_720X480P59_94, 0x4a, 0x00 }, + { V4L2_DV_BT_CEA_720X576P50, 0x4b, 0x00 }, + { V4L2_DV_BT_CEA_1280X720P60, 0x53, 0x00 }, + { V4L2_DV_BT_CEA_1280X720P50, 0x53, 0x01 }, + { V4L2_DV_BT_CEA_1280X720P30, 0x53, 0x02 }, + { V4L2_DV_BT_CEA_1280X720P25, 0x53, 0x03 }, + { V4L2_DV_BT_CEA_1280X720P24, 0x53, 0x04 }, + { V4L2_DV_BT_CEA_1920X1080P60, 0x5e, 0x00 }, + { V4L2_DV_BT_CEA_1920X1080P50, 0x5e, 0x01 }, + { V4L2_DV_BT_CEA_1920X1080P30, 0x5e, 0x02 }, + { V4L2_DV_BT_CEA_1920X1080P25, 0x5e, 0x03 }, + { V4L2_DV_BT_CEA_1920X1080P24, 0x5e, 0x04 }, + /* SVGA */ + { V4L2_DV_BT_DMT_800X600P56, 0x80, 0x00 }, + { V4L2_DV_BT_DMT_800X600P60, 0x81, 0x00 }, + { V4L2_DV_BT_DMT_800X600P72, 0x82, 0x00 }, + { V4L2_DV_BT_DMT_800X600P75, 0x83, 0x00 }, + { V4L2_DV_BT_DMT_800X600P85, 0x84, 0x00 }, + /* SXGA */ + { V4L2_DV_BT_DMT_1280X1024P60, 0x85, 0x00 }, + { V4L2_DV_BT_DMT_1280X1024P75, 0x86, 0x00 }, + /* VGA */ + { V4L2_DV_BT_DMT_640X480P60, 0x88, 0x00 }, + { V4L2_DV_BT_DMT_640X480P72, 0x89, 0x00 }, + { V4L2_DV_BT_DMT_640X480P75, 0x8a, 0x00 }, + { V4L2_DV_BT_DMT_640X480P85, 0x8b, 0x00 }, + /* XGA */ + { V4L2_DV_BT_DMT_1024X768P60, 0x8c, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P70, 0x8d, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P75, 0x8e, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P85, 0x8f, 0x00 }, + /* UXGA */ + { V4L2_DV_BT_DMT_1600X1200P60, 0x96, 0x00 }, +}; + +static void adv748x_hdmi_fill_format(struct adv748x_hdmi *hdmi, + struct v4l2_mbus_framefmt *fmt) +{ + memset(fmt, 0, sizeof(*fmt)); + + fmt->code = MEDIA_BUS_FMT_RGB888_1X24; + fmt->field = hdmi->timings.bt.interlaced ? + V4L2_FIELD_ALTERNATE : V4L2_FIELD_NONE; + + /* TODO: The colorspace depends on the AVI InfoFrame contents */ + fmt->colorspace = V4L2_COLORSPACE_SRGB; + + fmt->width = hdmi->timings.bt.width; + fmt->height = hdmi->timings.bt.height; +} + +static void adv748x_fill_optional_dv_timings(struct v4l2_dv_timings *timings) +{ + v4l2_find_dv_timings_cap(timings, &adv748x_hdmi_timings_cap, + 250000, NULL, NULL); +} + +static bool adv748x_hdmi_has_signal(struct adv748x_state *state) +{ + int val; + + /* Check that VERT_FILTER and DE_REGEN is locked */ + val = hdmi_read(state, ADV748X_HDMI_LW1); + return (val & ADV748X_HDMI_LW1_VERT_FILTER) && + (val & ADV748X_HDMI_LW1_DE_REGEN); +} + +static int adv748x_hdmi_read_pixelclock(struct adv748x_state *state) +{ + int a, b; + + a = hdmi_read(state, ADV748X_HDMI_TMDS_1); + b = hdmi_read(state, ADV748X_HDMI_TMDS_2); + if (a < 0 || b < 0) + return -ENODATA; + + /* + * The high 9 bits store TMDS frequency measurement in MHz + * The low 7 bits of TMDS_2 store the 7-bit TMDS fractional frequency + * measurement in 1/128 MHz + */ + return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128; +} + +/* + * adv748x_hdmi_set_de_timings: Adjust horizontal picture offset through DE + * + * HDMI CP uses a Data Enable synchronisation timing reference + * + * Vary the leading and trailing edge position of the DE signal output by the CP + * core. Values are stored as signed-twos-complement in one-pixel-clock units + * + * The start and end are shifted equally by the 10-bit shift value. + */ +static void adv748x_hdmi_set_de_timings(struct adv748x_state *state, int shift) +{ + u8 high, low; + + /* POS_HIGH stores bits 8 and 9 of both the start and end */ + high = ADV748X_CP_DE_POS_HIGH_SET; + high |= (shift & 0x300) >> 8; + low = shift & 0xff; + + /* The sequence of the writes is important and must be followed */ + cp_write(state, ADV748X_CP_DE_POS_HIGH, high); + cp_write(state, ADV748X_CP_DE_POS_END_LOW, low); + + high |= (shift & 0x300) >> 6; + + cp_write(state, ADV748X_CP_DE_POS_HIGH, high); + cp_write(state, ADV748X_CP_DE_POS_START_LOW, low); +} + +static int adv748x_hdmi_set_video_timings(struct adv748x_state *state, + const struct v4l2_dv_timings *timings) +{ + const struct adv748x_hdmi_video_standards *stds = + adv748x_hdmi_video_standards; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(adv748x_hdmi_video_standards); i++) { + if (!v4l2_match_dv_timings(timings, &stds[i].timings, 250000, + false)) + continue; + } + + if (i >= ARRAY_SIZE(adv748x_hdmi_video_standards)) + return -EINVAL; + + /* + * When setting cp_vid_std to either 720p, 1080i, or 1080p, the video + * will get shifted horizontally to the left in active video mode. + * The de_h_start and de_h_end controls are used to centre the picture + * correctly + */ + switch (stds[i].vid_std) { + case 0x53: /* 720p */ + adv748x_hdmi_set_de_timings(state, -40); + break; + case 0x54: /* 1080i */ + case 0x5e: /* 1080p */ + adv748x_hdmi_set_de_timings(state, -44); + break; + default: + adv748x_hdmi_set_de_timings(state, 0); + break; + } + + io_write(state, ADV748X_IO_VID_STD, stds[i].vid_std); + io_clrset(state, ADV748X_IO_DATAPATH, ADV748X_IO_DATAPATH_VFREQ_M, + stds[i].v_freq << ADV748X_IO_DATAPATH_VFREQ_SHIFT); + + return 0; +} + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_video_ops + */ + +static int adv748x_hdmi_s_dv_timings(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + int ret; + + if (!timings) + return -EINVAL; + + if (v4l2_match_dv_timings(&hdmi->timings, timings, 0, false)) + return 0; + + if (!v4l2_valid_dv_timings(timings, &adv748x_hdmi_timings_cap, + NULL, NULL)) + return -ERANGE; + + adv748x_fill_optional_dv_timings(timings); + + mutex_lock(&state->mutex); + + ret = adv748x_hdmi_set_video_timings(state, timings); + if (ret) + goto error; + + hdmi->timings = *timings; + + cp_clrset(state, ADV748X_CP_VID_ADJ_2, ADV748X_CP_VID_ADJ_2_INTERLACED, + timings->bt.interlaced ? + ADV748X_CP_VID_ADJ_2_INTERLACED : 0); + + mutex_unlock(&state->mutex); + + return 0; + +error: + mutex_unlock(&state->mutex); + return ret; +} + +static int adv748x_hdmi_g_dv_timings(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + + mutex_lock(&state->mutex); + + *timings = hdmi->timings; + + mutex_unlock(&state->mutex); + + return 0; +} + +static int adv748x_hdmi_query_dv_timings(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + struct v4l2_bt_timings *bt = &timings->bt; + int pixelclock; + int polarity; + + if (!timings) + return -EINVAL; + + memset(timings, 0, sizeof(struct v4l2_dv_timings)); + + if (!adv748x_hdmi_has_signal(state)) + return -ENOLINK; + + pixelclock = adv748x_hdmi_read_pixelclock(state); + if (pixelclock < 0) + return -ENODATA; + + timings->type = V4L2_DV_BT_656_1120; + + bt->pixelclock = pixelclock; + bt->interlaced = hdmi_read(state, ADV748X_HDMI_F1H1) & + ADV748X_HDMI_F1H1_INTERLACED ? + V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; + bt->width = hdmi_read16(state, ADV748X_HDMI_LW1, + ADV748X_HDMI_LW1_WIDTH_MASK); + bt->height = hdmi_read16(state, ADV748X_HDMI_F0H1, + ADV748X_HDMI_F0H1_HEIGHT_MASK); + bt->hfrontporch = hdmi_read16(state, ADV748X_HDMI_HFRONT_PORCH, + ADV748X_HDMI_HFRONT_PORCH_MASK); + bt->hsync = hdmi_read16(state, ADV748X_HDMI_HSYNC_WIDTH, + ADV748X_HDMI_HSYNC_WIDTH_MASK); + bt->hbackporch = hdmi_read16(state, ADV748X_HDMI_HBACK_PORCH, + ADV748X_HDMI_HBACK_PORCH_MASK); + bt->vfrontporch = hdmi_read16(state, ADV748X_HDMI_VFRONT_PORCH, + ADV748X_HDMI_VFRONT_PORCH_MASK) / 2; + bt->vsync = hdmi_read16(state, ADV748X_HDMI_VSYNC_WIDTH, + ADV748X_HDMI_VSYNC_WIDTH_MASK) / 2; + bt->vbackporch = hdmi_read16(state, ADV748X_HDMI_VBACK_PORCH, + ADV748X_HDMI_VBACK_PORCH_MASK) / 2; + + polarity = hdmi_read(state, 0x05); + bt->polarities = (polarity & BIT(4) ? V4L2_DV_VSYNC_POS_POL : 0) | + (polarity & BIT(5) ? V4L2_DV_HSYNC_POS_POL : 0); + + if (bt->interlaced == V4L2_DV_INTERLACED) { + bt->height += hdmi_read16(state, 0x0b, 0x1fff); + bt->il_vfrontporch = hdmi_read16(state, 0x2c, 0x3fff) / 2; + bt->il_vsync = hdmi_read16(state, 0x30, 0x3fff) / 2; + bt->il_vbackporch = hdmi_read16(state, 0x34, 0x3fff) / 2; + } + + adv748x_fill_optional_dv_timings(timings); + + /* + * No interrupt handling is implemented yet. + * There should be an IRQ when a cable is plugged and the new timings + * should be figured out and stored to state. + */ + hdmi->timings = *timings; + + return 0; +} + +static int adv748x_hdmi_g_input_status(struct v4l2_subdev *sd, u32 *status) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + + mutex_lock(&state->mutex); + + *status = adv748x_hdmi_has_signal(state) ? 0 : V4L2_IN_ST_NO_SIGNAL; + + mutex_unlock(&state->mutex); + + return 0; +} + +static int adv748x_hdmi_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + int ret; + + mutex_lock(&state->mutex); + + ret = adv748x_txa_power(state, enable); + if (ret) + goto done; + + if (adv748x_hdmi_has_signal(state)) + adv_dbg(state, "Detected HDMI signal\n"); + else + adv_dbg(state, "Couldn't detect HDMI video signal\n"); + +done: + mutex_unlock(&state->mutex); + return ret; +} + +static int adv748x_hdmi_g_pixelaspect(struct v4l2_subdev *sd, + struct v4l2_fract *aspect) +{ + aspect->numerator = 1; + aspect->denominator = 1; + + return 0; +} + +static const struct v4l2_subdev_video_ops adv748x_video_ops_hdmi = { + .s_dv_timings = adv748x_hdmi_s_dv_timings, + .g_dv_timings = adv748x_hdmi_g_dv_timings, + .query_dv_timings = adv748x_hdmi_query_dv_timings, + .g_input_status = adv748x_hdmi_g_input_status, + .s_stream = adv748x_hdmi_s_stream, + .g_pixelaspect = adv748x_hdmi_g_pixelaspect, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_pad_ops + */ + +static int adv748x_hdmi_propagate_pixelrate(struct adv748x_hdmi *hdmi) +{ + struct v4l2_subdev *tx; + struct v4l2_dv_timings timings; + struct v4l2_bt_timings *bt = &timings.bt; + unsigned int fps; + + tx = adv748x_get_remote_sd(&hdmi->pads[ADV748X_HDMI_SOURCE]); + if (!tx) + return -ENOLINK; + + adv748x_hdmi_query_dv_timings(&hdmi->sd, &timings); + + fps = DIV_ROUND_CLOSEST_ULL(bt->pixelclock, + V4L2_DV_BT_FRAME_WIDTH(bt) * + V4L2_DV_BT_FRAME_HEIGHT(bt)); + + return adv748x_csi2_set_pixelrate(tx, bt->width * bt->height * fps); +} + +static int adv748x_hdmi_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index != 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_RGB888_1X24; + + return 0; +} + +static int adv748x_hdmi_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct v4l2_mbus_framefmt *mbusformat; + + if (sdformat->pad != ADV748X_HDMI_SOURCE) + return -EINVAL; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { + mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + sdformat->format = *mbusformat; + } else { + adv748x_hdmi_fill_format(hdmi, &sdformat->format); + adv748x_hdmi_propagate_pixelrate(hdmi); + } + + return 0; +} + +static int adv748x_hdmi_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *sdformat) +{ + struct v4l2_mbus_framefmt *mbusformat; + + if (sdformat->pad != ADV748X_HDMI_SOURCE) + return -EINVAL; + + if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return adv748x_hdmi_get_format(sd, cfg, sdformat); + + mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + *mbusformat = sdformat->format; + + return 0; +} + +static int adv748x_hdmi_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + + memset(edid->reserved, 0, sizeof(edid->reserved)); + + if (!hdmi->edid.present) + return -ENODATA; + + if (edid->start_block == 0 && edid->blocks == 0) { + edid->blocks = hdmi->edid.blocks; + return 0; + } + + if (edid->start_block >= hdmi->edid.blocks) + return -EINVAL; + + if (edid->start_block + edid->blocks > hdmi->edid.blocks) + edid->blocks = hdmi->edid.blocks - edid->start_block; + + memcpy(edid->edid, hdmi->edid.edid + edid->start_block * 128, + edid->blocks * 128); + + return 0; +} + +static inline int adv748x_hdmi_edid_write_block(struct adv748x_hdmi *hdmi, + unsigned int total_len, const u8 *val) +{ + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + int err = 0; + int i = 0; + int len = 0; + + adv_dbg(state, "%s: write EDID block (%d byte)\n", + __func__, total_len); + + while (!err && i < total_len) { + len = (total_len - i) > I2C_SMBUS_BLOCK_MAX ? + I2C_SMBUS_BLOCK_MAX : + (total_len - i); + + err = adv748x_write_block(state, ADV748X_PAGE_EDID, + i, val + i, len); + i += len; + } + + return err; +} + +static int adv748x_hdmi_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) +{ + struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + int err; + + memset(edid->reserved, 0, sizeof(edid->reserved)); + + if (edid->start_block != 0) + return -EINVAL; + + if (edid->blocks == 0) { + hdmi->edid.blocks = 0; + hdmi->edid.present = 0; + + /* Fall back to a 16:9 aspect ratio */ + hdmi->aspect_ratio.numerator = 16; + hdmi->aspect_ratio.denominator = 9; + + /* Disable the EDID */ + repeater_write(state, ADV748X_REPEATER_EDID_SZ, + edid->blocks << ADV748X_REPEATER_EDID_SZ_SHIFT); + + repeater_write(state, ADV748X_REPEATER_EDID_CTL, 0); + + return 0; + } + + if (edid->blocks > 4) { + edid->blocks = 4; + return -E2BIG; + } + + memcpy(hdmi->edid.edid, edid->edid, 128 * edid->blocks); + hdmi->edid.blocks = edid->blocks; + hdmi->edid.present = true; + + hdmi->aspect_ratio = v4l2_calc_aspect_ratio(edid->edid[0x15], + edid->edid[0x16]); + + err = adv748x_hdmi_edid_write_block(hdmi, 128 * edid->blocks, + hdmi->edid.edid); + if (err < 0) { + v4l2_err(sd, "error %d writing edid pad %d\n", err, edid->pad); + return err; + } + + repeater_write(state, ADV748X_REPEATER_EDID_SZ, + edid->blocks << ADV748X_REPEATER_EDID_SZ_SHIFT); + + repeater_write(state, ADV748X_REPEATER_EDID_CTL, + ADV748X_REPEATER_EDID_CTL_EN); + + return 0; +} + +static bool adv748x_hdmi_check_dv_timings(const struct v4l2_dv_timings *timings, + void *hdl) +{ + const struct adv748x_hdmi_video_standards *stds = + adv748x_hdmi_video_standards; + unsigned int i; + + for (i = 0; stds[i].timings.bt.width; i++) + if (v4l2_match_dv_timings(timings, &stds[i].timings, 0, false)) + return true; + + return false; +} + +static int adv748x_hdmi_enum_dv_timings(struct v4l2_subdev *sd, + struct v4l2_enum_dv_timings *timings) +{ + return v4l2_enum_dv_timings_cap(timings, &adv748x_hdmi_timings_cap, + adv748x_hdmi_check_dv_timings, NULL); +} + +static int adv748x_hdmi_dv_timings_cap(struct v4l2_subdev *sd, + struct v4l2_dv_timings_cap *cap) +{ + *cap = adv748x_hdmi_timings_cap; + return 0; +} + +static const struct v4l2_subdev_pad_ops adv748x_pad_ops_hdmi = { + .enum_mbus_code = adv748x_hdmi_enum_mbus_code, + .set_fmt = adv748x_hdmi_set_format, + .get_fmt = adv748x_hdmi_get_format, + .get_edid = adv748x_hdmi_get_edid, + .set_edid = adv748x_hdmi_set_edid, + .dv_timings_cap = adv748x_hdmi_dv_timings_cap, + .enum_dv_timings = adv748x_hdmi_enum_dv_timings, +}; + +/* ----------------------------------------------------------------------------- + * v4l2_subdev_ops + */ + +static const struct v4l2_subdev_ops adv748x_ops_hdmi = { + .video = &adv748x_video_ops_hdmi, + .pad = &adv748x_pad_ops_hdmi, +}; + +/* ----------------------------------------------------------------------------- + * Controls + */ + +static const char * const hdmi_ctrl_patgen_menu[] = { + "Disabled", + "Solid Color", + "Color Bars", + "Ramp Grey", + "Ramp Blue", + "Ramp Red", + "Checkered" +}; + +static int adv748x_hdmi_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct adv748x_hdmi *hdmi = adv748x_ctrl_to_hdmi(ctrl); + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + int ret; + u8 pattern; + + /* Enable video adjustment first */ + ret = cp_clrset(state, ADV748X_CP_VID_ADJ, + ADV748X_CP_VID_ADJ_ENABLE, + ADV748X_CP_VID_ADJ_ENABLE); + if (ret < 0) + return ret; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ret = cp_write(state, ADV748X_CP_BRI, ctrl->val); + break; + case V4L2_CID_HUE: + ret = cp_write(state, ADV748X_CP_HUE, ctrl->val); + break; + case V4L2_CID_CONTRAST: + ret = cp_write(state, ADV748X_CP_CON, ctrl->val); + break; + case V4L2_CID_SATURATION: + ret = cp_write(state, ADV748X_CP_SAT, ctrl->val); + break; + case V4L2_CID_TEST_PATTERN: + pattern = ctrl->val; + + /* Pattern is 0-indexed. Ctrl Menu is 1-indexed */ + if (pattern) { + pattern--; + pattern |= ADV748X_CP_PAT_GEN_EN; + } + + ret = cp_write(state, ADV748X_CP_PAT_GEN, pattern); + + break; + default: + return -EINVAL; + } + + return ret; +} + +static const struct v4l2_ctrl_ops adv748x_hdmi_ctrl_ops = { + .s_ctrl = adv748x_hdmi_s_ctrl, +}; + +static int adv748x_hdmi_init_controls(struct adv748x_hdmi *hdmi) +{ + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + + v4l2_ctrl_handler_init(&hdmi->ctrl_hdl, 5); + + /* Use our mutex for the controls */ + hdmi->ctrl_hdl.lock = &state->mutex; + + v4l2_ctrl_new_std(&hdmi->ctrl_hdl, &adv748x_hdmi_ctrl_ops, + V4L2_CID_BRIGHTNESS, ADV748X_CP_BRI_MIN, + ADV748X_CP_BRI_MAX, 1, ADV748X_CP_BRI_DEF); + v4l2_ctrl_new_std(&hdmi->ctrl_hdl, &adv748x_hdmi_ctrl_ops, + V4L2_CID_CONTRAST, ADV748X_CP_CON_MIN, + ADV748X_CP_CON_MAX, 1, ADV748X_CP_CON_DEF); + v4l2_ctrl_new_std(&hdmi->ctrl_hdl, &adv748x_hdmi_ctrl_ops, + V4L2_CID_SATURATION, ADV748X_CP_SAT_MIN, + ADV748X_CP_SAT_MAX, 1, ADV748X_CP_SAT_DEF); + v4l2_ctrl_new_std(&hdmi->ctrl_hdl, &adv748x_hdmi_ctrl_ops, + V4L2_CID_HUE, ADV748X_CP_HUE_MIN, + ADV748X_CP_HUE_MAX, 1, ADV748X_CP_HUE_DEF); + + /* + * Todo: V4L2_CID_DV_RX_POWER_PRESENT should also be supported when + * interrupts are handled correctly + */ + + v4l2_ctrl_new_std_menu_items(&hdmi->ctrl_hdl, &adv748x_hdmi_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(hdmi_ctrl_patgen_menu) - 1, + 0, 0, hdmi_ctrl_patgen_menu); + + hdmi->sd.ctrl_handler = &hdmi->ctrl_hdl; + if (hdmi->ctrl_hdl.error) { + v4l2_ctrl_handler_free(&hdmi->ctrl_hdl); + return hdmi->ctrl_hdl.error; + } + + return v4l2_ctrl_handler_setup(&hdmi->ctrl_hdl); +} + +int adv748x_hdmi_init(struct adv748x_hdmi *hdmi) +{ + struct adv748x_state *state = adv748x_hdmi_to_state(hdmi); + static const struct v4l2_dv_timings cea1280x720 = + V4L2_DV_BT_CEA_1280X720P30; + int ret; + + hdmi->timings = cea1280x720; + + /* Initialise a default 16:9 aspect ratio */ + hdmi->aspect_ratio.numerator = 16; + hdmi->aspect_ratio.denominator = 9; + + adv748x_subdev_init(&hdmi->sd, state, &adv748x_ops_hdmi, + MEDIA_ENT_F_IO_DTV, "hdmi"); + + hdmi->pads[ADV748X_HDMI_SINK].flags = MEDIA_PAD_FL_SINK; + hdmi->pads[ADV748X_HDMI_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&hdmi->sd.entity, + ADV748X_HDMI_NR_PADS, hdmi->pads); + if (ret) + return ret; + + ret = adv748x_hdmi_init_controls(hdmi); + if (ret) + goto err_free_media; + + return 0; + +err_free_media: + media_entity_cleanup(&hdmi->sd.entity); + + return ret; +} + +void adv748x_hdmi_cleanup(struct adv748x_hdmi *hdmi) +{ + v4l2_device_unregister_subdev(&hdmi->sd); + media_entity_cleanup(&hdmi->sd.entity); + v4l2_ctrl_handler_free(&hdmi->ctrl_hdl); +} diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h new file mode 100644 index 000000000000..cc4151b5b31e --- /dev/null +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -0,0 +1,425 @@ +/* + * Driver for Analog Devices ADV748X video decoder and HDMI receiver + * + * Copyright (C) 2017 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Authors: + * Koji Matsuoka + * Niklas Söderlund + * Kieran Bingham + * + * The ADV748x range of receivers have the following configurations: + * + * Analog HDMI MHL 4-Lane 1-Lane + * In In CSI CSI + * ADV7480 X X X + * ADV7481 X X X X X + * ADV7482 X X X X + */ + +#include + +#ifndef _ADV748X_H_ +#define _ADV748X_H_ + +/* I2C slave addresses */ +#define ADV748X_I2C_IO 0x70 /* IO Map */ +#define ADV748X_I2C_DPLL 0x26 /* DPLL Map */ +#define ADV748X_I2C_CP 0x22 /* CP Map */ +#define ADV748X_I2C_HDMI 0x34 /* HDMI Map */ +#define ADV748X_I2C_EDID 0x36 /* EDID Map */ +#define ADV748X_I2C_REPEATER 0x32 /* HDMI RX Repeater Map */ +#define ADV748X_I2C_INFOFRAME 0x31 /* HDMI RX InfoFrame Map */ +#define ADV748X_I2C_CEC 0x41 /* CEC Map */ +#define ADV748X_I2C_SDP 0x79 /* SDP Map */ +#define ADV748X_I2C_TXB 0x48 /* CSI-TXB Map */ +#define ADV748X_I2C_TXA 0x4a /* CSI-TXA Map */ + +enum adv748x_page { + ADV748X_PAGE_IO, + ADV748X_PAGE_DPLL, + ADV748X_PAGE_CP, + ADV748X_PAGE_HDMI, + ADV748X_PAGE_EDID, + ADV748X_PAGE_REPEATER, + ADV748X_PAGE_INFOFRAME, + ADV748X_PAGE_CEC, + ADV748X_PAGE_SDP, + ADV748X_PAGE_TXB, + ADV748X_PAGE_TXA, + ADV748X_PAGE_MAX, + + /* Fake pages for register sequences */ + ADV748X_PAGE_WAIT, /* Wait x msec */ + ADV748X_PAGE_EOR, /* End Mark */ +}; + +/** + * enum adv748x_ports - Device tree port number definitions + * + * The ADV748X ports define the mapping between subdevices + * and the device tree specification + */ +enum adv748x_ports { + ADV748X_PORT_AIN0 = 0, + ADV748X_PORT_AIN1 = 1, + ADV748X_PORT_AIN2 = 2, + ADV748X_PORT_AIN3 = 3, + ADV748X_PORT_AIN4 = 4, + ADV748X_PORT_AIN5 = 5, + ADV748X_PORT_AIN6 = 6, + ADV748X_PORT_AIN7 = 7, + ADV748X_PORT_HDMI = 8, + ADV748X_PORT_TTL = 9, + ADV748X_PORT_TXA = 10, + ADV748X_PORT_TXB = 11, + ADV748X_PORT_MAX = 12, +}; + +enum adv748x_csi2_pads { + ADV748X_CSI2_SINK, + ADV748X_CSI2_SOURCE, + ADV748X_CSI2_NR_PADS, +}; + +/* CSI2 transmitters can have 2 internal connections, HDMI/AFE */ +#define ADV748X_CSI2_MAX_SUBDEVS 2 + +struct adv748x_csi2 { + struct adv748x_state *state; + struct v4l2_mbus_framefmt format; + unsigned int page; + + struct media_pad pads[ADV748X_CSI2_NR_PADS]; + struct v4l2_ctrl_handler ctrl_hdl; + struct v4l2_subdev sd; +}; + +#define notifier_to_csi2(n) container_of(n, struct adv748x_csi2, notifier) +#define adv748x_sd_to_csi2(sd) container_of(sd, struct adv748x_csi2, sd) + +enum adv748x_hdmi_pads { + ADV748X_HDMI_SINK, + ADV748X_HDMI_SOURCE, + ADV748X_HDMI_NR_PADS, +}; + +struct adv748x_hdmi { + struct media_pad pads[ADV748X_HDMI_NR_PADS]; + struct v4l2_ctrl_handler ctrl_hdl; + struct v4l2_subdev sd; + struct v4l2_mbus_framefmt format; + + struct v4l2_dv_timings timings; + struct v4l2_fract aspect_ratio; + + struct { + u8 edid[512]; + u32 present; + unsigned int blocks; + } edid; +}; + +#define adv748x_ctrl_to_hdmi(ctrl) \ + container_of(ctrl->handler, struct adv748x_hdmi, ctrl_hdl) +#define adv748x_sd_to_hdmi(sd) container_of(sd, struct adv748x_hdmi, sd) + +enum adv748x_afe_pads { + ADV748X_AFE_SINK_AIN0, + ADV748X_AFE_SINK_AIN1, + ADV748X_AFE_SINK_AIN2, + ADV748X_AFE_SINK_AIN3, + ADV748X_AFE_SINK_AIN4, + ADV748X_AFE_SINK_AIN5, + ADV748X_AFE_SINK_AIN6, + ADV748X_AFE_SINK_AIN7, + ADV748X_AFE_SOURCE, + ADV748X_AFE_NR_PADS, +}; + +struct adv748x_afe { + struct media_pad pads[ADV748X_AFE_NR_PADS]; + struct v4l2_ctrl_handler ctrl_hdl; + struct v4l2_subdev sd; + struct v4l2_mbus_framefmt format; + + bool streaming; + v4l2_std_id curr_norm; + unsigned int input; +}; + +#define adv748x_ctrl_to_afe(ctrl) \ + container_of(ctrl->handler, struct adv748x_afe, ctrl_hdl) +#define adv748x_sd_to_afe(sd) container_of(sd, struct adv748x_afe, sd) + +/** + * struct adv748x_state - State of ADV748X + * @dev: (OF) device + * @client: I2C client + * @mutex: protect global state + * + * @endpoints: parsed device node endpoints for each port + * + * @i2c_addresses I2C Page addresses + * @i2c_clients I2C clients for the page accesses + * @regmap regmap configuration pages. + * + * @hdmi: state of HDMI receiver context + * @afe: state of AFE receiver context + * @txa: state of TXA transmitter context + * @txb: state of TXB transmitter context + */ +struct adv748x_state { + struct device *dev; + struct i2c_client *client; + struct mutex mutex; + + struct device_node *endpoints[ADV748X_PORT_MAX]; + + struct i2c_client *i2c_clients[ADV748X_PAGE_MAX]; + struct regmap *regmap[ADV748X_PAGE_MAX]; + + struct adv748x_hdmi hdmi; + struct adv748x_afe afe; + struct adv748x_csi2 txa; + struct adv748x_csi2 txb; +}; + +#define adv748x_hdmi_to_state(h) container_of(h, struct adv748x_state, hdmi) +#define adv748x_afe_to_state(a) container_of(a, struct adv748x_state, afe) + +#define adv_err(a, fmt, arg...) dev_err(a->dev, fmt, ##arg) +#define adv_info(a, fmt, arg...) dev_info(a->dev, fmt, ##arg) +#define adv_dbg(a, fmt, arg...) dev_dbg(a->dev, fmt, ##arg) + +/* Register Mappings */ + +/* IO Map */ +#define ADV748X_IO_PD 0x00 /* power down controls */ +#define ADV748X_IO_PD_RX_EN BIT(6) + +#define ADV748X_IO_REG_04 0x04 +#define ADV748X_IO_REG_04_FORCE_FR BIT(0) /* Force CP free-run */ + +#define ADV748X_IO_DATAPATH 0x03 /* datapath cntrl */ +#define ADV748X_IO_DATAPATH_VFREQ_M 0x70 +#define ADV748X_IO_DATAPATH_VFREQ_SHIFT 4 + +#define ADV748X_IO_VID_STD 0x05 + +#define ADV748X_IO_10 0x10 /* io_reg_10 */ +#define ADV748X_IO_10_CSI4_EN BIT(7) +#define ADV748X_IO_10_CSI1_EN BIT(6) +#define ADV748X_IO_10_PIX_OUT_EN BIT(5) + +#define ADV748X_IO_CHIP_REV_ID_1 0xdf +#define ADV748X_IO_CHIP_REV_ID_2 0xe0 + +#define ADV748X_IO_SLAVE_ADDR_BASE 0xf2 + +/* HDMI RX Map */ +#define ADV748X_HDMI_LW1 0x07 /* line width_1 */ +#define ADV748X_HDMI_LW1_VERT_FILTER BIT(7) +#define ADV748X_HDMI_LW1_DE_REGEN BIT(5) +#define ADV748X_HDMI_LW1_WIDTH_MASK 0x1fff + +#define ADV748X_HDMI_F0H1 0x09 /* field0 height_1 */ +#define ADV748X_HDMI_F0H1_HEIGHT_MASK 0x1fff + +#define ADV748X_HDMI_F1H1 0x0b /* field1 height_1 */ +#define ADV748X_HDMI_F1H1_INTERLACED BIT(5) + +#define ADV748X_HDMI_HFRONT_PORCH 0x20 /* hsync_front_porch_1 */ +#define ADV748X_HDMI_HFRONT_PORCH_MASK 0x1fff + +#define ADV748X_HDMI_HSYNC_WIDTH 0x22 /* hsync_pulse_width_1 */ +#define ADV748X_HDMI_HSYNC_WIDTH_MASK 0x1fff + +#define ADV748X_HDMI_HBACK_PORCH 0x24 /* hsync_back_porch_1 */ +#define ADV748X_HDMI_HBACK_PORCH_MASK 0x1fff + +#define ADV748X_HDMI_VFRONT_PORCH 0x2a /* field0_vs_front_porch_1 */ +#define ADV748X_HDMI_VFRONT_PORCH_MASK 0x3fff + +#define ADV748X_HDMI_VSYNC_WIDTH 0x2e /* field0_vs_pulse_width_1 */ +#define ADV748X_HDMI_VSYNC_WIDTH_MASK 0x3fff + +#define ADV748X_HDMI_VBACK_PORCH 0x32 /* field0_vs_back_porch_1 */ +#define ADV748X_HDMI_VBACK_PORCH_MASK 0x3fff + +#define ADV748X_HDMI_TMDS_1 0x51 /* hdmi_reg_51 */ +#define ADV748X_HDMI_TMDS_2 0x52 /* hdmi_reg_52 */ + +/* HDMI RX Repeater Map */ +#define ADV748X_REPEATER_EDID_SZ 0x70 /* primary_edid_size */ +#define ADV748X_REPEATER_EDID_SZ_SHIFT 4 + +#define ADV748X_REPEATER_EDID_CTL 0x74 /* hdcp edid controls */ +#define ADV748X_REPEATER_EDID_CTL_EN BIT(0) /* man_edid_a_enable */ + +/* SDP Main Map */ +#define ADV748X_SDP_INSEL 0x00 /* user_map_rw_reg_00 */ + +#define ADV748X_SDP_VID_SEL 0x02 /* user_map_rw_reg_02 */ +#define ADV748X_SDP_VID_SEL_MASK 0xf0 +#define ADV748X_SDP_VID_SEL_SHIFT 4 + +/* Contrast - Unsigned*/ +#define ADV748X_SDP_CON 0x08 /* user_map_rw_reg_08 */ +#define ADV748X_SDP_CON_MIN 0 +#define ADV748X_SDP_CON_DEF 128 +#define ADV748X_SDP_CON_MAX 255 + +/* Brightness - Signed */ +#define ADV748X_SDP_BRI 0x0a /* user_map_rw_reg_0a */ +#define ADV748X_SDP_BRI_MIN -128 +#define ADV748X_SDP_BRI_DEF 0 +#define ADV748X_SDP_BRI_MAX 127 + +/* Hue - Signed, inverted*/ +#define ADV748X_SDP_HUE 0x0b /* user_map_rw_reg_0b */ +#define ADV748X_SDP_HUE_MIN -127 +#define ADV748X_SDP_HUE_DEF 0 +#define ADV748X_SDP_HUE_MAX 128 + +/* Test Patterns / Default Values */ +#define ADV748X_SDP_DEF 0x0c /* user_map_rw_reg_0c */ +#define ADV748X_SDP_DEF_VAL_EN BIT(0) /* Force free run mode */ +#define ADV748X_SDP_DEF_VAL_AUTO_EN BIT(1) /* Free run when no signal */ + +#define ADV748X_SDP_MAP_SEL 0x0e /* user_map_rw_reg_0e */ +#define ADV748X_SDP_MAP_SEL_RO_MAIN 1 + +/* Free run pattern select */ +#define ADV748X_SDP_FRP 0x14 +#define ADV748X_SDP_FRP_MASK GENMASK(3, 1) + +/* Saturation */ +#define ADV748X_SDP_SD_SAT_U 0xe3 /* user_map_rw_reg_e3 */ +#define ADV748X_SDP_SD_SAT_V 0xe4 /* user_map_rw_reg_e4 */ +#define ADV748X_SDP_SAT_MIN 0 +#define ADV748X_SDP_SAT_DEF 128 +#define ADV748X_SDP_SAT_MAX 255 + +/* SDP RO Main Map */ +#define ADV748X_SDP_RO_10 0x10 +#define ADV748X_SDP_RO_10_IN_LOCK BIT(0) + +/* CP Map */ +#define ADV748X_CP_PAT_GEN 0x37 /* int_pat_gen_1 */ +#define ADV748X_CP_PAT_GEN_EN BIT(7) + +/* Contrast Control - Unsigned */ +#define ADV748X_CP_CON 0x3a /* contrast_cntrl */ +#define ADV748X_CP_CON_MIN 0 /* Minimum contrast */ +#define ADV748X_CP_CON_DEF 128 /* Default */ +#define ADV748X_CP_CON_MAX 255 /* Maximum contrast */ + +/* Saturation Control - Unsigned */ +#define ADV748X_CP_SAT 0x3b /* saturation_cntrl */ +#define ADV748X_CP_SAT_MIN 0 /* Minimum saturation */ +#define ADV748X_CP_SAT_DEF 128 /* Default */ +#define ADV748X_CP_SAT_MAX 255 /* Maximum saturation */ + +/* Brightness Control - Signed */ +#define ADV748X_CP_BRI 0x3c /* brightness_cntrl */ +#define ADV748X_CP_BRI_MIN -128 /* Luma is -512d */ +#define ADV748X_CP_BRI_DEF 0 /* Luma is 0 */ +#define ADV748X_CP_BRI_MAX 127 /* Luma is 508d */ + +/* Hue Control */ +#define ADV748X_CP_HUE 0x3d /* hue_cntrl */ +#define ADV748X_CP_HUE_MIN 0 /* -90 degree */ +#define ADV748X_CP_HUE_DEF 0 /* -90 degree */ +#define ADV748X_CP_HUE_MAX 255 /* +90 degree */ + +#define ADV748X_CP_VID_ADJ 0x3e /* vid_adj_0 */ +#define ADV748X_CP_VID_ADJ_ENABLE BIT(7) /* Enable colour controls */ + +#define ADV748X_CP_DE_POS_HIGH 0x8b /* de_pos_adj_6 */ +#define ADV748X_CP_DE_POS_HIGH_SET BIT(6) +#define ADV748X_CP_DE_POS_END_LOW 0x8c /* de_pos_adj_7 */ +#define ADV748X_CP_DE_POS_START_LOW 0x8d /* de_pos_adj_8 */ + +#define ADV748X_CP_VID_ADJ_2 0x91 +#define ADV748X_CP_VID_ADJ_2_INTERLACED BIT(6) +#define ADV748X_CP_VID_ADJ_2_INTERLACED_3D BIT(4) + +#define ADV748X_CP_CLMP_POS 0xc9 /* clmp_pos_cntrl_4 */ +#define ADV748X_CP_CLMP_POS_DIS_AUTO BIT(0) /* dis_auto_param_buff */ + +/* CSI : TXA/TXB Maps */ +#define ADV748X_CSI_VC_REF 0x0d /* csi_tx_top_reg_0d */ +#define ADV748X_CSI_VC_REF_SHIFT 6 + +#define ADV748X_CSI_FS_AS_LS 0x1e /* csi_tx_top_reg_1e */ +#define ADV748X_CSI_FS_AS_LS_UNKNOWN BIT(6) /* Undocumented bit */ + +/* Register handling */ + +int adv748x_read(struct adv748x_state *state, u8 addr, u8 reg); +int adv748x_write(struct adv748x_state *state, u8 page, u8 reg, u8 value); +int adv748x_write_block(struct adv748x_state *state, int client_page, + unsigned int init_reg, const void *val, + size_t val_len); + +#define io_read(s, r) adv748x_read(s, ADV748X_PAGE_IO, r) +#define io_write(s, r, v) adv748x_write(s, ADV748X_PAGE_IO, r, v) +#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~m) | v) + +#define hdmi_read(s, r) adv748x_read(s, ADV748X_PAGE_HDMI, r) +#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, r+1)) & m) +#define hdmi_write(s, r, v) adv748x_write(s, ADV748X_PAGE_HDMI, r, v) + +#define repeater_read(s, r) adv748x_read(s, ADV748X_PAGE_REPEATER, r) +#define repeater_write(s, r, v) adv748x_write(s, ADV748X_PAGE_REPEATER, r, v) + +#define sdp_read(s, r) adv748x_read(s, ADV748X_PAGE_SDP, r) +#define sdp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_SDP, r, v) +#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~m) | v) + +#define cp_read(s, r) adv748x_read(s, ADV748X_PAGE_CP, r) +#define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v) +#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v) + +#define txa_read(s, r) adv748x_read(s, ADV748X_PAGE_TXA, r) +#define txb_read(s, r) adv748x_read(s, ADV748X_PAGE_TXB, r) + +#define tx_read(t, r) adv748x_read(t->state, t->page, r) +#define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v) + +static inline struct v4l2_subdev *adv748x_get_remote_sd(struct media_pad *pad) +{ + pad = media_entity_remote_pad(pad); + if (!pad) + return NULL; + + return media_entity_to_v4l2_subdev(pad->entity); +} + +void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state, + const struct v4l2_subdev_ops *ops, u32 function, + const char *ident); + +int adv748x_register_subdevs(struct adv748x_state *state, + struct v4l2_device *v4l2_dev); + +int adv748x_txa_power(struct adv748x_state *state, bool on); +int adv748x_txb_power(struct adv748x_state *state, bool on); + +int adv748x_afe_init(struct adv748x_afe *afe); +void adv748x_afe_cleanup(struct adv748x_afe *afe); + +int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx); +void adv748x_csi2_cleanup(struct adv748x_csi2 *tx); +int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate); + +int adv748x_hdmi_init(struct adv748x_hdmi *hdmi); +void adv748x_hdmi_cleanup(struct adv748x_hdmi *hdmi); + +#endif /* _ADV748X_H_ */ -- cgit v1.2.3 From cc0ff41b0f1e2ba7785333e86b12389be211c9a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 19 Jul 2017 16:51:01 -0400 Subject: media: adv748x: get rid of unused var drivers/media/i2c/adv748x/adv748x-csi2.c: In function 'adv748x_csi2_init_controls': drivers/media/i2c/adv748x/adv748x-csi2.c:251:20: warning: variable 'ctrl' set but not used [-Wunused-but-set-variable] struct v4l2_ctrl *ctrl; ^~~~ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv748x/adv748x-csi2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index b4fee7f52d6a..979825d4a419 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -248,12 +248,11 @@ static const struct v4l2_ctrl_ops adv748x_csi2_ctrl_ops = { static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) { - struct v4l2_ctrl *ctrl; v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1); - ctrl = v4l2_ctrl_new_std(&tx->ctrl_hdl, &adv748x_csi2_ctrl_ops, - V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); + v4l2_ctrl_new_std(&tx->ctrl_hdl, &adv748x_csi2_ctrl_ops, + V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1); tx->sd.ctrl_handler = &tx->ctrl_hdl; if (tx->ctrl_hdl.error) { -- cgit v1.2.3 From 3361d54eecccc8e0f9b9893bdca1c2b84fbe0d30 Mon Sep 17 00:00:00 2001 From: Anton Sviridenko Date: Sat, 1 Jul 2017 07:26:01 -0400 Subject: media: solo6x10: fix detection of TW2864B chips This patch enables support for non-Bluecherry labeled solo6110 based PCI cards which have 3 x TW2864B chips and one TW2865. These cards are displayed by lspci -nn as "Softlogic Co., Ltd. SOLO6110 H.264 Video encoder/decoder [9413:6110]" Bluecherry cards have 4 x TW2864A. According to datasheet register 0xFF of TW2864B chips contains value 0x6A or 0x6B depending on revision which being shifted 3 bits right gives value 0x0d. Existing version of solo6x10 fails on these cards with [276582.344942] solo6x10 0000:07:00.0: Probing Softlogic 6110 [276582.402151] solo6x10 0000:07:00.0: Could not initialize any techwell chips [276582.402781] solo6x10: probe of 0000:07:00.0 failed with error -22 Signed-off-by: Anton Sviridenko Acked-by: Andrey Utkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-tw28.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/pci/solo6x10/solo6x10-tw28.c b/drivers/media/pci/solo6x10/solo6x10-tw28.c index 1c013a03d851..7ecb725b6dd2 100644 --- a/drivers/media/pci/solo6x10/solo6x10-tw28.c +++ b/drivers/media/pci/solo6x10/solo6x10-tw28.c @@ -606,6 +606,7 @@ int solo_tw28_init(struct solo_dev *solo_dev) solo_dev->tw28_cnt++; break; case 0x0c: + case 0x0d: solo_dev->tw2864 |= 1 << i; solo_dev->tw28_cnt++; break; -- cgit v1.2.3 From 281ddc3cdc10413b98531d701ab5323c4f3ff1f4 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Mon, 3 Jul 2017 04:43:33 -0400 Subject: media: adv7180: add missing adv7180cp, adv7180st i2c device IDs Fixes a crash on Renesas R8A7793 Gose board that uses these "compatible" entries. Signed-off-by: Ulrich Hecht Tested-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7180.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 78de7ddf5081..3df28f2f9b38 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1402,6 +1402,8 @@ static int adv7180_remove(struct i2c_client *client) static const struct i2c_device_id adv7180_id[] = { { "adv7180", (kernel_ulong_t)&adv7180_info }, + { "adv7180cp", (kernel_ulong_t)&adv7180_info }, + { "adv7180st", (kernel_ulong_t)&adv7180_info }, { "adv7182", (kernel_ulong_t)&adv7182_info }, { "adv7280", (kernel_ulong_t)&adv7280_info }, { "adv7280-m", (kernel_ulong_t)&adv7280_m_info }, -- cgit v1.2.3 From d82cf24859ea781837574ae63396be968b66cf34 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 17 Jul 2017 10:29:58 -0400 Subject: media: usbvision-i2c: fix format overflow warning gcc-7 notices that we copy a fixed length string into another string of the same size, with additional characters: drivers/media/usb/usbvision/usbvision-i2c.c: In function 'usbvision_i2c_register': drivers/media/usb/usbvision/usbvision-i2c.c:190:36: error: '%d' directive writing between 1 and 11 bytes into a region of size between 0 and 47 [-Werror=format-overflow=] sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, ^~~~~~~~~~ drivers/media/usb/usbvision/usbvision-i2c.c:190:2: note: 'sprintf' output between 4 and 76 bytes into a destination of size 48 Using snprintf() makes the code more robust in general, but will still trigger a possible warning about truncation in the string. We know this won't happen as the template name is always "usbvision", so we can easily avoid the warning as well by using this as the format string directly. Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-i2c.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c index fdf6b6e285da..38749331e7df 100644 --- a/drivers/media/usb/usbvision/usbvision-i2c.c +++ b/drivers/media/usb/usbvision/usbvision-i2c.c @@ -187,8 +187,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) usbvision->i2c_adap = i2c_adap_template; - sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, - usbvision->dev->bus->busnum, usbvision->dev->devpath); + snprintf(usbvision->i2c_adap.name, sizeof(usbvision->i2c_adap.name), + "usbvision-%d-%s", + usbvision->dev->bus->busnum, usbvision->dev->devpath); PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name); usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; -- cgit v1.2.3 From 435945e08551ef05a5e01610e042bc16df0db8de Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 18 Jul 2017 09:26:00 -0400 Subject: media: platform: video-mux: convert to multiplexer framework Now that the multiplexer framework is merged, drop the temporary mmio-mux implementation from the video-mux driver and convert it to use the multiplexer API. [mchehab@s-opensource.com: fix a merge conflict at Kconfig] Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 1 + drivers/media/platform/video-mux.c | 53 +++++--------------------------------- 2 files changed, 8 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 323155d6754f..17cffff86454 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -76,6 +76,7 @@ config VIDEO_M32R_AR_M64278 config VIDEO_MUX tristate "Video Multiplexer" + select MULTIPLEXER depends on VIDEO_V4L2 && OF && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER select REGMAP help diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 665744716f73..ee89ad76bee2 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -30,7 +29,7 @@ struct video_mux { struct v4l2_subdev subdev; struct media_pad *pads; struct v4l2_mbus_framefmt *format_mbus; - struct regmap_field *field; + struct mux_control *mux; struct mutex lock; int active; }; @@ -71,7 +70,7 @@ static int video_mux_link_setup(struct media_entity *entity, } dev_dbg(sd->dev, "setting %d active\n", local->index); - ret = regmap_field_write(vmux->field, local->index); + ret = mux_control_try_select(vmux->mux, local->index); if (ret < 0) goto out; vmux->active = local->index; @@ -80,6 +79,7 @@ static int video_mux_link_setup(struct media_entity *entity, goto out; dev_dbg(sd->dev, "going inactive\n"); + mux_control_deselect(vmux->mux); vmux->active = -1; } @@ -193,46 +193,6 @@ static const struct v4l2_subdev_ops video_mux_subdev_ops = { .video = &video_mux_subdev_video_ops, }; -static int video_mux_probe_mmio_mux(struct video_mux *vmux) -{ - struct device *dev = vmux->subdev.dev; - struct of_phandle_args args; - struct reg_field field; - struct regmap *regmap; - u32 reg, mask; - int ret; - - ret = of_parse_phandle_with_args(dev->of_node, "mux-controls", - "#mux-control-cells", 0, &args); - if (ret) - return ret; - - if (!of_device_is_compatible(args.np, "mmio-mux")) - return -EINVAL; - - regmap = syscon_node_to_regmap(args.np->parent); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - ret = of_property_read_u32_index(args.np, "mux-reg-masks", - 2 * args.args[0], ®); - if (!ret) - ret = of_property_read_u32_index(args.np, "mux-reg-masks", - 2 * args.args[0] + 1, &mask); - if (ret < 0) - return ret; - - field.reg = reg; - field.msb = fls(mask) - 1; - field.lsb = ffs(mask) - 1; - - vmux->field = devm_regmap_field_alloc(dev, regmap, field); - if (IS_ERR(vmux->field)) - return PTR_ERR(vmux->field); - - return 0; -} - static int video_mux_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -270,8 +230,9 @@ static int video_mux_probe(struct platform_device *pdev) return -EINVAL; } - ret = video_mux_probe_mmio_mux(vmux); - if (ret) { + vmux->mux = devm_mux_control_get(dev, NULL); + if (IS_ERR(vmux->mux)) { + ret = PTR_ERR(vmux->mux); if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to get mux: %d\n", ret); return ret; -- cgit v1.2.3 From cd21b334943719f880e707eb91895fc916a88000 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:54 -0400 Subject: media: dvb-frontends: add ST STV0910 DVB-S/S2 demodulator frontend driver This adds a multi frontend driver for the ST STV0910 DVB-S/S2 demodulator frontends. The driver code originates from the Digital Devices' dddvb vendor driver package as of version 0.9.29, and has been cleaned up from core API usage which isn't supported yet in the kernel, and additionally all obvious style issues have been resolved. All camel case and allcaps have been converted to kernel_case and lowercase. Patches have been sent to the vendor package maintainers to fix this aswell. Signal statistics acquisition has been refactored to comply with standards. Permission to reuse and mainline the driver code was formally granted by Ralph Metzler . Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 9 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/stv0910.c | 1702 ++++++++++ drivers/media/dvb-frontends/stv0910.h | 32 + drivers/media/dvb-frontends/stv0910_regs.h | 4759 ++++++++++++++++++++++++++++ 5 files changed, 6503 insertions(+) create mode 100644 drivers/media/dvb-frontends/stv0910.c create mode 100644 drivers/media/dvb-frontends/stv0910.h create mode 100644 drivers/media/dvb-frontends/stv0910_regs.h (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 3a260b82b3e8..773de5e264e3 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -28,6 +28,15 @@ config DVB_STV090x DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators. Say Y when you want to support these frontends. +config DVB_STV0910 + tristate "STV0910 based" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + ST STV0910 DVB-S/S2 demodulator driver. + + Say Y when you want to support these frontends. + config DVB_STV6110x tristate "STV6110/(A) based tuners" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 3fccaf34ef52..c302b2d07499 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o obj-$(CONFIG_DVB_CXD2841ER) += cxd2841er.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o +obj-$(CONFIG_DVB_STV0910) += stv0910.o obj-$(CONFIG_DVB_SI2165) += si2165.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_SP2) += sp2.o diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c new file mode 100644 index 000000000000..9dfcaf5e067f --- /dev/null +++ b/drivers/media/dvb-frontends/stv0910.c @@ -0,0 +1,1702 @@ +/* + * Driver for the ST STV0910 DVB-S/S2 demodulator. + * + * Copyright (C) 2014-2015 Ralph Metzler + * Marcus Metzler + * developed for Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvb_math.h" +#include "dvb_frontend.h" +#include "stv0910.h" +#include "stv0910_regs.h" + +#define EXT_CLOCK 30000000 +#define TUNING_DELAY 200 +#define BER_SRC_S 0x20 +#define BER_SRC_S2 0x20 + +LIST_HEAD(stvlist); + +enum receive_mode { RCVMODE_NONE, RCVMODE_DVBS, RCVMODE_DVBS2, RCVMODE_AUTO }; + +enum dvbs2_fectype { DVBS2_64K, DVBS2_16K }; + +enum dvbs2_mod_cod { + DVBS2_DUMMY_PLF, DVBS2_QPSK_1_4, DVBS2_QPSK_1_3, DVBS2_QPSK_2_5, + DVBS2_QPSK_1_2, DVBS2_QPSK_3_5, DVBS2_QPSK_2_3, DVBS2_QPSK_3_4, + DVBS2_QPSK_4_5, DVBS2_QPSK_5_6, DVBS2_QPSK_8_9, DVBS2_QPSK_9_10, + DVBS2_8PSK_3_5, DVBS2_8PSK_2_3, DVBS2_8PSK_3_4, DVBS2_8PSK_5_6, + DVBS2_8PSK_8_9, DVBS2_8PSK_9_10, DVBS2_16APSK_2_3, DVBS2_16APSK_3_4, + DVBS2_16APSK_4_5, DVBS2_16APSK_5_6, DVBS2_16APSK_8_9, DVBS2_16APSK_9_10, + DVBS2_32APSK_3_4, DVBS2_32APSK_4_5, DVBS2_32APSK_5_6, DVBS2_32APSK_8_9, + DVBS2_32APSK_9_10 +}; + +enum fe_stv0910_mod_cod { + FE_DUMMY_PLF, FE_QPSK_14, FE_QPSK_13, FE_QPSK_25, + FE_QPSK_12, FE_QPSK_35, FE_QPSK_23, FE_QPSK_34, + FE_QPSK_45, FE_QPSK_56, FE_QPSK_89, FE_QPSK_910, + FE_8PSK_35, FE_8PSK_23, FE_8PSK_34, FE_8PSK_56, + FE_8PSK_89, FE_8PSK_910, FE_16APSK_23, FE_16APSK_34, + FE_16APSK_45, FE_16APSK_56, FE_16APSK_89, FE_16APSK_910, + FE_32APSK_34, FE_32APSK_45, FE_32APSK_56, FE_32APSK_89, + FE_32APSK_910 +}; + +enum fe_stv0910_roll_off { FE_SAT_35, FE_SAT_25, FE_SAT_20, FE_SAT_15 }; + +static inline u32 muldiv32(u32 a, u32 b, u32 c) +{ + u64 tmp64; + + tmp64 = (u64)a * (u64)b; + do_div(tmp64, c); + + return (u32) tmp64; +} + +struct stv_base { + struct list_head stvlist; + + u8 adr; + struct i2c_adapter *i2c; + struct mutex i2c_lock; + struct mutex reg_lock; + int count; + + u32 extclk; + u32 mclk; +}; + +struct stv { + struct stv_base *base; + struct dvb_frontend fe; + int nr; + u16 regoff; + u8 i2crpt; + u8 tscfgh; + u8 tsgeneral; + u8 tsspeed; + u8 single; + unsigned long tune_time; + + s32 search_range; + u32 started; + u32 demod_lock_time; + enum receive_mode receive_mode; + u32 demod_timeout; + u32 fec_timeout; + u32 first_time_lock; + u8 demod_bits; + u32 symbol_rate; + + u8 last_viterbi_rate; + enum fe_code_rate puncture_rate; + enum fe_stv0910_mod_cod mod_cod; + enum dvbs2_fectype fectype; + u32 pilots; + enum fe_stv0910_roll_off feroll_off; + + int is_standard_broadcast; + int is_vcm; + + u32 last_bernumerator; + u32 last_berdenominator; + u8 berscale; + + u8 vth[6]; +}; + +struct sinit_table { + u16 address; + u8 data; +}; + +struct slookup { + s16 value; + u16 reg_value; +}; + +static inline int i2c_write(struct i2c_adapter *adap, u8 adr, + u8 *data, int len) +{ + struct i2c_msg msg = {.addr = adr, .flags = 0, + .buf = data, .len = len}; + + if (i2c_transfer(adap, &msg, 1) != 1) { + dev_warn(&adap->dev, "i2c write error ([%02x] %04x: %02x)\n", + adr, (data[0] << 8) | data[1], + (len > 2 ? data[2] : 0)); + return -EREMOTEIO; + } + return 0; +} + +static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val) +{ + u8 msg[3] = {reg >> 8, reg & 0xff, val}; + + return i2c_write(adap, adr, msg, 3); +} + +static int write_reg(struct stv *state, u16 reg, u8 val) +{ + return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val); +} + +static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, + u16 reg, u8 *val, int count) +{ + u8 msg[2] = {reg >> 8, reg & 0xff}; + struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, + .buf = msg, .len = 2}, + {.addr = adr, .flags = I2C_M_RD, + .buf = val, .len = count } }; + + if (i2c_transfer(adapter, msgs, 2) != 2) { + dev_warn(&adapter->dev, "i2c read error ([%02x] %04x)\n", + adr, reg); + return -EREMOTEIO; + } + return 0; +} + +static int read_reg(struct stv *state, u16 reg, u8 *val) +{ + return i2c_read_regs16(state->base->i2c, state->base->adr, + reg, val, 1); +} + +static int read_regs(struct stv *state, u16 reg, u8 *val, int len) +{ + return i2c_read_regs16(state->base->i2c, state->base->adr, + reg, val, len); +} + +static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val) +{ + int status; + u8 tmp; + + mutex_lock(&state->base->reg_lock); + status = read_reg(state, reg, &tmp); + if (!status) + status = write_reg(state, reg, (tmp & ~mask) | (val & mask)); + mutex_unlock(&state->base->reg_lock); + return status; +} + +struct slookup s1_sn_lookup[] = { + { 0, 9242 }, /*C/N= 0dB*/ + { 5, 9105 }, /*C/N=0.5dB*/ + { 10, 8950 }, /*C/N=1.0dB*/ + { 15, 8780 }, /*C/N=1.5dB*/ + { 20, 8566 }, /*C/N=2.0dB*/ + { 25, 8366 }, /*C/N=2.5dB*/ + { 30, 8146 }, /*C/N=3.0dB*/ + { 35, 7908 }, /*C/N=3.5dB*/ + { 40, 7666 }, /*C/N=4.0dB*/ + { 45, 7405 }, /*C/N=4.5dB*/ + { 50, 7136 }, /*C/N=5.0dB*/ + { 55, 6861 }, /*C/N=5.5dB*/ + { 60, 6576 }, /*C/N=6.0dB*/ + { 65, 6330 }, /*C/N=6.5dB*/ + { 70, 6048 }, /*C/N=7.0dB*/ + { 75, 5768 }, /*C/N=7.5dB*/ + { 80, 5492 }, /*C/N=8.0dB*/ + { 85, 5224 }, /*C/N=8.5dB*/ + { 90, 4959 }, /*C/N=9.0dB*/ + { 95, 4709 }, /*C/N=9.5dB*/ + { 100, 4467 }, /*C/N=10.0dB*/ + { 105, 4236 }, /*C/N=10.5dB*/ + { 110, 4013 }, /*C/N=11.0dB*/ + { 115, 3800 }, /*C/N=11.5dB*/ + { 120, 3598 }, /*C/N=12.0dB*/ + { 125, 3406 }, /*C/N=12.5dB*/ + { 130, 3225 }, /*C/N=13.0dB*/ + { 135, 3052 }, /*C/N=13.5dB*/ + { 140, 2889 }, /*C/N=14.0dB*/ + { 145, 2733 }, /*C/N=14.5dB*/ + { 150, 2587 }, /*C/N=15.0dB*/ + { 160, 2318 }, /*C/N=16.0dB*/ + { 170, 2077 }, /*C/N=17.0dB*/ + { 180, 1862 }, /*C/N=18.0dB*/ + { 190, 1670 }, /*C/N=19.0dB*/ + { 200, 1499 }, /*C/N=20.0dB*/ + { 210, 1347 }, /*C/N=21.0dB*/ + { 220, 1213 }, /*C/N=22.0dB*/ + { 230, 1095 }, /*C/N=23.0dB*/ + { 240, 992 }, /*C/N=24.0dB*/ + { 250, 900 }, /*C/N=25.0dB*/ + { 260, 826 }, /*C/N=26.0dB*/ + { 270, 758 }, /*C/N=27.0dB*/ + { 280, 702 }, /*C/N=28.0dB*/ + { 290, 653 }, /*C/N=29.0dB*/ + { 300, 613 }, /*C/N=30.0dB*/ + { 310, 579 }, /*C/N=31.0dB*/ + { 320, 550 }, /*C/N=32.0dB*/ + { 330, 526 }, /*C/N=33.0dB*/ + { 350, 490 }, /*C/N=33.0dB*/ + { 400, 445 }, /*C/N=40.0dB*/ + { 450, 430 }, /*C/N=45.0dB*/ + { 500, 426 }, /*C/N=50.0dB*/ + { 510, 425 } /*C/N=51.0dB*/ +}; + +struct slookup s2_sn_lookup[] = { + { -30, 13950 }, /*C/N=-2.5dB*/ + { -25, 13580 }, /*C/N=-2.5dB*/ + { -20, 13150 }, /*C/N=-2.0dB*/ + { -15, 12760 }, /*C/N=-1.5dB*/ + { -10, 12345 }, /*C/N=-1.0dB*/ + { -5, 11900 }, /*C/N=-0.5dB*/ + { 0, 11520 }, /*C/N= 0dB*/ + { 5, 11080 }, /*C/N= 0.5dB*/ + { 10, 10630 }, /*C/N= 1.0dB*/ + { 15, 10210 }, /*C/N= 1.5dB*/ + { 20, 9790 }, /*C/N= 2.0dB*/ + { 25, 9390 }, /*C/N= 2.5dB*/ + { 30, 8970 }, /*C/N= 3.0dB*/ + { 35, 8575 }, /*C/N= 3.5dB*/ + { 40, 8180 }, /*C/N= 4.0dB*/ + { 45, 7800 }, /*C/N= 4.5dB*/ + { 50, 7430 }, /*C/N= 5.0dB*/ + { 55, 7080 }, /*C/N= 5.5dB*/ + { 60, 6720 }, /*C/N= 6.0dB*/ + { 65, 6320 }, /*C/N= 6.5dB*/ + { 70, 6060 }, /*C/N= 7.0dB*/ + { 75, 5760 }, /*C/N= 7.5dB*/ + { 80, 5480 }, /*C/N= 8.0dB*/ + { 85, 5200 }, /*C/N= 8.5dB*/ + { 90, 4930 }, /*C/N= 9.0dB*/ + { 95, 4680 }, /*C/N= 9.5dB*/ + { 100, 4425 }, /*C/N=10.0dB*/ + { 105, 4210 }, /*C/N=10.5dB*/ + { 110, 3980 }, /*C/N=11.0dB*/ + { 115, 3765 }, /*C/N=11.5dB*/ + { 120, 3570 }, /*C/N=12.0dB*/ + { 125, 3315 }, /*C/N=12.5dB*/ + { 130, 3140 }, /*C/N=13.0dB*/ + { 135, 2980 }, /*C/N=13.5dB*/ + { 140, 2820 }, /*C/N=14.0dB*/ + { 145, 2670 }, /*C/N=14.5dB*/ + { 150, 2535 }, /*C/N=15.0dB*/ + { 160, 2270 }, /*C/N=16.0dB*/ + { 170, 2035 }, /*C/N=17.0dB*/ + { 180, 1825 }, /*C/N=18.0dB*/ + { 190, 1650 }, /*C/N=19.0dB*/ + { 200, 1485 }, /*C/N=20.0dB*/ + { 210, 1340 }, /*C/N=21.0dB*/ + { 220, 1212 }, /*C/N=22.0dB*/ + { 230, 1100 }, /*C/N=23.0dB*/ + { 240, 1000 }, /*C/N=24.0dB*/ + { 250, 910 }, /*C/N=25.0dB*/ + { 260, 836 }, /*C/N=26.0dB*/ + { 270, 772 }, /*C/N=27.0dB*/ + { 280, 718 }, /*C/N=28.0dB*/ + { 290, 671 }, /*C/N=29.0dB*/ + { 300, 635 }, /*C/N=30.0dB*/ + { 310, 602 }, /*C/N=31.0dB*/ + { 320, 575 }, /*C/N=32.0dB*/ + { 330, 550 }, /*C/N=33.0dB*/ + { 350, 517 }, /*C/N=35.0dB*/ + { 400, 480 }, /*C/N=40.0dB*/ + { 450, 466 }, /*C/N=45.0dB*/ + { 500, 464 }, /*C/N=50.0dB*/ + { 510, 463 }, /*C/N=51.0dB*/ +}; + +/********************************************************************* + * Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame + *********************************************************************/ +static u8 s2car_loop[] = { + /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff + * 20MPon 20MPoff 30MPon 30MPoff + */ + + /* FE_QPSK_14 */ + 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x2A, 0x1C, 0x3A, 0x3B, + /* FE_QPSK_13 */ + 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, + /* FE_QPSK_25 */ + 0x1C, 0x3C, 0x1B, 0x3C, 0x3A, 0x1C, 0x3A, 0x3B, 0x3A, 0x2B, + /* FE_QPSK_12 */ + 0x0C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, + /* FE_QPSK_35 */ + 0x1C, 0x1C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, + /* FE_QPSK_23 */ + 0x2C, 0x2C, 0x2B, 0x1C, 0x0B, 0x2C, 0x0B, 0x0C, 0x2A, 0x2B, + /* FE_QPSK_34 */ + 0x3C, 0x2C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, + /* FE_QPSK_45 */ + 0x0D, 0x3C, 0x3B, 0x2C, 0x1B, 0x1C, 0x1B, 0x3B, 0x3A, 0x1B, + /* FE_QPSK_56 */ + 0x1D, 0x3C, 0x0C, 0x2C, 0x2B, 0x1C, 0x1B, 0x3B, 0x0B, 0x1B, + /* FE_QPSK_89 */ + 0x3D, 0x0D, 0x0C, 0x2C, 0x2B, 0x0C, 0x2B, 0x2B, 0x0B, 0x0B, + /* FE_QPSK_910 */ + 0x1E, 0x0D, 0x1C, 0x2C, 0x3B, 0x0C, 0x2B, 0x2B, 0x1B, 0x0B, + /* FE_8PSK_35 */ + 0x28, 0x09, 0x28, 0x09, 0x28, 0x09, 0x28, 0x08, 0x28, 0x27, + /* FE_8PSK_23 */ + 0x19, 0x29, 0x19, 0x29, 0x19, 0x29, 0x38, 0x19, 0x28, 0x09, + /* FE_8PSK_34 */ + 0x1A, 0x0B, 0x1A, 0x3A, 0x0A, 0x2A, 0x39, 0x2A, 0x39, 0x1A, + /* FE_8PSK_56 */ + 0x2B, 0x2B, 0x1B, 0x1B, 0x0B, 0x1B, 0x1A, 0x0B, 0x1A, 0x1A, + /* FE_8PSK_89 */ + 0x0C, 0x0C, 0x3B, 0x3B, 0x1B, 0x1B, 0x2A, 0x0B, 0x2A, 0x2A, + /* FE_8PSK_910 */ + 0x0C, 0x1C, 0x0C, 0x3B, 0x2B, 0x1B, 0x3A, 0x0B, 0x2A, 0x2A, + + /********************************************************************** + * Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame + **********************************************************************/ + + /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon + * 20MPoff 30MPon 30MPoff + */ + + /* FE_16APSK_23 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x0A, 0x39, 0x0A, 0x29, 0x0A, + /* FE_16APSK_34 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0A, 0x2A, 0x0A, 0x1A, 0x0A, + /* FE_16APSK_45 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, + /* FE_16APSK_56 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x1B, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A, + /* FE_16APSK_89 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, + /* FE_16APSK_910 */ + 0x0A, 0x0A, 0x0A, 0x0A, 0x2B, 0x0A, 0x0B, 0x0A, 0x3A, 0x0A, + /* FE_32APSK_34 */ + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + /* FE_32APSK_45 */ + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + /* FE_32APSK_56 */ + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + /* FE_32APSK_89 */ + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + /* FE_32APSK_910 */ + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, +}; + +static u8 get_optim_cloop(struct stv *state, + enum fe_stv0910_mod_cod mod_cod, u32 pilots) +{ + int i = 0; + + if (mod_cod >= FE_32APSK_910) + i = ((int)FE_32APSK_910 - (int)FE_QPSK_14) * 10; + else if (mod_cod >= FE_QPSK_14) + i = ((int)mod_cod - (int)FE_QPSK_14) * 10; + + if (state->symbol_rate <= 3000000) + i += 0; + else if (state->symbol_rate <= 7000000) + i += 2; + else if (state->symbol_rate <= 15000000) + i += 4; + else if (state->symbol_rate <= 25000000) + i += 6; + else + i += 8; + + if (!pilots) + i += 1; + + return s2car_loop[i]; +} + +static int get_cur_symbol_rate(struct stv *state, u32 *p_symbol_rate) +{ + int status = 0; + u8 symb_freq0; + u8 symb_freq1; + u8 symb_freq2; + u8 symb_freq3; + u8 tim_offs0; + u8 tim_offs1; + u8 tim_offs2; + u32 symbol_rate; + s32 timing_offset; + + *p_symbol_rate = 0; + if (!state->started) + return status; + + read_reg(state, RSTV0910_P2_SFR3 + state->regoff, &symb_freq3); + read_reg(state, RSTV0910_P2_SFR2 + state->regoff, &symb_freq2); + read_reg(state, RSTV0910_P2_SFR1 + state->regoff, &symb_freq1); + read_reg(state, RSTV0910_P2_SFR0 + state->regoff, &symb_freq0); + read_reg(state, RSTV0910_P2_TMGREG2 + state->regoff, &tim_offs2); + read_reg(state, RSTV0910_P2_TMGREG1 + state->regoff, &tim_offs1); + read_reg(state, RSTV0910_P2_TMGREG0 + state->regoff, &tim_offs0); + + symbol_rate = ((u32) symb_freq3 << 24) | ((u32) symb_freq2 << 16) | + ((u32) symb_freq1 << 8) | (u32) symb_freq0; + timing_offset = ((u32) tim_offs2 << 16) | ((u32) tim_offs1 << 8) | + (u32) tim_offs0; + + if ((timing_offset & (1<<23)) != 0) + timing_offset |= 0xFF000000; /* Sign extent */ + + symbol_rate = (u32) (((u64) symbol_rate * state->base->mclk) >> 32); + timing_offset = (s32) (((s64) symbol_rate * (s64) timing_offset) >> 29); + + *p_symbol_rate = symbol_rate + timing_offset; + + return 0; +} + +static int get_signal_parameters(struct stv *state) +{ + u8 tmp; + + if (!state->started) + return -EINVAL; + + if (state->receive_mode == RCVMODE_DVBS2) { + read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); + state->mod_cod = (enum fe_stv0910_mod_cod) ((tmp & 0x7c) >> 2); + state->pilots = (tmp & 0x01) != 0; + state->fectype = (enum dvbs2_fectype) ((tmp & 0x02) >> 1); + + } else if (state->receive_mode == RCVMODE_DVBS) { + read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); + state->puncture_rate = FEC_NONE; + switch (tmp & 0x1F) { + case 0x0d: + state->puncture_rate = FEC_1_2; + break; + case 0x12: + state->puncture_rate = FEC_2_3; + break; + case 0x15: + state->puncture_rate = FEC_3_4; + break; + case 0x18: + state->puncture_rate = FEC_5_6; + break; + case 0x1a: + state->puncture_rate = FEC_7_8; + break; + } + state->is_vcm = 0; + state->is_standard_broadcast = 1; + state->feroll_off = FE_SAT_35; + } + return 0; +} + +static int tracking_optimization(struct stv *state) +{ + u32 symbol_rate = 0; + u8 tmp; + + get_cur_symbol_rate(state, &symbol_rate); + read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp); + tmp &= ~0xC0; + + switch (state->receive_mode) { + case RCVMODE_DVBS: + tmp |= 0x40; + break; + case RCVMODE_DVBS2: + tmp |= 0x80; + break; + default: + tmp |= 0xC0; + break; + } + write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp); + + if (state->receive_mode == RCVMODE_DVBS2) { + /* Disable Reed-Solomon */ + write_shared_reg(state, + RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, + 0x03); + + if (state->fectype == DVBS2_64K) { + u8 aclc = get_optim_cloop(state, state->mod_cod, + state->pilots); + + if (state->mod_cod <= FE_QPSK_910) { + write_reg(state, RSTV0910_P2_ACLC2S2Q + + state->regoff, aclc); + } else if (state->mod_cod <= FE_8PSK_910) { + write_reg(state, RSTV0910_P2_ACLC2S2Q + + state->regoff, 0x2a); + write_reg(state, RSTV0910_P2_ACLC2S28 + + state->regoff, aclc); + } else if (state->mod_cod <= FE_16APSK_910) { + write_reg(state, RSTV0910_P2_ACLC2S2Q + + state->regoff, 0x2a); + write_reg(state, RSTV0910_P2_ACLC2S216A + + state->regoff, aclc); + } else if (state->mod_cod <= FE_32APSK_910) { + write_reg(state, RSTV0910_P2_ACLC2S2Q + + state->regoff, 0x2a); + write_reg(state, RSTV0910_P2_ACLC2S232A + + state->regoff, aclc); + } + } + } + return 0; +} + +static s32 table_lookup(struct slookup *table, + int table_size, u16 reg_value) +{ + s32 value; + int imin = 0; + int imax = table_size - 1; + int i; + s32 reg_diff; + + /* Assumes Table[0].RegValue > Table[imax].RegValue */ + if (reg_value >= table[0].reg_value) + value = table[0].value; + else if (reg_value <= table[imax].reg_value) + value = table[imax].value; + else { + while (imax-imin > 1) { + i = (imax + imin) / 2; + if ((table[imin].reg_value >= reg_value) && + (reg_value >= table[i].reg_value)) + imax = i; + else + imin = i; + } + + reg_diff = table[imax].reg_value - table[imin].reg_value; + value = table[imin].value; + if (reg_diff != 0) + value += ((s32)(reg_value - table[imin].reg_value) * + (s32)(table[imax].value + - table[imin].value)) + / (reg_diff); + } + + return value; +} + +static int get_signal_to_noise(struct stv *state, s32 *signal_to_noise) +{ + u8 data0; + u8 data1; + u16 data; + int n_lookup; + struct slookup *lookup; + + *signal_to_noise = 0; + + if (!state->started) + return -EINVAL; + + if (state->receive_mode == RCVMODE_DVBS2) { + read_reg(state, RSTV0910_P2_NNOSPLHT1 + state->regoff, + &data1); + read_reg(state, RSTV0910_P2_NNOSPLHT0 + state->regoff, + &data0); + n_lookup = ARRAY_SIZE(s2_sn_lookup); + lookup = s2_sn_lookup; + } else { + read_reg(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, + &data1); + read_reg(state, RSTV0910_P2_NNOSDATAT0 + state->regoff, + &data0); + n_lookup = ARRAY_SIZE(s1_sn_lookup); + lookup = s1_sn_lookup; + } + data = (((u16)data1) << 8) | (u16) data0; + *signal_to_noise = table_lookup(lookup, n_lookup, data); + return 0; +} + +static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, + u32 *berdenominator) +{ + u8 regs[3]; + + int status = read_regs(state, + RSTV0910_P2_ERRCNT12 + state->regoff, + regs, 3); + + if (status) + return -EINVAL; + + if ((regs[0] & 0x80) == 0) { + state->last_berdenominator = 1 << ((state->berscale * 2) + + 10 + 3); + state->last_bernumerator = ((u32) (regs[0] & 0x7F) << 16) | + ((u32) regs[1] << 8) | regs[2]; + if (state->last_bernumerator < 256 && state->berscale < 6) { + state->berscale += 1; + status = write_reg(state, RSTV0910_P2_ERRCTRL1 + + state->regoff, + 0x20 | state->berscale); + } else if (state->last_bernumerator > 1024 && + state->berscale > 2) { + state->berscale -= 1; + status = write_reg(state, RSTV0910_P2_ERRCTRL1 + + state->regoff, 0x20 | + state->berscale); + } + } + *bernumerator = state->last_bernumerator; + *berdenominator = state->last_berdenominator; + return 0; +} + +static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) +{ + static u32 nbch[][2] = { + {16200, 3240}, /* QPSK_1_4, */ + {21600, 5400}, /* QPSK_1_3, */ + {25920, 6480}, /* QPSK_2_5, */ + {32400, 7200}, /* QPSK_1_2, */ + {38880, 9720}, /* QPSK_3_5, */ + {43200, 10800}, /* QPSK_2_3, */ + {48600, 11880}, /* QPSK_3_4, */ + {51840, 12600}, /* QPSK_4_5, */ + {54000, 13320}, /* QPSK_5_6, */ + {57600, 14400}, /* QPSK_8_9, */ + {58320, 16000}, /* QPSK_9_10, */ + {43200, 9720}, /* 8PSK_3_5, */ + {48600, 10800}, /* 8PSK_2_3, */ + {51840, 11880}, /* 8PSK_3_4, */ + {54000, 13320}, /* 8PSK_5_6, */ + {57600, 14400}, /* 8PSK_8_9, */ + {58320, 16000}, /* 8PSK_9_10, */ + {43200, 10800}, /* 16APSK_2_3, */ + {48600, 11880}, /* 16APSK_3_4, */ + {51840, 12600}, /* 16APSK_4_5, */ + {54000, 13320}, /* 16APSK_5_6, */ + {57600, 14400}, /* 16APSK_8_9, */ + {58320, 16000}, /* 16APSK_9_10 */ + {48600, 11880}, /* 32APSK_3_4, */ + {51840, 12600}, /* 32APSK_4_5, */ + {54000, 13320}, /* 32APSK_5_6, */ + {57600, 14400}, /* 32APSK_8_9, */ + {58320, 16000}, /* 32APSK_9_10 */ + }; + + if (mod_cod >= DVBS2_QPSK_1_4 && + mod_cod <= DVBS2_32APSK_9_10 && fectype <= DVBS2_16K) + return nbch[fectype][mod_cod]; + return 64800; +} + +static int get_bit_error_rate_s2(struct stv *state, u32 *bernumerator, + u32 *berdenominator) +{ + u8 regs[3]; + + int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, + regs, 3); + + if (status) + return -EINVAL; + + if ((regs[0] & 0x80) == 0) { + state->last_berdenominator = + dvbs2_nbch((enum dvbs2_mod_cod) state->mod_cod, + state->fectype) << + (state->berscale * 2); + state->last_bernumerator = (((u32) regs[0] & 0x7F) << 16) | + ((u32) regs[1] << 8) | regs[2]; + if (state->last_bernumerator < 256 && state->berscale < 6) { + state->berscale += 1; + write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, + 0x20 | state->berscale); + } else if (state->last_bernumerator > 1024 && + state->berscale > 2) { + state->berscale -= 1; + write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, + 0x20 | state->berscale); + } + } + *bernumerator = state->last_bernumerator; + *berdenominator = state->last_berdenominator; + return status; +} + +static int get_bit_error_rate(struct stv *state, u32 *bernumerator, + u32 *berdenominator) +{ + *bernumerator = 0; + *berdenominator = 1; + + switch (state->receive_mode) { + case RCVMODE_DVBS: + return get_bit_error_rate_s(state, + bernumerator, berdenominator); + case RCVMODE_DVBS2: + return get_bit_error_rate_s2(state, + bernumerator, berdenominator); + default: + break; + } + return 0; +} + +static int set_mclock(struct stv *state, u32 master_clock) +{ + u32 idf = 1; + u32 odf = 4; + u32 quartz = state->base->extclk / 1000000; + u32 fphi = master_clock / 1000000; + u32 ndiv = (fphi * odf * idf) / quartz; + u32 cp = 7; + u32 fvco; + + if (ndiv >= 7 && ndiv <= 71) + cp = 7; + else if (ndiv >= 72 && ndiv <= 79) + cp = 8; + else if (ndiv >= 80 && ndiv <= 87) + cp = 9; + else if (ndiv >= 88 && ndiv <= 95) + cp = 10; + else if (ndiv >= 96 && ndiv <= 103) + cp = 11; + else if (ndiv >= 104 && ndiv <= 111) + cp = 12; + else if (ndiv >= 112 && ndiv <= 119) + cp = 13; + else if (ndiv >= 120 && ndiv <= 127) + cp = 14; + else if (ndiv >= 128 && ndiv <= 135) + cp = 15; + else if (ndiv >= 136 && ndiv <= 143) + cp = 16; + else if (ndiv >= 144 && ndiv <= 151) + cp = 17; + else if (ndiv >= 152 && ndiv <= 159) + cp = 18; + else if (ndiv >= 160 && ndiv <= 167) + cp = 19; + else if (ndiv >= 168 && ndiv <= 175) + cp = 20; + else if (ndiv >= 176 && ndiv <= 183) + cp = 21; + else if (ndiv >= 184 && ndiv <= 191) + cp = 22; + else if (ndiv >= 192 && ndiv <= 199) + cp = 23; + else if (ndiv >= 200 && ndiv <= 207) + cp = 24; + else if (ndiv >= 208 && ndiv <= 215) + cp = 25; + else if (ndiv >= 216 && ndiv <= 223) + cp = 26; + else if (ndiv >= 224 && ndiv <= 225) + cp = 27; + + write_reg(state, RSTV0910_NCOARSE, (cp << 3) | idf); + write_reg(state, RSTV0910_NCOARSE2, odf); + write_reg(state, RSTV0910_NCOARSE1, ndiv); + + fvco = (quartz * 2 * ndiv) / idf; + state->base->mclk = fvco / (2 * odf) * 1000000; + + return 0; +} + +static int stop(struct stv *state) +{ + if (state->started) { + u8 tmp; + + write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, + state->tscfgh | 0x01); + read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); + tmp &= ~0x01; /*release reset DVBS2 packet delin*/ + write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); + /* Blind optim*/ + write_reg(state, RSTV0910_P2_AGC2O + state->regoff, 0x5B); + /* Stop the demod */ + write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5c); + state->started = 0; + } + state->receive_mode = RCVMODE_NONE; + return 0; +} + +static int init_search_param(struct stv *state) +{ + u8 tmp; + + read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); + tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS + write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp); + tmp &= ~0x02; // frame mode = 0 + write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp); + + write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0); + write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00); + + read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp); + tmp &= ~0x01; // nosync = 0, in case next signal is standard TS + write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp); + tmp &= ~0x04; // embindvb = 0 + write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp); + tmp &= ~0x80; // syncbyte = 0 + write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp); + tmp &= ~0x08; // token = 0 + write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp); + tmp &= ~0x30; // hysteresis threshold = 0 + write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp); + + read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp); + tmp = (tmp & ~0x30) | 0x10; // isi obs mode = 1, observe min ISI + write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp); + + return 0; +} + +static int enable_puncture_rate(struct stv *state, enum fe_code_rate rate) +{ + switch (rate) { + case FEC_1_2: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x01); + case FEC_2_3: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x02); + case FEC_3_4: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x04); + case FEC_5_6: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x08); + case FEC_7_8: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x20); + case FEC_NONE: + default: + return write_reg(state, + RSTV0910_P2_PRVIT + state->regoff, 0x2f); + } +} + +static int set_vth_default(struct stv *state) +{ + state->vth[0] = 0xd7; + state->vth[1] = 0x85; + state->vth[2] = 0x58; + state->vth[3] = 0x3a; + state->vth[4] = 0x34; + state->vth[5] = 0x28; + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->vth[0]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->vth[1]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->vth[2]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->vth[3]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->vth[4]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->vth[5]); + return 0; +} + +static int set_vth(struct stv *state) +{ + static struct slookup vthlookup_table[] = { + {250, 8780}, /*C/N=1.5dB*/ + {100, 7405}, /*C/N=4.5dB*/ + {40, 6330}, /*C/N=6.5dB*/ + {12, 5224}, /*C/N=8.5dB*/ + {5, 4236} /*C/N=10.5dB*/ + }; + + int i; + u8 tmp[2]; + int status = read_regs(state, + RSTV0910_P2_NNOSDATAT1 + state->regoff, + tmp, 2); + u16 reg_value = (tmp[0] << 8) | tmp[1]; + s32 vth = table_lookup(vthlookup_table, ARRAY_SIZE(vthlookup_table), + reg_value); + + for (i = 0; i < 6; i += 1) + if (state->vth[i] > vth) + state->vth[i] = vth; + + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->vth[0]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->vth[1]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->vth[2]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->vth[3]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->vth[4]); + write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->vth[5]); + return status; +} + +static int start(struct stv *state, struct dtv_frontend_properties *p) +{ + s32 freq; + u8 reg_dmdcfgmd; + u16 symb; + + if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) + return -EINVAL; + + state->receive_mode = RCVMODE_NONE; + state->demod_lock_time = 0; + + /* Demod Stop */ + if (state->started) + write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C); + + init_search_param(state); + + if (p->symbol_rate <= 1000000) { /* SR <=1Msps */ + state->demod_timeout = 3000; + state->fec_timeout = 2000; + } else if (p->symbol_rate <= 2000000) { /* 1Msps < SR <=2Msps */ + state->demod_timeout = 2500; + state->fec_timeout = 1300; + } else if (p->symbol_rate <= 5000000) { /* 2Msps< SR <=5Msps */ + state->demod_timeout = 1000; + state->fec_timeout = 650; + } else if (p->symbol_rate <= 10000000) { /* 5Msps< SR <=10Msps */ + state->demod_timeout = 700; + state->fec_timeout = 350; + } else if (p->symbol_rate < 20000000) { /* 10Msps< SR <=20Msps */ + state->demod_timeout = 400; + state->fec_timeout = 200; + } else { /* SR >=20Msps */ + state->demod_timeout = 300; + state->fec_timeout = 200; + } + + /* Set the Init Symbol rate */ + symb = muldiv32(p->symbol_rate, 65536, state->base->mclk); + write_reg(state, RSTV0910_P2_SFRINIT1 + state->regoff, + ((symb >> 8) & 0x7F)); + write_reg(state, RSTV0910_P2_SFRINIT0 + state->regoff, (symb & 0xFF)); + + state->demod_bits |= 0x80; + write_reg(state, RSTV0910_P2_DEMOD + state->regoff, state->demod_bits); + + /* FE_STV0910_SetSearchStandard */ + read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®_dmdcfgmd); + write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, + reg_dmdcfgmd |= 0xC0); + + write_shared_reg(state, + RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x00); + + /* Disable DSS */ + write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00); + write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F); + + enable_puncture_rate(state, FEC_NONE); + + /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ + write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); + write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); + write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); + write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84); + write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C); + write_reg(state, RSTV0910_P2_CARFREQ + state->regoff, 0x79); + + write_reg(state, RSTV0910_P2_ACLC2S216A + state->regoff, 0x29); + write_reg(state, RSTV0910_P2_ACLC2S232A + state->regoff, 0x09); + write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84); + write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84); + + /* Reset CAR3, bug DVBS2->DVBS1 lock*/ + /* Note: The bit is only pulsed -> no lock on shared register needed */ + write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08); + write_reg(state, RSTV0910_TSTRES0, 0); + + set_vth_default(state); + /* Reset demod */ + write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); + + write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46); + + if (p->symbol_rate <= 5000000) + freq = (state->search_range / 2000) + 80; + else + freq = (state->search_range / 2000) + 1600; + freq = (freq << 16) / (state->base->mclk / 1000); + + write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, + (freq >> 8) & 0xff); + write_reg(state, RSTV0910_P2_CFRUP0 + state->regoff, (freq & 0xff)); + /*CFR Low Setting*/ + freq = -freq; + write_reg(state, RSTV0910_P2_CFRLOW1 + state->regoff, + (freq >> 8) & 0xff); + write_reg(state, RSTV0910_P2_CFRLOW0 + state->regoff, (freq & 0xff)); + + /* init the demod frequency offset to 0 */ + write_reg(state, RSTV0910_P2_CFRINIT1 + state->regoff, 0); + write_reg(state, RSTV0910_P2_CFRINIT0 + state->regoff, 0); + + write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); + /* Trigger acq */ + write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x15); + + state->demod_lock_time += TUNING_DELAY; + state->started = 1; + + return 0; +} + +static int init_diseqc(struct stv *state) +{ + u16 offs = state->nr ? 0x40 : 0; /* Address offset */ + u8 freq = ((state->base->mclk + 11000 * 32) / (22000 * 32)); + + /* Disable receiver */ + write_reg(state, RSTV0910_P1_DISRXCFG + offs, 0x00); + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0xBA); /* Reset = 1 */ + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); /* Reset = 0 */ + write_reg(state, RSTV0910_P1_DISTXF22 + offs, freq); + return 0; +} + +static int probe(struct stv *state) +{ + u8 id; + + state->receive_mode = RCVMODE_NONE; + state->started = 0; + + if (read_reg(state, RSTV0910_MID, &id) < 0) + return -ENODEV; + + if (id != 0x51) + return -EINVAL; + + /* Configure the I2C repeater to off */ + write_reg(state, RSTV0910_P1_I2CRPT, 0x24); + /* Configure the I2C repeater to off */ + write_reg(state, RSTV0910_P2_I2CRPT, 0x24); + /* Set the I2C to oversampling ratio */ + write_reg(state, RSTV0910_I2CCFG, 0x88); /* state->i2ccfg */ + + write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ + write_reg(state, RSTV0910_PADCFG, 0x05); /* RFAGC Pads Dev = 05 */ + write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ + write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */ + write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ + + if (state->single) + write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */ + else + write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ + + write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */ + write_reg(state, RSTV0910_P2_TNRCFG2, 0x82); /* IQSWAP = 1 */ + + write_reg(state, RSTV0910_P1_CAR3CFG, 0x02); + write_reg(state, RSTV0910_P2_CAR3CFG, 0x02); + write_reg(state, RSTV0910_P1_DMDCFG4, 0x04); + write_reg(state, RSTV0910_P2_DMDCFG4, 0x04); + + write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */ + write_reg(state, RSTV0910_TSTRES0, 0x00); + + write_reg(state, RSTV0910_P1_TSPIDFLT1, 0x00); + write_reg(state, RSTV0910_P2_TSPIDFLT1, 0x00); + + write_reg(state, RSTV0910_P1_TMGCFG2, 0x80); + write_reg(state, RSTV0910_P2_TMGCFG2, 0x80); + + set_mclock(state, 135000000); + + /* TS output */ + write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh | 0x01); + write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh); + write_reg(state, RSTV0910_P1_TSCFGM, 0xC0); /* Manual speed */ + write_reg(state, RSTV0910_P1_TSCFGL, 0x20); + + /* Speed = 67.5 MHz */ + write_reg(state, RSTV0910_P1_TSSPEED, state->tsspeed); + + write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh | 0x01); + write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh); + write_reg(state, RSTV0910_P2_TSCFGM, 0xC0); /* Manual speed */ + write_reg(state, RSTV0910_P2_TSCFGL, 0x20); + + /* Speed = 67.5 MHz */ + write_reg(state, RSTV0910_P2_TSSPEED, state->tsspeed); + + /* Reset stream merger */ + write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh | 0x01); + write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh | 0x01); + write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh); + write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh); + + write_reg(state, RSTV0910_P1_I2CRPT, state->i2crpt); + write_reg(state, RSTV0910_P2_I2CRPT, state->i2crpt); + + init_diseqc(state); + return 0; +} + + +static int gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct stv *state = fe->demodulator_priv; + u8 i2crpt = state->i2crpt & ~0x86; + + if (enable) + mutex_lock(&state->base->i2c_lock); + + if (enable) + i2crpt |= 0x80; + else + i2crpt |= 0x02; + + if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT : + RSTV0910_P1_I2CRPT, i2crpt) < 0) + return -EIO; + + state->i2crpt = i2crpt; + + if (!enable) + mutex_unlock(&state->base->i2c_lock); + return 0; +} + +static void release(struct dvb_frontend *fe) +{ + struct stv *state = fe->demodulator_priv; + + state->base->count--; + if (state->base->count == 0) { + list_del(&state->base->stvlist); + kfree(state->base); + } + kfree(state); +} + +static int set_parameters(struct dvb_frontend *fe) +{ + int stat = 0; + struct stv *state = fe->demodulator_priv; + u32 iffreq; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + stop(state); + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe); + if (fe->ops.tuner_ops.get_if_frequency) + fe->ops.tuner_ops.get_if_frequency(fe, &iffreq); + state->symbol_rate = p->symbol_rate; + stat = start(state, p); + return stat; +} + +static int manage_matype_info(struct stv *state) +{ + if (!state->started) + return -EINVAL; + if (state->receive_mode == RCVMODE_DVBS2) { + u8 bbheader[2]; + + read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff, + bbheader, 2); + state->feroll_off = + (enum fe_stv0910_roll_off) (bbheader[0] & 0x03); + state->is_vcm = (bbheader[0] & 0x10) == 0; + state->is_standard_broadcast = (bbheader[0] & 0xFC) == 0xF0; + } else if (state->receive_mode == RCVMODE_DVBS) { + state->is_vcm = 0; + state->is_standard_broadcast = 1; + state->feroll_off = FE_SAT_35; + } + return 0; +} + +static int read_snr(struct dvb_frontend *fe) +{ + struct stv *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + s32 snrval; + + if (!get_signal_to_noise(state, &snrval)) { + p->cnr.stat[0].scale = FE_SCALE_DECIBEL; + p->cnr.stat[0].uvalue = 100 * snrval; /* fix scale */ + } else + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + return 0; +} + +static int read_ber(struct dvb_frontend *fe) +{ + struct stv *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 n, d; + + get_bit_error_rate(state, &n, &d); + + p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_error.stat[0].uvalue = n; + p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_count.stat[0].uvalue = d; + + return 0; +} + +static void read_signal_strength(struct dvb_frontend *fe) +{ + /* FIXME: add signal strength algo */ + struct stv *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; + + p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +} + +static int read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct stv *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u8 dmd_state = 0; + u8 dstatus = 0; + enum receive_mode cur_receive_mode = RCVMODE_NONE; + u32 feclock = 0; + + *status = 0; + + read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &dmd_state); + + if (dmd_state & 0x40) { + read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &dstatus); + if (dstatus & 0x08) + cur_receive_mode = (dmd_state & 0x20) ? + RCVMODE_DVBS : RCVMODE_DVBS2; + } + if (cur_receive_mode == RCVMODE_NONE) { + set_vth(state); + + /* reset signal statistics */ + p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + return 0; + } + + *status |= (FE_HAS_SIGNAL + | FE_HAS_CARRIER + | FE_HAS_VITERBI + | FE_HAS_SYNC); + + if (state->receive_mode == RCVMODE_NONE) { + state->receive_mode = cur_receive_mode; + state->demod_lock_time = jiffies; + state->first_time_lock = 1; + + get_signal_parameters(state); + tracking_optimization(state); + + write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, + state->tscfgh); + usleep_range(3000, 4000); + write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, + state->tscfgh | 0x01); + write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, + state->tscfgh); + } + if (dmd_state & 0x40) { + if (state->receive_mode == RCVMODE_DVBS2) { + u8 pdelstatus; + + read_reg(state, + RSTV0910_P2_PDELSTATUS1 + state->regoff, + &pdelstatus); + feclock = (pdelstatus & 0x02) != 0; + } else { + u8 vstatus; + + read_reg(state, + RSTV0910_P2_VSTATUSVIT + state->regoff, + &vstatus); + feclock = (vstatus & 0x08) != 0; + } + } + + if (feclock) { + *status |= FE_HAS_LOCK; + + if (state->first_time_lock) { + u8 tmp; + + state->first_time_lock = 0; + + manage_matype_info(state); + + if (state->receive_mode == RCVMODE_DVBS2) { + /* FSTV0910_P2_MANUALSX_ROLLOFF, + * FSTV0910_P2_MANUALS2_ROLLOFF = 0 + */ + state->demod_bits &= ~0x84; + write_reg(state, + RSTV0910_P2_DEMOD + state->regoff, + state->demod_bits); + read_reg(state, + RSTV0910_P2_PDELCTRL2 + state->regoff, + &tmp); + /*reset DVBS2 packet delinator error counter */ + tmp |= 0x40; + write_reg(state, + RSTV0910_P2_PDELCTRL2 + state->regoff, + tmp); + /*reset DVBS2 packet delinator error counter */ + tmp &= ~0x40; + write_reg(state, + RSTV0910_P2_PDELCTRL2 + state->regoff, + tmp); + + state->berscale = 2; + state->last_bernumerator = 0; + state->last_berdenominator = 1; + /* force to PRE BCH Rate */ + write_reg(state, + RSTV0910_P2_ERRCTRL1 + state->regoff, + BER_SRC_S2 | state->berscale); + } else { + state->berscale = 2; + state->last_bernumerator = 0; + state->last_berdenominator = 1; + /* force to PRE RS Rate */ + write_reg(state, + RSTV0910_P2_ERRCTRL1 + state->regoff, + BER_SRC_S | state->berscale); + } + /*Reset the Total packet counter */ + write_reg(state, + RSTV0910_P2_FBERCPT4 + state->regoff, 0x00); + /* Reset the packet Error counter2 (and Set it to + * infinit error count mode ) + */ + write_reg(state, + RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); + + set_vth_default(state); + if (state->receive_mode == RCVMODE_DVBS) + enable_puncture_rate(state, + state->puncture_rate); + } + } + + /* read signal statistics */ + + /* read signal strength */ + read_signal_strength(fe); + + /* read carrier/noise on FE_HAS_CARRIER */ + if (*status & FE_HAS_CARRIER) + read_snr(fe); + else + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + /* read ber */ + if (*status & FE_HAS_VITERBI) + read_ber(fe); + else { + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + return 0; +} + +static int get_frontend(struct dvb_frontend *fe, + struct dtv_frontend_properties *p) +{ + struct stv *state = fe->demodulator_priv; + u8 tmp; + + if (state->receive_mode == RCVMODE_DVBS2) { + u32 mc; + enum fe_modulation modcod2mod[0x20] = { + QPSK, QPSK, QPSK, QPSK, + QPSK, QPSK, QPSK, QPSK, + QPSK, QPSK, QPSK, QPSK, + PSK_8, PSK_8, PSK_8, PSK_8, + PSK_8, PSK_8, APSK_16, APSK_16, + APSK_16, APSK_16, APSK_16, APSK_16, + APSK_32, APSK_32, APSK_32, APSK_32, + APSK_32, + }; + enum fe_code_rate modcod2fec[0x20] = { + FEC_NONE, FEC_NONE, FEC_NONE, FEC_2_5, + FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, + FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6, + FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, + FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, + FEC_9_10 + }; + read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); + mc = ((tmp & 0x7c) >> 2); + p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF; + p->modulation = modcod2mod[mc]; + p->fec_inner = modcod2fec[mc]; + } else if (state->receive_mode == RCVMODE_DVBS) { + read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); + switch (tmp & 0x1F) { + case 0x0d: + p->fec_inner = FEC_1_2; + break; + case 0x12: + p->fec_inner = FEC_2_3; + break; + case 0x15: + p->fec_inner = FEC_3_4; + break; + case 0x18: + p->fec_inner = FEC_5_6; + break; + case 0x1a: + p->fec_inner = FEC_7_8; + break; + default: + p->fec_inner = FEC_NONE; + break; + } + p->rolloff = ROLLOFF_35; + } + + return 0; +} + +static int tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, + unsigned int *delay, enum fe_status *status) +{ + struct stv *state = fe->demodulator_priv; + int r; + + if (re_tune) { + r = set_parameters(fe); + if (r) + return r; + state->tune_time = jiffies; + } + if (*status & FE_HAS_LOCK) + return 0; + *delay = HZ; + + r = read_status(fe, status); + if (r) + return r; + return 0; +} + + +static int get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_HW; +} + +static int set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) +{ + struct stv *state = fe->demodulator_priv; + u16 offs = state->nr ? 0x40 : 0; + + switch (tone) { + case SEC_TONE_ON: + return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x38); + case SEC_TONE_OFF: + return write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3a); + default: + break; + } + return -EINVAL; +} + +static int wait_dis(struct stv *state, u8 flag, u8 val) +{ + int i; + u8 stat; + u16 offs = state->nr ? 0x40 : 0; + + for (i = 0; i < 10; i++) { + read_reg(state, RSTV0910_P1_DISTXSTATUS + offs, &stat); + if ((stat & flag) == val) + return 0; + usleep_range(10000, 11000); + } + return -ETIMEDOUT; +} + +static int send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + struct stv *state = fe->demodulator_priv; + u16 offs = state->nr ? 0x40 : 0; + int i; + + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); + for (i = 0; i < cmd->msg_len; i++) { + wait_dis(state, 0x40, 0x00); + write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]); + } + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); + wait_dis(state, 0x20, 0x20); + return 0; +} + +static int sleep(struct dvb_frontend *fe) +{ + struct stv *state = fe->demodulator_priv; + + stop(state); + return 0; +} + +static struct dvb_frontend_ops stv0910_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, + .info = { + .name = "STV0910", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 70000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_2G_MODULATION + }, + .sleep = sleep, + .release = release, + .i2c_gate_ctrl = gate_ctrl, + .get_frontend_algo = get_algo, + .get_frontend = get_frontend, + .tune = tune, + .read_status = read_status, + .set_tone = set_tone, + + .diseqc_send_master_cmd = send_master_cmd, +}; + +static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) +{ + struct stv_base *p; + + list_for_each_entry(p, &stvlist, stvlist) + if (p->i2c == i2c && p->adr == adr) + return p; + return NULL; +} + +static void stv0910_init_stats(struct stv *state) +{ + struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; + + p->strength.len = 1; + p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->cnr.len = 1; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_error.len = 1; + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.len = 1; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; +} + +struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, + struct stv0910_cfg *cfg, + int nr) +{ + struct stv *state; + struct stv_base *base; + + state = kzalloc(sizeof(struct stv), GFP_KERNEL); + if (!state) + return NULL; + + state->tscfgh = 0x20 | (cfg->parallel ? 0 : 0x40); + state->tsgeneral = (cfg->parallel == 2) ? 0x02 : 0x00; + state->i2crpt = 0x0A | ((cfg->rptlvl & 0x07) << 4); + state->tsspeed = 0x28; + state->nr = nr; + state->regoff = state->nr ? 0 : 0x200; + state->search_range = 16000000; + state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ + state->receive_mode = RCVMODE_NONE; + state->single = cfg->single ? 1 : 0; + + base = match_base(i2c, cfg->adr); + if (base) { + base->count++; + state->base = base; + } else { + base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); + if (!base) + goto fail; + base->i2c = i2c; + base->adr = cfg->adr; + base->count = 1; + base->extclk = cfg->clk ? cfg->clk : 30000000; + + mutex_init(&base->i2c_lock); + mutex_init(&base->reg_lock); + state->base = base; + if (probe(state) < 0) { + dev_info(&i2c->dev, "No demod found at adr %02X on %s\n", + cfg->adr, dev_name(&i2c->dev)); + kfree(base); + goto fail; + } + list_add(&base->stvlist, &stvlist); + } + state->fe.ops = stv0910_ops; + state->fe.demodulator_priv = state; + state->nr = nr; + + dev_info(&i2c->dev, "%s demod found at adr %02X on %s\n", + state->fe.ops.info.name, cfg->adr, dev_name(&i2c->dev)); + + stv0910_init_stats(state); + + return &state->fe; + +fail: + kfree(state); + return NULL; +} +EXPORT_SYMBOL_GPL(stv0910_attach); + +MODULE_DESCRIPTION("ST STV0910 multistandard frontend driver"); +MODULE_AUTHOR("Ralph and Marcus Metzler, Manfred Voelkel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/stv0910.h b/drivers/media/dvb-frontends/stv0910.h new file mode 100644 index 000000000000..e1ab6df7c805 --- /dev/null +++ b/drivers/media/dvb-frontends/stv0910.h @@ -0,0 +1,32 @@ +#ifndef _STV0910_H_ +#define _STV0910_H_ + +#include +#include + +struct stv0910_cfg { + u32 clk; + u8 adr; + u8 parallel; + u8 rptlvl; + u8 single; +}; + +#if IS_REACHABLE(CONFIG_DVB_STV0910) + +extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, + struct stv0910_cfg *cfg, int nr); + +#else + +static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, + struct stv0910_cfg *cfg, + int nr) +{ + pr_warn("%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +#endif /* CONFIG_DVB_STV0910 */ + +#endif /* _STV0910_H_ */ diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h new file mode 100644 index 000000000000..17c9a51e2e34 --- /dev/null +++ b/drivers/media/dvb-frontends/stv0910_regs.h @@ -0,0 +1,4759 @@ +/* @DVB-S/DVB-S2 STMicroelectronics STV0900 register definitions + * Author Manfred Voelkel, August 2013 + * (c) 2013 Digital Devices GmbH Germany. All rights reserved + * + * ======================================================================= + * Registers Declaration (Internal ST, All Applications ) + * ------------------------- + * Each register (RSTV0910__XXXXX) is defined by its address (2 bytes). + * + * Each field (FSTV0910__XXXXX)is defined as follow: + * [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte] + * ====================================================================== + */ + +/*MID*/ +#define RSTV0910_MID 0xf100 +#define FSTV0910_MCHIP_IDENT 0xf10000f0 +#define FSTV0910_MRELEASE 0xf100000f + +/*DID*/ +#define RSTV0910_DID 0xf101 +#define FSTV0910_DEVICE_ID 0xf10100ff + +/*DACR1*/ +#define RSTV0910_DACR1 0xf113 +#define FSTV0910_DAC_MODE 0xf11300e0 +#define FSTV0910_DAC_VALUE1 0xf113000f + +/*DACR2*/ +#define RSTV0910_DACR2 0xf114 +#define FSTV0910_DAC_VALUE0 0xf11400ff + +/*PADCFG*/ +#define RSTV0910_PADCFG 0xf11a +#define FSTV0910_AGCRF2_OPD 0xf11a0008 +#define FSTV0910_AGCRF2_XOR 0xf11a0004 +#define FSTV0910_AGCRF1_OPD 0xf11a0002 +#define FSTV0910_AGCRF1_XOR 0xf11a0001 + +/*OUTCFG2*/ +#define RSTV0910_OUTCFG2 0xf11b +#define FSTV0910_TS2_ERROR_XOR 0xf11b0080 +#define FSTV0910_TS2_DPN_XOR 0xf11b0040 +#define FSTV0910_TS2_STROUT_XOR 0xf11b0020 +#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b0010 +#define FSTV0910_TS1_ERROR_XOR 0xf11b0008 +#define FSTV0910_TS1_DPN_XOR 0xf11b0004 +#define FSTV0910_TS1_STROUT_XOR 0xf11b0002 +#define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001 + +/*OUTCFG*/ +#define RSTV0910_OUTCFG 0xf11c +#define FSTV0910_TS2_OUTSER_HZ 0xf11c0020 +#define FSTV0910_TS1_OUTSER_HZ 0xf11c0010 +#define FSTV0910_TS2_OUTPAR_HZ 0xf11c0008 +#define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004 +#define FSTV0910_TS_SERDATA0 0xf11c0002 + +/*IRQSTATUS3*/ +#define RSTV0910_IRQSTATUS3 0xf120 +#define FSTV0910_SPLL_LOCK 0xf1200020 +#define FSTV0910_SSTREAM_LCK_1 0xf1200010 +#define FSTV0910_SSTREAM_LCK_2 0xf1200008 +#define FSTV0910_SDVBS1_PRF_2 0xf1200002 +#define FSTV0910_SDVBS1_PRF_1 0xf1200001 + +/*IRQSTATUS2*/ +#define RSTV0910_IRQSTATUS2 0xf121 +#define FSTV0910_SSPY_ENDSIM_1 0xf1210080 +#define FSTV0910_SSPY_ENDSIM_2 0xf1210040 +#define FSTV0910_SPKTDEL_ERROR_2 0xf1210010 +#define FSTV0910_SPKTDEL_LOCKB_2 0xf1210008 +#define FSTV0910_SPKTDEL_LOCK_2 0xf1210004 +#define FSTV0910_SPKTDEL_ERROR_1 0xf1210002 +#define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001 + +/*IRQSTATUS1*/ +#define RSTV0910_IRQSTATUS1 0xf122 +#define FSTV0910_SPKTDEL_LOCK_1 0xf1220080 +#define FSTV0910_SFEC_LOCKB_2 0xf1220040 +#define FSTV0910_SFEC_LOCK_2 0xf1220020 +#define FSTV0910_SFEC_LOCKB_1 0xf1220010 +#define FSTV0910_SFEC_LOCK_1 0xf1220008 +#define FSTV0910_SDEMOD_LOCKB_2 0xf1220004 +#define FSTV0910_SDEMOD_LOCK_2 0xf1220002 +#define FSTV0910_SDEMOD_IRQ_2 0xf1220001 + +/*IRQSTATUS0*/ +#define RSTV0910_IRQSTATUS0 0xf123 +#define FSTV0910_SDEMOD_LOCKB_1 0xf1230080 +#define FSTV0910_SDEMOD_LOCK_1 0xf1230040 +#define FSTV0910_SDEMOD_IRQ_1 0xf1230020 +#define FSTV0910_SBCH_ERRFLAG 0xf1230010 +#define FSTV0910_SDISEQC2_IRQ 0xf1230004 +#define FSTV0910_SDISEQC1_IRQ 0xf1230001 + +/*IRQMASK3*/ +#define RSTV0910_IRQMASK3 0xf124 +#define FSTV0910_MPLL_LOCK 0xf1240020 +#define FSTV0910_MSTREAM_LCK_1 0xf1240010 +#define FSTV0910_MSTREAM_LCK_2 0xf1240008 +#define FSTV0910_MDVBS1_PRF_2 0xf1240002 +#define FSTV0910_MDVBS1_PRF_1 0xf1240001 + +/*IRQMASK2*/ +#define RSTV0910_IRQMASK2 0xf125 +#define FSTV0910_MSPY_ENDSIM_1 0xf1250080 +#define FSTV0910_MSPY_ENDSIM_2 0xf1250040 +#define FSTV0910_MPKTDEL_ERROR_2 0xf1250010 +#define FSTV0910_MPKTDEL_LOCKB_2 0xf1250008 +#define FSTV0910_MPKTDEL_LOCK_2 0xf1250004 +#define FSTV0910_MPKTDEL_ERROR_1 0xf1250002 +#define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001 + +/*IRQMASK1*/ +#define RSTV0910_IRQMASK1 0xf126 +#define FSTV0910_MPKTDEL_LOCK_1 0xf1260080 +#define FSTV0910_MFEC_LOCKB_2 0xf1260040 +#define FSTV0910_MFEC_LOCK_2 0xf1260020 +#define FSTV0910_MFEC_LOCKB_1 0xf1260010 +#define FSTV0910_MFEC_LOCK_1 0xf1260008 +#define FSTV0910_MDEMOD_LOCKB_2 0xf1260004 +#define FSTV0910_MDEMOD_LOCK_2 0xf1260002 +#define FSTV0910_MDEMOD_IRQ_2 0xf1260001 + +/*IRQMASK0*/ +#define RSTV0910_IRQMASK0 0xf127 +#define FSTV0910_MDEMOD_LOCKB_1 0xf1270080 +#define FSTV0910_MDEMOD_LOCK_1 0xf1270040 +#define FSTV0910_MDEMOD_IRQ_1 0xf1270020 +#define FSTV0910_MBCH_ERRFLAG 0xf1270010 +#define FSTV0910_MDISEQC2_IRQ 0xf1270004 +#define FSTV0910_MDISEQC1_IRQ 0xf1270001 + +/*I2CCFG*/ +#define RSTV0910_I2CCFG 0xf129 +#define FSTV0910_I2C_FASTMODE 0xf1290008 +#define FSTV0910_I2CADDR_INC 0xf1290003 + +/*P1_I2CRPT*/ +#define RSTV0910_P1_I2CRPT 0xf12a +#define FSTV0910_P1_I2CT_ON 0xf12a0080 +#define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070 +#define FSTV0910_P1_SCLT_DELAY 0xf12a0008 +#define FSTV0910_P1_STOP_ENABLE 0xf12a0004 +#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002 + +/*P2_I2CRPT*/ +#define RSTV0910_P2_I2CRPT 0xf12b +#define FSTV0910_P2_I2CT_ON 0xf12b0080 +#define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070 +#define FSTV0910_P2_SCLT_DELAY 0xf12b0008 +#define FSTV0910_P2_STOP_ENABLE 0xf12b0004 +#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002 + +/*GPIO0CFG*/ +#define RSTV0910_GPIO0CFG 0xf140 +#define FSTV0910_GPIO0_OPD 0xf1400080 +#define FSTV0910_GPIO0_CONFIG 0xf140007e +#define FSTV0910_GPIO0_XOR 0xf1400001 + +/*GPIO1CFG*/ +#define RSTV0910_GPIO1CFG 0xf141 +#define FSTV0910_GPIO1_OPD 0xf1410080 +#define FSTV0910_GPIO1_CONFIG 0xf141007e +#define FSTV0910_GPIO1_XOR 0xf1410001 + +/*GPIO2CFG*/ +#define RSTV0910_GPIO2CFG 0xf142 +#define FSTV0910_GPIO2_OPD 0xf1420080 +#define FSTV0910_GPIO2_CONFIG 0xf142007e +#define FSTV0910_GPIO2_XOR 0xf1420001 + +/*GPIO3CFG*/ +#define RSTV0910_GPIO3CFG 0xf143 +#define FSTV0910_GPIO3_OPD 0xf1430080 +#define FSTV0910_GPIO3_CONFIG 0xf143007e +#define FSTV0910_GPIO3_XOR 0xf1430001 + +/*GPIO4CFG*/ +#define RSTV0910_GPIO4CFG 0xf144 +#define FSTV0910_GPIO4_OPD 0xf1440080 +#define FSTV0910_GPIO4_CONFIG 0xf144007e +#define FSTV0910_GPIO4_XOR 0xf1440001 + +/*GPIO5CFG*/ +#define RSTV0910_GPIO5CFG 0xf145 +#define FSTV0910_GPIO5_OPD 0xf1450080 +#define FSTV0910_GPIO5_CONFIG 0xf145007e +#define FSTV0910_GPIO5_XOR 0xf1450001 + +/*GPIO6CFG*/ +#define RSTV0910_GPIO6CFG 0xf146 +#define FSTV0910_GPIO6_OPD 0xf1460080 +#define FSTV0910_GPIO6_CONFIG 0xf146007e +#define FSTV0910_GPIO6_XOR 0xf1460001 + +/*GPIO7CFG*/ +#define RSTV0910_GPIO7CFG 0xf147 +#define FSTV0910_GPIO7_OPD 0xf1470080 +#define FSTV0910_GPIO7_CONFIG 0xf147007e +#define FSTV0910_GPIO7_XOR 0xf1470001 + +/*GPIO8CFG*/ +#define RSTV0910_GPIO8CFG 0xf148 +#define FSTV0910_GPIO8_OPD 0xf1480080 +#define FSTV0910_GPIO8_CONFIG 0xf148007e +#define FSTV0910_GPIO8_XOR 0xf1480001 + +/*GPIO9CFG*/ +#define RSTV0910_GPIO9CFG 0xf149 +#define FSTV0910_GPIO9_OPD 0xf1490080 +#define FSTV0910_GPIO9_CONFIG 0xf149007e +#define FSTV0910_GPIO9_XOR 0xf1490001 + +/*GPIO10CFG*/ +#define RSTV0910_GPIO10CFG 0xf14a +#define FSTV0910_GPIO10_OPD 0xf14a0080 +#define FSTV0910_GPIO10_CONFIG 0xf14a007e +#define FSTV0910_GPIO10_XOR 0xf14a0001 + +/*GPIO11CFG*/ +#define RSTV0910_GPIO11CFG 0xf14b +#define FSTV0910_GPIO11_OPD 0xf14b0080 +#define FSTV0910_GPIO11_CONFIG 0xf14b007e +#define FSTV0910_GPIO11_XOR 0xf14b0001 + +/*GPIO12CFG*/ +#define RSTV0910_GPIO12CFG 0xf14c +#define FSTV0910_GPIO12_OPD 0xf14c0080 +#define FSTV0910_GPIO12_CONFIG 0xf14c007e +#define FSTV0910_GPIO12_XOR 0xf14c0001 + +/*GPIO13CFG*/ +#define RSTV0910_GPIO13CFG 0xf14d +#define FSTV0910_GPIO13_OPD 0xf14d0080 +#define FSTV0910_GPIO13_CONFIG 0xf14d007e +#define FSTV0910_GPIO13_XOR 0xf14d0001 + +/*GPIO14CFG*/ +#define RSTV0910_GPIO14CFG 0xf14e +#define FSTV0910_GPIO14_OPD 0xf14e0080 +#define FSTV0910_GPIO14_CONFIG 0xf14e007e +#define FSTV0910_GPIO14_XOR 0xf14e0001 + +/*GPIO15CFG*/ +#define RSTV0910_GPIO15CFG 0xf14f +#define FSTV0910_GPIO15_OPD 0xf14f0080 +#define FSTV0910_GPIO15_CONFIG 0xf14f007e +#define FSTV0910_GPIO15_XOR 0xf14f0001 + +/*GPIO16CFG*/ +#define RSTV0910_GPIO16CFG 0xf150 +#define FSTV0910_GPIO16_OPD 0xf1500080 +#define FSTV0910_GPIO16_CONFIG 0xf150007e +#define FSTV0910_GPIO16_XOR 0xf1500001 + +/*GPIO17CFG*/ +#define RSTV0910_GPIO17CFG 0xf151 +#define FSTV0910_GPIO17_OPD 0xf1510080 +#define FSTV0910_GPIO17_CONFIG 0xf151007e +#define FSTV0910_GPIO17_XOR 0xf1510001 + +/*GPIO18CFG*/ +#define RSTV0910_GPIO18CFG 0xf152 +#define FSTV0910_GPIO18_OPD 0xf1520080 +#define FSTV0910_GPIO18_CONFIG 0xf152007e +#define FSTV0910_GPIO18_XOR 0xf1520001 + +/*GPIO19CFG*/ +#define RSTV0910_GPIO19CFG 0xf153 +#define FSTV0910_GPIO19_OPD 0xf1530080 +#define FSTV0910_GPIO19_CONFIG 0xf153007e +#define FSTV0910_GPIO19_XOR 0xf1530001 + +/*GPIO20CFG*/ +#define RSTV0910_GPIO20CFG 0xf154 +#define FSTV0910_GPIO20_OPD 0xf1540080 +#define FSTV0910_GPIO20_CONFIG 0xf154007e +#define FSTV0910_GPIO20_XOR 0xf1540001 + +/*GPIO21CFG*/ +#define RSTV0910_GPIO21CFG 0xf155 +#define FSTV0910_GPIO21_OPD 0xf1550080 +#define FSTV0910_GPIO21_CONFIG 0xf155007e +#define FSTV0910_GPIO21_XOR 0xf1550001 + +/*GPIO22CFG*/ +#define RSTV0910_GPIO22CFG 0xf156 +#define FSTV0910_GPIO22_OPD 0xf1560080 +#define FSTV0910_GPIO22_CONFIG 0xf156007e +#define FSTV0910_GPIO22_XOR 0xf1560001 + +/*STRSTATUS1*/ +#define RSTV0910_STRSTATUS1 0xf16a +#define FSTV0910_STRSTATUS_SEL2 0xf16a00f0 +#define FSTV0910_STRSTATUS_SEL1 0xf16a000f + +/*STRSTATUS2*/ +#define RSTV0910_STRSTATUS2 0xf16b +#define FSTV0910_STRSTATUS_SEL4 0xf16b00f0 +#define FSTV0910_STRSTATUS_SEL3 0xf16b000f + +/*STRSTATUS3*/ +#define RSTV0910_STRSTATUS3 0xf16c +#define FSTV0910_STRSTATUS_SEL6 0xf16c00f0 +#define FSTV0910_STRSTATUS_SEL5 0xf16c000f + +/*FSKTFC2*/ +#define RSTV0910_FSKTFC2 0xf170 +#define FSTV0910_FSKT_KMOD 0xf17000fc +#define FSTV0910_FSKT_CAR2 0xf1700003 + +/*FSKTFC1*/ +#define RSTV0910_FSKTFC1 0xf171 +#define FSTV0910_FSKT_CAR1 0xf17100ff + +/*FSKTFC0*/ +#define RSTV0910_FSKTFC0 0xf172 +#define FSTV0910_FSKT_CAR0 0xf17200ff + +/*FSKTDELTAF1*/ +#define RSTV0910_FSKTDELTAF1 0xf173 +#define FSTV0910_FSKT_DELTAF1 0xf173000f + +/*FSKTDELTAF0*/ +#define RSTV0910_FSKTDELTAF0 0xf174 +#define FSTV0910_FSKT_DELTAF0 0xf17400ff + +/*FSKTCTRL*/ +#define RSTV0910_FSKTCTRL 0xf175 +#define FSTV0910_FSKT_PINSEL 0xf1750080 +#define FSTV0910_FSKT_EN_SGN 0xf1750040 +#define FSTV0910_FSKT_MOD_SGN 0xf1750020 +#define FSTV0910_FSKT_MOD_EN 0xf175001c +#define FSTV0910_FSKT_DACMODE 0xf1750003 + +/*FSKRFC2*/ +#define RSTV0910_FSKRFC2 0xf176 +#define FSTV0910_FSKR_DETSGN 0xf1760040 +#define FSTV0910_FSKR_OUTSGN 0xf1760020 +#define FSTV0910_FSKR_KAGC 0xf176001c +#define FSTV0910_FSKR_CAR2 0xf1760003 + +/*FSKRFC1*/ +#define RSTV0910_FSKRFC1 0xf177 +#define FSTV0910_FSKR_CAR1 0xf17700ff + +/*FSKRFC0*/ +#define RSTV0910_FSKRFC0 0xf178 +#define FSTV0910_FSKR_CAR0 0xf17800ff + +/*FSKRK1*/ +#define RSTV0910_FSKRK1 0xf179 +#define FSTV0910_FSKR_K1_EXP 0xf17900e0 +#define FSTV0910_FSKR_K1_MANT 0xf179001f + +/*FSKRK2*/ +#define RSTV0910_FSKRK2 0xf17a +#define FSTV0910_FSKR_K2_EXP 0xf17a00e0 +#define FSTV0910_FSKR_K2_MANT 0xf17a001f + +/*FSKRAGCR*/ +#define RSTV0910_FSKRAGCR 0xf17b +#define FSTV0910_FSKR_OUTCTL 0xf17b00c0 +#define FSTV0910_FSKR_AGC_REF 0xf17b003f + +/*FSKRAGC*/ +#define RSTV0910_FSKRAGC 0xf17c +#define FSTV0910_FSKR_AGC_ACCU 0xf17c00ff + +/*FSKRALPHA*/ +#define RSTV0910_FSKRALPHA 0xf17d +#define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c +#define FSTV0910_FSKR_ALPHA_M 0xf17d0003 + +/*FSKRPLTH1*/ +#define RSTV0910_FSKRPLTH1 0xf17e +#define FSTV0910_FSKR_BETA 0xf17e00f0 +#define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f + +/*FSKRPLTH0*/ +#define RSTV0910_FSKRPLTH0 0xf17f +#define FSTV0910_FSKR_PLL_TRESH0 0xf17f00ff + +/*FSKRDF1*/ +#define RSTV0910_FSKRDF1 0xf180 +#define FSTV0910_FSKR_OUT 0xf1800080 +#define FSTV0910_FSKR_STATE 0xf1800060 +#define FSTV0910_FSKR_DELTAF1 0xf180001f + +/*FSKRDF0*/ +#define RSTV0910_FSKRDF0 0xf181 +#define FSTV0910_FSKR_DELTAF0 0xf18100ff + +/*FSKRSTEPP*/ +#define RSTV0910_FSKRSTEPP 0xf182 +#define FSTV0910_FSKR_STEP_PLUS 0xf18200ff + +/*FSKRSTEPM*/ +#define RSTV0910_FSKRSTEPM 0xf183 +#define FSTV0910_FSKR_STEP_MINUS 0xf18300ff + +/*FSKRDET1*/ +#define RSTV0910_FSKRDET1 0xf184 +#define FSTV0910_FSKR_DETECT 0xf1840080 +#define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f + +/*FSKRDET0*/ +#define RSTV0910_FSKRDET0 0xf185 +#define FSTV0910_FSKR_CARDET_ACCU0 0xf18500ff + +/*FSKRDTH1*/ +#define RSTV0910_FSKRDTH1 0xf186 +#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0 +#define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f + +/*FSKRDTH0*/ +#define RSTV0910_FSKRDTH0 0xf187 +#define FSTV0910_FSKR_CARDET_THRESH0 0xf18700ff + +/*FSKRLOSS*/ +#define RSTV0910_FSKRLOSS 0xf188 +#define FSTV0910_FSKR_CARLOSS_THRESH0 0xf18800ff + +/*NCOARSE*/ +#define RSTV0910_NCOARSE 0xf1b3 +#define FSTV0910_CP 0xf1b300f8 +#define FSTV0910_IDF 0xf1b30007 + +/*NCOARSE1*/ +#define RSTV0910_NCOARSE1 0xf1b4 +#define FSTV0910_N_DIV 0xf1b400ff + +/*NCOARSE2*/ +#define RSTV0910_NCOARSE2 0xf1b5 +#define FSTV0910_ODF 0xf1b5003f + +/*SYNTCTRL*/ +#define RSTV0910_SYNTCTRL 0xf1b6 +#define FSTV0910_STANDBY 0xf1b60080 +#define FSTV0910_BYPASSPLLCORE 0xf1b60040 +#define FSTV0910_STOP_PLL 0xf1b60008 +#define FSTV0910_OSCI_E 0xf1b60002 + +/*FILTCTRL*/ +#define RSTV0910_FILTCTRL 0xf1b7 +#define FSTV0910_INV_CLKFSK 0xf1b70002 +#define FSTV0910_BYPASS_APPLI 0xf1b70001 + +/*PLLSTAT*/ +#define RSTV0910_PLLSTAT 0xf1b8 +#define FSTV0910_PLLLOCK 0xf1b80001 + +/*STOPCLK1*/ +#define RSTV0910_STOPCLK1 0xf1c2 +#define FSTV0910_INV_CLKADCI2 0xf1c20004 +#define FSTV0910_INV_CLKADCI1 0xf1c20001 + +/*STOPCLK2*/ +#define RSTV0910_STOPCLK2 0xf1c3 +#define FSTV0910_STOP_DVBS2FEC2 0xf1c30020 +#define FSTV0910_STOP_DVBS2FEC 0xf1c30010 +#define FSTV0910_STOP_DVBS1FEC2 0xf1c30008 +#define FSTV0910_STOP_DVBS1FEC 0xf1c30004 +#define FSTV0910_STOP_DEMOD2 0xf1c30002 +#define FSTV0910_STOP_DEMOD 0xf1c30001 + +/*PREGCTL*/ +#define RSTV0910_PREGCTL 0xf1c8 +#define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080 + +/*TSTTNR0*/ +#define RSTV0910_TSTTNR0 0xf1df +#define FSTV0910_FSK_PON 0xf1df0004 + +/*TSTTNR1*/ +#define RSTV0910_TSTTNR1 0xf1e0 +#define FSTV0910_ADC1_PON 0xf1e00002 + +/*TSTTNR2*/ +#define RSTV0910_TSTTNR2 0xf1e1 +#define FSTV0910_I2C_DISEQC_PON 0xf1e10020 +#define FSTV0910_DISEQC_CLKDIV 0xf1e1000f + +/*TSTTNR3*/ +#define RSTV0910_TSTTNR3 0xf1e2 +#define FSTV0910_ADC2_PON 0xf1e20002 + +/*P2_IQCONST*/ +#define RSTV0910_P2_IQCONST 0xf200 +#define FSTV0910_P2_CONSTEL_SELECT 0xf2000060 +#define FSTV0910_P2_IQSYMB_SEL 0xf200001f + +/*P2_NOSCFG*/ +#define RSTV0910_P2_NOSCFG 0xf201 +#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020 +#define FSTV0910_P2_NOSPLH_BETA 0xf2010018 +#define FSTV0910_P2_NOSDATA_BETA 0xf2010007 + +/*P2_ISYMB*/ +#define RSTV0910_P2_ISYMB 0xf202 +#define FSTV0910_P2_I_SYMBOL 0xf20201ff + +/*P2_QSYMB*/ +#define RSTV0910_P2_QSYMB 0xf203 +#define FSTV0910_P2_Q_SYMBOL 0xf20301ff + +/*P2_AGC1CFG*/ +#define RSTV0910_P2_AGC1CFG 0xf204 +#define FSTV0910_P2_DC_FROZEN 0xf2040080 +#define FSTV0910_P2_DC_CORRECT 0xf2040040 +#define FSTV0910_P2_AMM_FROZEN 0xf2040020 +#define FSTV0910_P2_AMM_CORRECT 0xf2040010 +#define FSTV0910_P2_QUAD_FROZEN 0xf2040008 +#define FSTV0910_P2_QUAD_CORRECT 0xf2040004 + +/*P2_AGC1CN*/ +#define RSTV0910_P2_AGC1CN 0xf206 +#define FSTV0910_P2_AGC1_LOCKED 0xf2060080 +#define FSTV0910_P2_AGC1_MINPOWER 0xf2060010 +#define FSTV0910_P2_AGCOUT_FAST 0xf2060008 +#define FSTV0910_P2_AGCIQ_BETA 0xf2060007 + +/*P2_AGC1REF*/ +#define RSTV0910_P2_AGC1REF 0xf207 +#define FSTV0910_P2_AGCIQ_REF 0xf20700ff + +/*P2_IDCCOMP*/ +#define RSTV0910_P2_IDCCOMP 0xf208 +#define FSTV0910_P2_IAVERAGE_ADJ 0xf20801ff + +/*P2_QDCCOMP*/ +#define RSTV0910_P2_QDCCOMP 0xf209 +#define FSTV0910_P2_QAVERAGE_ADJ 0xf20901ff + +/*P2_POWERI*/ +#define RSTV0910_P2_POWERI 0xf20a +#define FSTV0910_P2_POWER_I 0xf20a00ff + +/*P2_POWERQ*/ +#define RSTV0910_P2_POWERQ 0xf20b +#define FSTV0910_P2_POWER_Q 0xf20b00ff + +/*P2_AGC1AMM*/ +#define RSTV0910_P2_AGC1AMM 0xf20c +#define FSTV0910_P2_AMM_VALUE 0xf20c00ff + +/*P2_AGC1QUAD*/ +#define RSTV0910_P2_AGC1QUAD 0xf20d +#define FSTV0910_P2_QUAD_VALUE 0xf20d01ff + +/*P2_AGCIQIN1*/ +#define RSTV0910_P2_AGCIQIN1 0xf20e +#define FSTV0910_P2_AGCIQ_VALUE1 0xf20e00ff + +/*P2_AGCIQIN0*/ +#define RSTV0910_P2_AGCIQIN0 0xf20f +#define FSTV0910_P2_AGCIQ_VALUE0 0xf20f00ff + +/*P2_DEMOD*/ +#define RSTV0910_P2_DEMOD 0xf210 +#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080 +#define FSTV0910_P2_SPECINV_CONTROL 0xf2100030 +#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004 +#define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003 + +/*P2_DMDMODCOD*/ +#define RSTV0910_P2_DMDMODCOD 0xf211 +#define FSTV0910_P2_MANUAL_MODCOD 0xf2110080 +#define FSTV0910_P2_DEMOD_MODCOD 0xf211007c +#define FSTV0910_P2_DEMOD_TYPE 0xf2110003 + +/*P2_DSTATUS*/ +#define RSTV0910_P2_DSTATUS 0xf212 +#define FSTV0910_P2_CAR_LOCK 0xf2120080 +#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060 +#define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008 +#define FSTV0910_P2_OVADC_DETECT 0xf2120001 + +/*P2_DSTATUS2*/ +#define RSTV0910_P2_DSTATUS2 0xf213 +#define FSTV0910_P2_DEMOD_DELOCK 0xf2130080 +#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020 +#define FSTV0910_P2_POLYPH_SATEVENT 0xf2130010 +#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2130008 +#define FSTV0910_P2_AGC2_OVERFLOW 0xf2130004 +#define FSTV0910_P2_CFR_OVERFLOW 0xf2130002 +#define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001 + +/*P2_DMDCFGMD*/ +#define RSTV0910_P2_DMDCFGMD 0xf214 +#define FSTV0910_P2_DVBS2_ENABLE 0xf2140080 +#define FSTV0910_P2_DVBS1_ENABLE 0xf2140040 +#define FSTV0910_P2_SCAN_ENABLE 0xf2140010 +#define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008 +#define FSTV0910_P2_TUN_RNG 0xf2140003 + +/*P2_DMDCFG2*/ +#define RSTV0910_P2_DMDCFG2 0xf215 +#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040 +#define FSTV0910_P2_INFINITE_RELOCK 0xf2150010 + +/*P2_DMDISTATE*/ +#define RSTV0910_P2_DMDISTATE 0xf216 +#define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080 +#define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f + +/*P2_DMDT0M*/ +#define RSTV0910_P2_DMDT0M 0xf217 +#define FSTV0910_P2_DMDT0_MIN 0xf21700ff + +/*P2_DMDSTATE*/ +#define RSTV0910_P2_DMDSTATE 0xf21b +#define FSTV0910_P2_HEADER_MODE 0xf21b0060 + +/*P2_DMDFLYW*/ +#define RSTV0910_P2_DMDFLYW 0xf21c +#define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0 +#define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f + +/*P2_DSTATUS3*/ +#define RSTV0910_P2_DSTATUS3 0xf21d +#define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080 +#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060 +#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010 + +/*P2_DMDCFG3*/ +#define RSTV0910_P2_DMDCFG3 0xf21e +#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008 + +/*P2_DMDCFG4*/ +#define RSTV0910_P2_DMDCFG4 0xf21f +#define FSTV0910_P2_DIS_VITLOCK 0xf21f0080 +#define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004 + +/*P2_CORRELMANT*/ +#define RSTV0910_P2_CORRELMANT 0xf220 +#define FSTV0910_P2_CORREL_MANT 0xf22000ff + +/*P2_CORRELABS*/ +#define RSTV0910_P2_CORRELABS 0xf221 +#define FSTV0910_P2_CORREL_ABS 0xf22100ff + +/*P2_CORRELEXP*/ +#define RSTV0910_P2_CORRELEXP 0xf222 +#define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0 +#define FSTV0910_P2_CORREL_EXP 0xf222000f + +/*P2_PLHMODCOD*/ +#define RSTV0910_P2_PLHMODCOD 0xf224 +#define FSTV0910_P2_SPECINV_DEMOD 0xf2240080 +#define FSTV0910_P2_PLH_MODCOD 0xf224007c +#define FSTV0910_P2_PLH_TYPE 0xf2240003 + +/*P2_DMDREG*/ +#define RSTV0910_P2_DMDREG 0xf225 +#define FSTV0910_P2_DECIM_PLFRAMES 0xf2250001 + +/*P2_AGCNADJ*/ +#define RSTV0910_P2_AGCNADJ 0xf226 +#define FSTV0910_P2_RADJOFF_AGC2 0xf2260080 +#define FSTV0910_P2_RADJOFF_AGC1 0xf2260040 +#define FSTV0910_P2_AGC_NADJ 0xf226013f + +/*P2_AGCKS*/ +#define RSTV0910_P2_AGCKS 0xf227 +#define FSTV0910_P2_RSADJ_MANUALCFG 0xf2270080 +#define FSTV0910_P2_RSADJ_CCMMODE 0xf2270040 +#define FSTV0910_P2_RADJ_SPSK 0xf227013f + +/*P2_AGCKQ*/ +#define RSTV0910_P2_AGCKQ 0xf228 +#define FSTV0910_P2_RADJON_DVBS1 0xf2280040 +#define FSTV0910_P2_RADJ_QPSK 0xf228013f + +/*P2_AGCK8*/ +#define RSTV0910_P2_AGCK8 0xf229 +#define FSTV0910_P2_RADJ_8PSK 0xf229013f + +/*P2_AGCK16*/ +#define RSTV0910_P2_AGCK16 0xf22a +#define FSTV0910_P2_R2ADJOFF_16APSK 0xf22a0040 +#define FSTV0910_P2_R1ADJOFF_16APSK 0xf22a0020 +#define FSTV0910_P2_RADJ_16APSK 0xf22a011f + +/*P2_AGCK32*/ +#define RSTV0910_P2_AGCK32 0xf22b +#define FSTV0910_P2_R3ADJOFF_32APSK 0xf22b0080 +#define FSTV0910_P2_R2ADJOFF_32APSK 0xf22b0040 +#define FSTV0910_P2_R1ADJOFF_32APSK 0xf22b0020 +#define FSTV0910_P2_RADJ_32APSK 0xf22b011f + +/*P2_AGC2O*/ +#define RSTV0910_P2_AGC2O 0xf22c +#define FSTV0910_P2_CSTENV_MODE 0xf22c00c0 +#define FSTV0910_P2_AGC2_COEF 0xf22c0007 + +/*P2_AGC2REF*/ +#define RSTV0910_P2_AGC2REF 0xf22d +#define FSTV0910_P2_AGC2_REF 0xf22d00ff + +/*P2_AGC1ADJ*/ +#define RSTV0910_P2_AGC1ADJ 0xf22e +#define FSTV0910_P2_AGC1_ADJUSTED 0xf22e007f + +/*P2_AGCRSADJ*/ +#define RSTV0910_P2_AGCRSADJ 0xf22f +#define FSTV0910_P2_RS_ADJUSTED 0xf22f007f + +/*P2_AGCRQADJ*/ +#define RSTV0910_P2_AGCRQADJ 0xf230 +#define FSTV0910_P2_RQ_ADJUSTED 0xf230007f + +/*P2_AGCR8ADJ*/ +#define RSTV0910_P2_AGCR8ADJ 0xf231 +#define FSTV0910_P2_R8_ADJUSTED 0xf231007f + +/*P2_AGCR1ADJ*/ +#define RSTV0910_P2_AGCR1ADJ 0xf232 +#define FSTV0910_P2_R1_ADJUSTED 0xf232007f + +/*P2_AGCR2ADJ*/ +#define RSTV0910_P2_AGCR2ADJ 0xf233 +#define FSTV0910_P2_R2_ADJUSTED 0xf233007f + +/*P2_AGCR3ADJ*/ +#define RSTV0910_P2_AGCR3ADJ 0xf234 +#define FSTV0910_P2_R3_ADJUSTED 0xf234007f + +/*P2_AGCREFADJ*/ +#define RSTV0910_P2_AGCREFADJ 0xf235 +#define FSTV0910_P2_AGC2REF_ADJUSTED 0xf235007f + +/*P2_AGC2I1*/ +#define RSTV0910_P2_AGC2I1 0xf236 +#define FSTV0910_P2_AGC2_INTEGRATOR1 0xf23600ff + +/*P2_AGC2I0*/ +#define RSTV0910_P2_AGC2I0 0xf237 +#define FSTV0910_P2_AGC2_INTEGRATOR0 0xf23700ff + +/*P2_CARCFG*/ +#define RSTV0910_P2_CARCFG 0xf238 +#define FSTV0910_P2_ROTAON 0xf2380004 +#define FSTV0910_P2_PH_DET_ALGO 0xf2380003 + +/*P2_ACLC*/ +#define RSTV0910_P2_ACLC 0xf239 +#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030 +#define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f + +/*P2_BCLC*/ +#define RSTV0910_P2_BCLC 0xf23a +#define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030 +#define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f + +/*P2_ACLCS2*/ +#define RSTV0910_P2_ACLCS2 0xf23b +#define FSTV0910_P2_CARS2_APLHA_MANTISSE 0xf23b0030 +#define FSTV0910_P2_CARS2_ALPHA_EXP 0xf23b000f + +/*P2_BCLCS2*/ +#define RSTV0910_P2_BCLCS2 0xf23c +#define FSTV0910_P2_CARS2_BETA_MANTISSE 0xf23c0030 +#define FSTV0910_P2_CARS2_BETA_EXP 0xf23c000f + +/*P2_CARFREQ*/ +#define RSTV0910_P2_CARFREQ 0xf23d +#define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0 +#define FSTV0910_P2_BETA_FREQ 0xf23d000f + +/*P2_CARHDR*/ +#define RSTV0910_P2_CARHDR 0xf23e +#define FSTV0910_P2_K_FREQ_HDR 0xf23e00ff + +/*P2_LDT*/ +#define RSTV0910_P2_LDT 0xf23f +#define FSTV0910_P2_CARLOCK_THRES 0xf23f01ff + +/*P2_LDT2*/ +#define RSTV0910_P2_LDT2 0xf240 +#define FSTV0910_P2_CARLOCK_THRES2 0xf24001ff + +/*P2_CFRICFG*/ +#define RSTV0910_P2_CFRICFG 0xf241 +#define FSTV0910_P2_NEG_CFRSTEP 0xf2410001 + +/*P2_CFRUP1*/ +#define RSTV0910_P2_CFRUP1 0xf242 +#define FSTV0910_P2_CFR_UP1 0xf24201ff + +/*P2_CFRUP0*/ +#define RSTV0910_P2_CFRUP0 0xf243 +#define FSTV0910_P2_CFR_UP0 0xf24300ff + +/*P2_CFRIBASE1*/ +#define RSTV0910_P2_CFRIBASE1 0xf244 +#define FSTV0910_P2_CFRINIT_BASE1 0xf24400ff + +/*P2_CFRIBASE0*/ +#define RSTV0910_P2_CFRIBASE0 0xf245 +#define FSTV0910_P2_CFRINIT_BASE0 0xf24500ff + +/*P2_CFRLOW1*/ +#define RSTV0910_P2_CFRLOW1 0xf246 +#define FSTV0910_P2_CFR_LOW1 0xf24601ff + +/*P2_CFRLOW0*/ +#define RSTV0910_P2_CFRLOW0 0xf247 +#define FSTV0910_P2_CFR_LOW0 0xf24700ff + +/*P2_CFRINIT1*/ +#define RSTV0910_P2_CFRINIT1 0xf248 +#define FSTV0910_P2_CFR_INIT1 0xf24801ff + +/*P2_CFRINIT0*/ +#define RSTV0910_P2_CFRINIT0 0xf249 +#define FSTV0910_P2_CFR_INIT0 0xf24900ff + +/*P2_CFRINC1*/ +#define RSTV0910_P2_CFRINC1 0xf24a +#define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080 +#define FSTV0910_P2_CFR_INC1 0xf24a003f + +/*P2_CFRINC0*/ +#define RSTV0910_P2_CFRINC0 0xf24b +#define FSTV0910_P2_CFR_INC0 0xf24b00ff + +/*P2_CFR2*/ +#define RSTV0910_P2_CFR2 0xf24c +#define FSTV0910_P2_CAR_FREQ2 0xf24c01ff + +/*P2_CFR1*/ +#define RSTV0910_P2_CFR1 0xf24d +#define FSTV0910_P2_CAR_FREQ1 0xf24d00ff + +/*P2_CFR0*/ +#define RSTV0910_P2_CFR0 0xf24e +#define FSTV0910_P2_CAR_FREQ0 0xf24e00ff + +/*P2_LDI*/ +#define RSTV0910_P2_LDI 0xf24f +#define FSTV0910_P2_LOCK_DET_INTEGR 0xf24f01ff + +/*P2_TMGCFG*/ +#define RSTV0910_P2_TMGCFG 0xf250 +#define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0 +#define FSTV0910_P2_DO_TIMING_CORR 0xf2500010 +#define FSTV0910_P2_TMG_MINFREQ 0xf2500003 + +/*P2_RTC*/ +#define RSTV0910_P2_RTC 0xf251 +#define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0 +#define FSTV0910_P2_TMGBETA_EXP 0xf251000f + +/*P2_RTCS2*/ +#define RSTV0910_P2_RTCS2 0xf252 +#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0 +#define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f + +/*P2_TMGTHRISE*/ +#define RSTV0910_P2_TMGTHRISE 0xf253 +#define FSTV0910_P2_TMGLOCK_THRISE 0xf25300ff + +/*P2_TMGTHFALL*/ +#define RSTV0910_P2_TMGTHFALL 0xf254 +#define FSTV0910_P2_TMGLOCK_THFALL 0xf25400ff + +/*P2_SFRUPRATIO*/ +#define RSTV0910_P2_SFRUPRATIO 0xf255 +#define FSTV0910_P2_SFR_UPRATIO 0xf25500ff + +/*P2_SFRLOWRATIO*/ +#define RSTV0910_P2_SFRLOWRATIO 0xf256 +#define FSTV0910_P2_SFR_LOWRATIO 0xf25600ff + +/*P2_KTTMG*/ +#define RSTV0910_P2_KTTMG 0xf257 +#define FSTV0910_P2_KT_TMG_EXP 0xf25700f0 + +/*P2_KREFTMG*/ +#define RSTV0910_P2_KREFTMG 0xf258 +#define FSTV0910_P2_KREF_TMG 0xf25800ff + +/*P2_SFRSTEP*/ +#define RSTV0910_P2_SFRSTEP 0xf259 +#define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0 +#define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f + +/*P2_TMGCFG2*/ +#define RSTV0910_P2_TMGCFG2 0xf25a +#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008 +#define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001 + +/*P2_KREFTMG2*/ +#define RSTV0910_P2_KREFTMG2 0xf25b +#define FSTV0910_P2_KREF_TMG2 0xf25b00ff + +/*P2_TMGCFG3*/ +#define RSTV0910_P2_TMGCFG3 0xf25d +#define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008 +#define FSTV0910_P2_AUTO_GUP 0xf25d0004 +#define FSTV0910_P2_AUTO_GLOW 0xf25d0002 + +/*P2_SFRINIT1*/ +#define RSTV0910_P2_SFRINIT1 0xf25e +#define FSTV0910_P2_SFR_INIT1 0xf25e00ff + +/*P2_SFRINIT0*/ +#define RSTV0910_P2_SFRINIT0 0xf25f +#define FSTV0910_P2_SFR_INIT0 0xf25f00ff + +/*P2_SFRUP1*/ +#define RSTV0910_P2_SFRUP1 0xf260 +#define FSTV0910_P2_SYMB_FREQ_UP1 0xf26000ff + +/*P2_SFRUP0*/ +#define RSTV0910_P2_SFRUP0 0xf261 +#define FSTV0910_P2_SYMB_FREQ_UP0 0xf26100ff + +/*P2_SFRLOW1*/ +#define RSTV0910_P2_SFRLOW1 0xf262 +#define FSTV0910_P2_SYMB_FREQ_LOW1 0xf26200ff + +/*P2_SFRLOW0*/ +#define RSTV0910_P2_SFRLOW0 0xf263 +#define FSTV0910_P2_SYMB_FREQ_LOW0 0xf26300ff + +/*P2_SFR3*/ +#define RSTV0910_P2_SFR3 0xf264 +#define FSTV0910_P2_SYMB_FREQ3 0xf26400ff + +/*P2_SFR2*/ +#define RSTV0910_P2_SFR2 0xf265 +#define FSTV0910_P2_SYMB_FREQ2 0xf26500ff + +/*P2_SFR1*/ +#define RSTV0910_P2_SFR1 0xf266 +#define FSTV0910_P2_SYMB_FREQ1 0xf26600ff + +/*P2_SFR0*/ +#define RSTV0910_P2_SFR0 0xf267 +#define FSTV0910_P2_SYMB_FREQ0 0xf26700ff + +/*P2_TMGREG2*/ +#define RSTV0910_P2_TMGREG2 0xf268 +#define FSTV0910_P2_TMGREG2 0xf26800ff + +/*P2_TMGREG1*/ +#define RSTV0910_P2_TMGREG1 0xf269 +#define FSTV0910_P2_TMGREG1 0xf26900ff + +/*P2_TMGREG0*/ +#define RSTV0910_P2_TMGREG0 0xf26a +#define FSTV0910_P2_TMGREG0 0xf26a00ff + +/*P2_TMGLOCK1*/ +#define RSTV0910_P2_TMGLOCK1 0xf26b +#define FSTV0910_P2_TMGLOCK_LEVEL1 0xf26b01ff + +/*P2_TMGLOCK0*/ +#define RSTV0910_P2_TMGLOCK0 0xf26c +#define FSTV0910_P2_TMGLOCK_LEVEL0 0xf26c00ff + +/*P2_TMGOBS*/ +#define RSTV0910_P2_TMGOBS 0xf26d +#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0 + +/*P2_EQUALCFG*/ +#define RSTV0910_P2_EQUALCFG 0xf26f +#define FSTV0910_P2_EQUAL_ON 0xf26f0040 +#define FSTV0910_P2_MU_EQUALDFE 0xf26f0007 + +/*P2_EQUAI1*/ +#define RSTV0910_P2_EQUAI1 0xf270 +#define FSTV0910_P2_EQUA_ACCI1 0xf27001ff + +/*P2_EQUAQ1*/ +#define RSTV0910_P2_EQUAQ1 0xf271 +#define FSTV0910_P2_EQUA_ACCQ1 0xf27101ff + +/*P2_EQUAI2*/ +#define RSTV0910_P2_EQUAI2 0xf272 +#define FSTV0910_P2_EQUA_ACCI2 0xf27201ff + +/*P2_EQUAQ2*/ +#define RSTV0910_P2_EQUAQ2 0xf273 +#define FSTV0910_P2_EQUA_ACCQ2 0xf27301ff + +/*P2_EQUAI3*/ +#define RSTV0910_P2_EQUAI3 0xf274 +#define FSTV0910_P2_EQUA_ACCI3 0xf27401ff + +/*P2_EQUAQ3*/ +#define RSTV0910_P2_EQUAQ3 0xf275 +#define FSTV0910_P2_EQUA_ACCQ3 0xf27501ff + +/*P2_EQUAI4*/ +#define RSTV0910_P2_EQUAI4 0xf276 +#define FSTV0910_P2_EQUA_ACCI4 0xf27601ff + +/*P2_EQUAQ4*/ +#define RSTV0910_P2_EQUAQ4 0xf277 +#define FSTV0910_P2_EQUA_ACCQ4 0xf27701ff + +/*P2_EQUAI5*/ +#define RSTV0910_P2_EQUAI5 0xf278 +#define FSTV0910_P2_EQUA_ACCI5 0xf27801ff + +/*P2_EQUAQ5*/ +#define RSTV0910_P2_EQUAQ5 0xf279 +#define FSTV0910_P2_EQUA_ACCQ5 0xf27901ff + +/*P2_EQUAI6*/ +#define RSTV0910_P2_EQUAI6 0xf27a +#define FSTV0910_P2_EQUA_ACCI6 0xf27a01ff + +/*P2_EQUAQ6*/ +#define RSTV0910_P2_EQUAQ6 0xf27b +#define FSTV0910_P2_EQUA_ACCQ6 0xf27b01ff + +/*P2_EQUAI7*/ +#define RSTV0910_P2_EQUAI7 0xf27c +#define FSTV0910_P2_EQUA_ACCI7 0xf27c01ff + +/*P2_EQUAQ7*/ +#define RSTV0910_P2_EQUAQ7 0xf27d +#define FSTV0910_P2_EQUA_ACCQ7 0xf27d01ff + +/*P2_EQUAI8*/ +#define RSTV0910_P2_EQUAI8 0xf27e +#define FSTV0910_P2_EQUA_ACCI8 0xf27e01ff + +/*P2_EQUAQ8*/ +#define RSTV0910_P2_EQUAQ8 0xf27f +#define FSTV0910_P2_EQUA_ACCQ8 0xf27f01ff + +/*P2_NNOSDATAT1*/ +#define RSTV0910_P2_NNOSDATAT1 0xf280 +#define FSTV0910_P2_NOSDATAT_NORMED1 0xf28000ff + +/*P2_NNOSDATAT0*/ +#define RSTV0910_P2_NNOSDATAT0 0xf281 +#define FSTV0910_P2_NOSDATAT_NORMED0 0xf28100ff + +/*P2_NNOSDATA1*/ +#define RSTV0910_P2_NNOSDATA1 0xf282 +#define FSTV0910_P2_NOSDATA_NORMED1 0xf28200ff + +/*P2_NNOSDATA0*/ +#define RSTV0910_P2_NNOSDATA0 0xf283 +#define FSTV0910_P2_NOSDATA_NORMED0 0xf28300ff + +/*P2_NNOSPLHT1*/ +#define RSTV0910_P2_NNOSPLHT1 0xf284 +#define FSTV0910_P2_NOSPLHT_NORMED1 0xf28400ff + +/*P2_NNOSPLHT0*/ +#define RSTV0910_P2_NNOSPLHT0 0xf285 +#define FSTV0910_P2_NOSPLHT_NORMED0 0xf28500ff + +/*P2_NNOSPLH1*/ +#define RSTV0910_P2_NNOSPLH1 0xf286 +#define FSTV0910_P2_NOSPLH_NORMED1 0xf28600ff + +/*P2_NNOSPLH0*/ +#define RSTV0910_P2_NNOSPLH0 0xf287 +#define FSTV0910_P2_NOSPLH_NORMED0 0xf28700ff + +/*P2_NOSDATAT1*/ +#define RSTV0910_P2_NOSDATAT1 0xf288 +#define FSTV0910_P2_NOSDATAT_UNNORMED1 0xf28800ff + +/*P2_NOSDATAT0*/ +#define RSTV0910_P2_NOSDATAT0 0xf289 +#define FSTV0910_P2_NOSDATAT_UNNORMED0 0xf28900ff + +/*P2_NNOSFRAME1*/ +#define RSTV0910_P2_NNOSFRAME1 0xf28a +#define FSTV0910_P2_NOSFRAME_NORMED1 0xf28a00ff + +/*P2_NNOSFRAME0*/ +#define RSTV0910_P2_NNOSFRAME0 0xf28b +#define FSTV0910_P2_NOSFRAME_NORMED0 0xf28b00ff + +/*P2_NNOSRAD1*/ +#define RSTV0910_P2_NNOSRAD1 0xf28c +#define FSTV0910_P2_NOSRADIAL_NORMED1 0xf28c00ff + +/*P2_NNOSRAD0*/ +#define RSTV0910_P2_NNOSRAD0 0xf28d +#define FSTV0910_P2_NOSRADIAL_NORMED0 0xf28d00ff + +/*P2_NOSCFGF1*/ +#define RSTV0910_P2_NOSCFGF1 0xf28e +#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080 +#define FSTV0910_P2_NOS_DELFRAME 0xf28e0040 +#define FSTV0910_P2_NOSDATA_MODE 0xf28e0030 +#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c +#define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003 + +/*P2_NOSCFGF2*/ +#define RSTV0910_P2_NOSCFGF2 0xf28f +#define FSTV0910_P2_DIS_NOSPILOTS 0xf28f0080 +#define FSTV0910_P2_FRAMESEL_MODCODSEL 0xf28f0060 +#define FSTV0910_P2_FRAMESEL_MODCOD 0xf28f001f + +/*P2_CAR2CFG*/ +#define RSTV0910_P2_CAR2CFG 0xf290 +#define FSTV0910_P2_ROTA2ON 0xf2900004 +#define FSTV0910_P2_PH_DET_ALGO2 0xf2900003 + +/*P2_CFR2CFR1*/ +#define RSTV0910_P2_CFR2CFR1 0xf291 +#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020 +#define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007 + +/*P2_CAR3CFG*/ +#define RSTV0910_P2_CAR3CFG 0xf292 +#define FSTV0910_P2_CARRIER23_MODE 0xf29200c0 +#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020 +#define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018 +#define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007 + +/*P2_CFR22*/ +#define RSTV0910_P2_CFR22 0xf293 +#define FSTV0910_P2_CAR2_FREQ2 0xf29301ff + +/*P2_CFR21*/ +#define RSTV0910_P2_CFR21 0xf294 +#define FSTV0910_P2_CAR2_FREQ1 0xf29400ff + +/*P2_CFR20*/ +#define RSTV0910_P2_CFR20 0xf295 +#define FSTV0910_P2_CAR2_FREQ0 0xf29500ff + +/*P2_ACLC2S2Q*/ +#define RSTV0910_P2_ACLC2S2Q 0xf297 +#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080 +#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030 +#define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f + +/*P2_ACLC2S28*/ +#define RSTV0910_P2_ACLC2S28 0xf298 +#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030 +#define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f + +/*P2_ACLC2S216A*/ +#define RSTV0910_P2_ACLC2S216A 0xf299 +#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030 +#define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f + +/*P2_ACLC2S232A*/ +#define RSTV0910_P2_ACLC2S232A 0xf29a +#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030 +#define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f + +/*P2_BCLC2S2Q*/ +#define RSTV0910_P2_BCLC2S2Q 0xf29c +#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030 +#define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f + +/*P2_BCLC2S28*/ +#define RSTV0910_P2_BCLC2S28 0xf29d +#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030 +#define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f + +/*P2_BCLC2S216A*/ +#define RSTV0910_P2_BCLC2S216A 0xf29e +#define FSTV0910_P2_DVBS2S216A_NIP 0xf29e0080 +#define FSTV0910_P2_CAR2S2_16A_BETA_M 0xf29e0030 +#define FSTV0910_P2_CAR2S2_16A_BETA_E 0xf29e000f + +/*P2_BCLC2S232A*/ +#define RSTV0910_P2_BCLC2S232A 0xf29f +#define FSTV0910_P2_DVBS2S232A_NIP 0xf29f0080 +#define FSTV0910_P2_CAR2S2_32A_BETA_M 0xf29f0030 +#define FSTV0910_P2_CAR2S2_32A_BETA_E 0xf29f000f + +/*P2_PLROOT2*/ +#define RSTV0910_P2_PLROOT2 0xf2ac +#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c +#define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003 + +/*P2_PLROOT1*/ +#define RSTV0910_P2_PLROOT1 0xf2ad +#define FSTV0910_P2_PLSCRAMB_ROOT1 0xf2ad00ff + +/*P2_PLROOT0*/ +#define RSTV0910_P2_PLROOT0 0xf2ae +#define FSTV0910_P2_PLSCRAMB_ROOT0 0xf2ae00ff + +/*P2_MODCODLST0*/ +#define RSTV0910_P2_MODCODLST0 0xf2b0 +#define FSTV0910_P2_NACCES_MODCODCH 0xf2b00001 + +/*P2_MODCODLST1*/ +#define RSTV0910_P2_MODCODLST1 0xf2b1 +#define FSTV0910_P2_SYMBRATE_FILTER 0xf2b10008 +#define FSTV0910_P2_NRESET_MODCODLST 0xf2b10004 +#define FSTV0910_P2_DIS_32PSK_9_10 0xf2b10003 + +/*P2_MODCODLST2*/ +#define RSTV0910_P2_MODCODLST2 0xf2b2 +#define FSTV0910_P2_DIS_32PSK_8_9 0xf2b200f0 +#define FSTV0910_P2_DIS_32PSK_5_6 0xf2b2000f + +/*P2_MODCODLST3*/ +#define RSTV0910_P2_MODCODLST3 0xf2b3 +#define FSTV0910_P2_DIS_32PSK_4_5 0xf2b300f0 +#define FSTV0910_P2_DIS_32PSK_3_4 0xf2b3000f + +/*P2_MODCODLST4*/ +#define RSTV0910_P2_MODCODLST4 0xf2b4 +#define FSTV0910_P2_DUMMYPL_PILOT 0xf2b40080 +#define FSTV0910_P2_DUMMYPL_NOPILOT 0xf2b40040 +#define FSTV0910_P2_DIS_16PSK_9_10 0xf2b40030 +#define FSTV0910_P2_DIS_16PSK_8_9 0xf2b4000f + +/*P2_MODCODLST5*/ +#define RSTV0910_P2_MODCODLST5 0xf2b5 +#define FSTV0910_P2_DIS_16PSK_5_6 0xf2b500f0 +#define FSTV0910_P2_DIS_16PSK_4_5 0xf2b5000f + +/*P2_MODCODLST6*/ +#define RSTV0910_P2_MODCODLST6 0xf2b6 +#define FSTV0910_P2_DIS_16PSK_3_4 0xf2b600f0 +#define FSTV0910_P2_DIS_16PSK_2_3 0xf2b6000f + +/*P2_MODCODLST7*/ +#define RSTV0910_P2_MODCODLST7 0xf2b7 +#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080 +#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030 +#define FSTV0910_P2_DIS_8PSK_8_9 0xf2b7000f + +/*P2_MODCODLST8*/ +#define RSTV0910_P2_MODCODLST8 0xf2b8 +#define FSTV0910_P2_DIS_8PSK_5_6 0xf2b800f0 +#define FSTV0910_P2_DIS_8PSK_3_4 0xf2b8000f + +/*P2_MODCODLST9*/ +#define RSTV0910_P2_MODCODLST9 0xf2b9 +#define FSTV0910_P2_DIS_8PSK_2_3 0xf2b900f0 +#define FSTV0910_P2_DIS_8PSK_3_5 0xf2b9000f + +/*P2_MODCODLSTA*/ +#define RSTV0910_P2_MODCODLSTA 0xf2ba +#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080 +#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030 +#define FSTV0910_P2_DIS_QPSK_8_9 0xf2ba000f + +/*P2_MODCODLSTB*/ +#define RSTV0910_P2_MODCODLSTB 0xf2bb +#define FSTV0910_P2_DIS_QPSK_5_6 0xf2bb00f0 +#define FSTV0910_P2_DIS_QPSK_4_5 0xf2bb000f + +/*P2_MODCODLSTC*/ +#define RSTV0910_P2_MODCODLSTC 0xf2bc +#define FSTV0910_P2_DIS_QPSK_3_4 0xf2bc00f0 +#define FSTV0910_P2_DIS_QPSK_2_3 0xf2bc000f + +/*P2_MODCODLSTD*/ +#define RSTV0910_P2_MODCODLSTD 0xf2bd +#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0 +#define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f + +/*P2_MODCODLSTE*/ +#define RSTV0910_P2_MODCODLSTE 0xf2be +#define FSTV0910_P2_DIS_QPSK_2_5 0xf2be00f0 +#define FSTV0910_P2_DIS_QPSK_1_3 0xf2be000f + +/*P2_MODCODLSTF*/ +#define RSTV0910_P2_MODCODLSTF 0xf2bf +#define FSTV0910_P2_DIS_QPSK_1_4 0xf2bf00f0 +#define FSTV0910_P2_DEMOD_INVMODLST 0xf2bf0008 +#define FSTV0910_P2_DEMODOUT_ENABLE 0xf2bf0004 +#define FSTV0910_P2_DDEMOD_NSET 0xf2bf0002 +#define FSTV0910_P2_MODCOD_NSTOCK 0xf2bf0001 + +/*P2_GAUSSR0*/ +#define RSTV0910_P2_GAUSSR0 0xf2c0 +#define FSTV0910_P2_EN_CCIMODE 0xf2c00080 +#define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f + +/*P2_CCIR0*/ +#define RSTV0910_P2_CCIR0 0xf2c1 +#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080 +#define FSTV0910_P2_R0_CCI 0xf2c1007f + +/*P2_CCIQUANT*/ +#define RSTV0910_P2_CCIQUANT 0xf2c2 +#define FSTV0910_P2_CCI_BETA 0xf2c200e0 +#define FSTV0910_P2_CCI_QUANT 0xf2c2001f + +/*P2_CCITHRES*/ +#define RSTV0910_P2_CCITHRES 0xf2c3 +#define FSTV0910_P2_CCI_THRESHOLD 0xf2c300ff + +/*P2_CCIACC*/ +#define RSTV0910_P2_CCIACC 0xf2c4 +#define FSTV0910_P2_CCI_VALUE 0xf2c400ff + +/*P2_DSTATUS4*/ +#define RSTV0910_P2_DSTATUS4 0xf2c5 +#define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080 +#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040 +#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c50020 +#define FSTV0910_P2_DMDPROG_ERROR 0xf2c50004 +#define FSTV0910_P2_CSTENV_DETECT 0xf2c50002 +#define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001 + +/*P2_DMDRESCFG*/ +#define RSTV0910_P2_DMDRESCFG 0xf2c6 +#define FSTV0910_P2_DMDRES_RESET 0xf2c60080 +#define FSTV0910_P2_DMDRES_STRALL 0xf2c60008 +#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004 +#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002 + +/*P2_DMDRESADR*/ +#define RSTV0910_P2_DMDRESADR 0xf2c7 +#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040 +#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030 +#define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f + +/*P2_DMDRESDATA7*/ +#define RSTV0910_P2_DMDRESDATA7 0xf2c8 +#define FSTV0910_P2_DMDRES_DATA7 0xf2c800ff + +/*P2_DMDRESDATA6*/ +#define RSTV0910_P2_DMDRESDATA6 0xf2c9 +#define FSTV0910_P2_DMDRES_DATA6 0xf2c900ff + +/*P2_DMDRESDATA5*/ +#define RSTV0910_P2_DMDRESDATA5 0xf2ca +#define FSTV0910_P2_DMDRES_DATA5 0xf2ca00ff + +/*P2_DMDRESDATA4*/ +#define RSTV0910_P2_DMDRESDATA4 0xf2cb +#define FSTV0910_P2_DMDRES_DATA4 0xf2cb00ff + +/*P2_DMDRESDATA3*/ +#define RSTV0910_P2_DMDRESDATA3 0xf2cc +#define FSTV0910_P2_DMDRES_DATA3 0xf2cc00ff + +/*P2_DMDRESDATA2*/ +#define RSTV0910_P2_DMDRESDATA2 0xf2cd +#define FSTV0910_P2_DMDRES_DATA2 0xf2cd00ff + +/*P2_DMDRESDATA1*/ +#define RSTV0910_P2_DMDRESDATA1 0xf2ce +#define FSTV0910_P2_DMDRES_DATA1 0xf2ce00ff + +/*P2_DMDRESDATA0*/ +#define RSTV0910_P2_DMDRESDATA0 0xf2cf +#define FSTV0910_P2_DMDRES_DATA0 0xf2cf00ff + +/*P2_FFEI1*/ +#define RSTV0910_P2_FFEI1 0xf2d0 +#define FSTV0910_P2_FFE_ACCI1 0xf2d001ff + +/*P2_FFEQ1*/ +#define RSTV0910_P2_FFEQ1 0xf2d1 +#define FSTV0910_P2_FFE_ACCQ1 0xf2d101ff + +/*P2_FFEI2*/ +#define RSTV0910_P2_FFEI2 0xf2d2 +#define FSTV0910_P2_FFE_ACCI2 0xf2d201ff + +/*P2_FFEQ2*/ +#define RSTV0910_P2_FFEQ2 0xf2d3 +#define FSTV0910_P2_FFE_ACCQ2 0xf2d301ff + +/*P2_FFEI3*/ +#define RSTV0910_P2_FFEI3 0xf2d4 +#define FSTV0910_P2_FFE_ACCI3 0xf2d401ff + +/*P2_FFEQ3*/ +#define RSTV0910_P2_FFEQ3 0xf2d5 +#define FSTV0910_P2_FFE_ACCQ3 0xf2d501ff + +/*P2_FFEI4*/ +#define RSTV0910_P2_FFEI4 0xf2d6 +#define FSTV0910_P2_FFE_ACCI4 0xf2d601ff + +/*P2_FFEQ4*/ +#define RSTV0910_P2_FFEQ4 0xf2d7 +#define FSTV0910_P2_FFE_ACCQ4 0xf2d701ff + +/*P2_FFECFG*/ +#define RSTV0910_P2_FFECFG 0xf2d8 +#define FSTV0910_P2_EQUALFFE_ON 0xf2d80040 +#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030 +#define FSTV0910_P2_MU_EQUALFFE 0xf2d80007 + +/*P2_TNRCFG2*/ +#define RSTV0910_P2_TNRCFG2 0xf2e1 +#define FSTV0910_P2_TUN_IQSWAP 0xf2e10080 + +/*P2_SMAPCOEF7*/ +#define RSTV0910_P2_SMAPCOEF7 0xf300 +#define FSTV0910_P2_DIS_QSCALE 0xf3000080 +#define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f + +/*P2_SMAPCOEF6*/ +#define RSTV0910_P2_SMAPCOEF6 0xf301 +#define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080 +#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004 +#define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002 +#define FSTV0910_P2_DIS_AB8PSK 0xf3010001 + +/*P2_SMAPCOEF5*/ +#define RSTV0910_P2_SMAPCOEF5 0xf302 +#define FSTV0910_P2_DIS_8SCALE 0xf3020080 +#define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f + +/*P2_SMAPCOEF4*/ +#define RSTV0910_P2_SMAPCOEF4 0xf303 +#define FSTV0910_P2_SMAPCOEF_16APSK_LLR12 0xf303017f + +/*P2_SMAPCOEF3*/ +#define RSTV0910_P2_SMAPCOEF3 0xf304 +#define FSTV0910_P2_SMAPCOEF_16APSK_LLR34 0xf304017f + +/*P2_SMAPCOEF2*/ +#define RSTV0910_P2_SMAPCOEF2 0xf305 +#define FSTV0910_P2_SMAPCOEF_32APSK_R2R3 0xf30501f0 +#define FSTV0910_P2_SMAPCOEF_32APSK_LLR2 0xf305010f + +/*P2_SMAPCOEF1*/ +#define RSTV0910_P2_SMAPCOEF1 0xf306 +#define FSTV0910_P2_DIS_16SCALE 0xf3060080 +#define FSTV0910_P2_SMAPCOEF_32_LLR34 0xf306017f + +/*P2_SMAPCOEF0*/ +#define RSTV0910_P2_SMAPCOEF0 0xf307 +#define FSTV0910_P2_DIS_32SCALE 0xf3070080 +#define FSTV0910_P2_SMAPCOEF_32_LLR15 0xf307017f + +/*P2_NOSTHRES1*/ +#define RSTV0910_P2_NOSTHRES1 0xf309 +#define FSTV0910_P2_NOS_THRESHOLD1 0xf30900ff + +/*P2_NOSTHRES2*/ +#define RSTV0910_P2_NOSTHRES2 0xf30a +#define FSTV0910_P2_NOS_THRESHOLD2 0xf30a00ff + +/*P2_NOSDIFF1*/ +#define RSTV0910_P2_NOSDIFF1 0xf30b +#define FSTV0910_P2_NOSTHRES1_DIFF 0xf30b00ff + +/*P2_RAINFADE*/ +#define RSTV0910_P2_RAINFADE 0xf30c +#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080 +#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070 +#define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007 + +/*P2_NOSRAMCFG*/ +#define RSTV0910_P2_NOSRAMCFG 0xf30d +#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030 +#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008 +#define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007 + +/*P2_NOSRAMPOS*/ +#define RSTV0910_P2_NOSRAMPOS 0xf30e +#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0 +#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 +#define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003 + +/*P2_NOSRAMVAL*/ +#define RSTV0910_P2_NOSRAMVAL 0xf30f +#define FSTV0910_P2_NOSRAM_CNRVAL0 0xf30f00ff + +/*P2_DMDPLHSTAT*/ +#define RSTV0910_P2_DMDPLHSTAT 0xf320 +#define FSTV0910_P2_PLH_STATISTIC 0xf32000ff + +/*P2_LOCKTIME3*/ +#define RSTV0910_P2_LOCKTIME3 0xf322 +#define FSTV0910_P2_DEMOD_LOCKTIME3 0xf32200ff + +/*P2_LOCKTIME2*/ +#define RSTV0910_P2_LOCKTIME2 0xf323 +#define FSTV0910_P2_DEMOD_LOCKTIME2 0xf32300ff + +/*P2_LOCKTIME1*/ +#define RSTV0910_P2_LOCKTIME1 0xf324 +#define FSTV0910_P2_DEMOD_LOCKTIME1 0xf32400ff + +/*P2_LOCKTIME0*/ +#define RSTV0910_P2_LOCKTIME0 0xf325 +#define FSTV0910_P2_DEMOD_LOCKTIME0 0xf32500ff + +/*P2_VITSCALE*/ +#define RSTV0910_P2_VITSCALE 0xf332 +#define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080 +#define FSTV0910_P2_VERROR_MAXMODE 0xf3320040 +#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008 +#define FSTV0910_P2_DIS_RSFLOCK 0xf3320002 + +/*P2_FECM*/ +#define RSTV0910_P2_FECM 0xf333 +#define FSTV0910_P2_DSS_DVB 0xf3330080 +#define FSTV0910_P2_DSS_SRCH 0xf3330010 +#define FSTV0910_P2_SYNCVIT 0xf3330002 +#define FSTV0910_P2_IQINV 0xf3330001 + +/*P2_VTH12*/ +#define RSTV0910_P2_VTH12 0xf334 +#define FSTV0910_P2_VTH12 0xf33400ff + +/*P2_VTH23*/ +#define RSTV0910_P2_VTH23 0xf335 +#define FSTV0910_P2_VTH23 0xf33500ff + +/*P2_VTH34*/ +#define RSTV0910_P2_VTH34 0xf336 +#define FSTV0910_P2_VTH34 0xf33600ff + +/*P2_VTH56*/ +#define RSTV0910_P2_VTH56 0xf337 +#define FSTV0910_P2_VTH56 0xf33700ff + +/*P2_VTH67*/ +#define RSTV0910_P2_VTH67 0xf338 +#define FSTV0910_P2_VTH67 0xf33800ff + +/*P2_VTH78*/ +#define RSTV0910_P2_VTH78 0xf339 +#define FSTV0910_P2_VTH78 0xf33900ff + +/*P2_VITCURPUN*/ +#define RSTV0910_P2_VITCURPUN 0xf33a +#define FSTV0910_P2_VIT_CURPUN 0xf33a001f + +/*P2_VERROR*/ +#define RSTV0910_P2_VERROR 0xf33b +#define FSTV0910_P2_REGERR_VIT 0xf33b00ff + +/*P2_PRVIT*/ +#define RSTV0910_P2_PRVIT 0xf33c +#define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040 +#define FSTV0910_P2_E7_8VIT 0xf33c0020 +#define FSTV0910_P2_E6_7VIT 0xf33c0010 +#define FSTV0910_P2_E5_6VIT 0xf33c0008 +#define FSTV0910_P2_E3_4VIT 0xf33c0004 +#define FSTV0910_P2_E2_3VIT 0xf33c0002 +#define FSTV0910_P2_E1_2VIT 0xf33c0001 + +/*P2_VAVSRVIT*/ +#define RSTV0910_P2_VAVSRVIT 0xf33d +#define FSTV0910_P2_AMVIT 0xf33d0080 +#define FSTV0910_P2_FROZENVIT 0xf33d0040 +#define FSTV0910_P2_SNVIT 0xf33d0030 +#define FSTV0910_P2_TOVVIT 0xf33d000c +#define FSTV0910_P2_HYPVIT 0xf33d0003 + +/*P2_VSTATUSVIT*/ +#define RSTV0910_P2_VSTATUSVIT 0xf33e +#define FSTV0910_P2_PRFVIT 0xf33e0010 +#define FSTV0910_P2_LOCKEDVIT 0xf33e0008 + +/*P2_VTHINUSE*/ +#define RSTV0910_P2_VTHINUSE 0xf33f +#define FSTV0910_P2_VIT_INUSE 0xf33f00ff + +/*P2_KDIV12*/ +#define RSTV0910_P2_KDIV12 0xf340 +#define FSTV0910_P2_K_DIVIDER_12 0xf340007f + +/*P2_KDIV23*/ +#define RSTV0910_P2_KDIV23 0xf341 +#define FSTV0910_P2_K_DIVIDER_23 0xf341007f + +/*P2_KDIV34*/ +#define RSTV0910_P2_KDIV34 0xf342 +#define FSTV0910_P2_K_DIVIDER_34 0xf342007f + +/*P2_KDIV56*/ +#define RSTV0910_P2_KDIV56 0xf343 +#define FSTV0910_P2_K_DIVIDER_56 0xf343007f + +/*P2_KDIV67*/ +#define RSTV0910_P2_KDIV67 0xf344 +#define FSTV0910_P2_K_DIVIDER_67 0xf344007f + +/*P2_KDIV78*/ +#define RSTV0910_P2_KDIV78 0xf345 +#define FSTV0910_P2_K_DIVIDER_78 0xf345007f + +/*P2_TSPIDFLT1*/ +#define RSTV0910_P2_TSPIDFLT1 0xf346 +#define FSTV0910_P2_PIDFLT_ADDR 0xf34600ff + +/*P2_TSPIDFLT0*/ +#define RSTV0910_P2_TSPIDFLT0 0xf347 +#define FSTV0910_P2_PIDFLT_DATA 0xf34700ff + +/*P2_PDELCTRL0*/ +#define RSTV0910_P2_PDELCTRL0 0xf34f +#define FSTV0910_P2_ISIOBS_MODE 0xf34f0030 + +/*P2_PDELCTRL1*/ +#define RSTV0910_P2_PDELCTRL1 0xf350 +#define FSTV0910_P2_INV_MISMASK 0xf3500080 +#define FSTV0910_P2_FILTER_EN 0xf3500020 +#define FSTV0910_P2_HYSTEN 0xf3500008 +#define FSTV0910_P2_HYSTSWRST 0xf3500004 +#define FSTV0910_P2_EN_MIS00 0xf3500002 +#define FSTV0910_P2_ALGOSWRST 0xf3500001 + +/*P2_PDELCTRL2*/ +#define RSTV0910_P2_PDELCTRL2 0xf351 +#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080 +#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040 +#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020 +#define FSTV0910_P2_FRAME_MODE 0xf3510002 + +/*P2_HYSTTHRESH*/ +#define RSTV0910_P2_HYSTTHRESH 0xf354 +#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0 +#define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f + +/*P2_UPLCCST0*/ +#define RSTV0910_P2_UPLCCST0 0xf358 +#define FSTV0910_P2_UPL_CST0 0xf35800f8 +#define FSTV0910_P2_UPL_MODE 0xf3580007 + +/*P2_ISIENTRY*/ +#define RSTV0910_P2_ISIENTRY 0xf35e +#define FSTV0910_P2_ISI_ENTRY 0xf35e00ff + +/*P2_ISIBITENA*/ +#define RSTV0910_P2_ISIBITENA 0xf35f +#define FSTV0910_P2_ISI_BIT_EN 0xf35f00ff + +/*P2_MATSTR1*/ +#define RSTV0910_P2_MATSTR1 0xf360 +#define FSTV0910_P2_MATYPE_CURRENT1 0xf36000ff + +/*P2_MATSTR0*/ +#define RSTV0910_P2_MATSTR0 0xf361 +#define FSTV0910_P2_MATYPE_CURRENT0 0xf36100ff + +/*P2_UPLSTR1*/ +#define RSTV0910_P2_UPLSTR1 0xf362 +#define FSTV0910_P2_UPL_CURRENT1 0xf36200ff + +/*P2_UPLSTR0*/ +#define RSTV0910_P2_UPLSTR0 0xf363 +#define FSTV0910_P2_UPL_CURRENT0 0xf36300ff + +/*P2_DFLSTR1*/ +#define RSTV0910_P2_DFLSTR1 0xf364 +#define FSTV0910_P2_DFL_CURRENT1 0xf36400ff + +/*P2_DFLSTR0*/ +#define RSTV0910_P2_DFLSTR0 0xf365 +#define FSTV0910_P2_DFL_CURRENT0 0xf36500ff + +/*P2_SYNCSTR*/ +#define RSTV0910_P2_SYNCSTR 0xf366 +#define FSTV0910_P2_SYNC_CURRENT 0xf36600ff + +/*P2_SYNCDSTR1*/ +#define RSTV0910_P2_SYNCDSTR1 0xf367 +#define FSTV0910_P2_SYNCD_CURRENT1 0xf36700ff + +/*P2_SYNCDSTR0*/ +#define RSTV0910_P2_SYNCDSTR0 0xf368 +#define FSTV0910_P2_SYNCD_CURRENT0 0xf36800ff + +/*P2_PDELSTATUS1*/ +#define RSTV0910_P2_PDELSTATUS1 0xf369 +#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080 +#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040 +#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3690010 +#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3690008 +#define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002 +#define FSTV0910_P2_FIRST_LOCK 0xf3690001 + +/*P2_PDELSTATUS2*/ +#define RSTV0910_P2_PDELSTATUS2 0xf36a +#define FSTV0910_P2_FRAME_MODCOD 0xf36a007c +#define FSTV0910_P2_FRAME_TYPE 0xf36a0003 + +/*P2_BBFCRCKO1*/ +#define RSTV0910_P2_BBFCRCKO1 0xf36b +#define FSTV0910_P2_BBHCRC_KOCNT1 0xf36b00ff + +/*P2_BBFCRCKO0*/ +#define RSTV0910_P2_BBFCRCKO0 0xf36c +#define FSTV0910_P2_BBHCRC_KOCNT0 0xf36c00ff + +/*P2_UPCRCKO1*/ +#define RSTV0910_P2_UPCRCKO1 0xf36d +#define FSTV0910_P2_PKTCRC_KOCNT1 0xf36d00ff + +/*P2_UPCRCKO0*/ +#define RSTV0910_P2_UPCRCKO0 0xf36e +#define FSTV0910_P2_PKTCRC_KOCNT0 0xf36e00ff + +/*P2_PDELCTRL3*/ +#define RSTV0910_P2_PDELCTRL3 0xf36f +#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020 +#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010 + +/*P2_TSSTATEM*/ +#define RSTV0910_P2_TSSTATEM 0xf370 +#define FSTV0910_P2_TSDIL_ON 0xf3700080 +#define FSTV0910_P2_TSRS_ON 0xf3700020 +#define FSTV0910_P2_TSDESCRAMB_ON 0xf3700010 +#define FSTV0910_P2_TSFRAME_MODE 0xf3700008 +#define FSTV0910_P2_TS_DISABLE 0xf3700004 +#define FSTV0910_P2_TSACM_MODE 0xf3700002 +#define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001 + +/*P2_TSSTATEL*/ +#define RSTV0910_P2_TSSTATEL 0xf371 +#define FSTV0910_P2_TSNOSYNCBYTE 0xf3710080 +#define FSTV0910_P2_TSPARITY_ON 0xf3710040 +#define FSTV0910_P2_TSISSYI_ON 0xf3710008 +#define FSTV0910_P2_TSNPD_ON 0xf3710004 +#define FSTV0910_P2_TSCRC8_ON 0xf3710002 +#define FSTV0910_P2_TSDSS_PACKET 0xf3710001 + +/*P2_TSCFGH*/ +#define RSTV0910_P2_TSCFGH 0xf372 +#define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080 +#define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040 +#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3720020 +#define FSTV0910_P2_TSFIFO_DUTY50 0xf3720010 +#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3720008 +#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006 +#define FSTV0910_P2_RST_HWARE 0xf3720001 + +/*P2_TSCFGM*/ +#define RSTV0910_P2_TSCFGM 0xf373 +#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0 +#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020 +#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010 +#define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001 + +/*P2_TSCFGL*/ +#define RSTV0910_P2_TSCFGL 0xf374 +#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 +#define FSTV0910_P2_BCHERROR_MODE 0xf3740030 +#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3740008 +#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004 +#define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003 + +/*P2_TSSYNC*/ +#define RSTV0910_P2_TSSYNC 0xf375 +#define FSTV0910_P2_TSFIFO_SYNCMODE 0xf3750018 + +/*P2_TSINSDELH*/ +#define RSTV0910_P2_TSINSDELH 0xf376 +#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080 +#define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040 +#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3760010 +#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002 +#define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001 + +/*P2_TSINSDELM*/ +#define RSTV0910_P2_TSINSDELM 0xf377 +#define FSTV0910_P2_TSINS_EMODCOD 0xf3770010 +#define FSTV0910_P2_TSINS_TOKEN 0xf3770008 +#define FSTV0910_P2_TSINS_XXXERR 0xf3770004 +#define FSTV0910_P2_TSINS_MATYPE 0xf3770002 +#define FSTV0910_P2_TSINS_UPL 0xf3770001 + +/*P2_TSINSDELL*/ +#define RSTV0910_P2_TSINSDELL 0xf378 +#define FSTV0910_P2_TSINS_DFL 0xf3780080 +#define FSTV0910_P2_TSINS_SYNCD 0xf3780040 +#define FSTV0910_P2_TSINS_BLOCLEN 0xf3780020 +#define FSTV0910_P2_TSINS_SIGPCOUNT 0xf3780010 +#define FSTV0910_P2_TSINS_FIFO 0xf3780008 +#define FSTV0910_P2_TSINS_REALPACK 0xf3780004 +#define FSTV0910_P2_TSINS_TSCONFIG 0xf3780002 +#define FSTV0910_P2_TSINS_LATENCY 0xf3780001 + +/*P2_TSDIVN*/ +#define RSTV0910_P2_TSDIVN 0xf379 +#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0 +#define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007 + +/*P2_TSCFG4*/ +#define RSTV0910_P2_TSCFG4 0xf37a +#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 + +/*P2_TSSPEED*/ +#define RSTV0910_P2_TSSPEED 0xf380 +#define FSTV0910_P2_TSFIFO_OUTSPEED 0xf38000ff + +/*P2_TSSTATUS*/ +#define RSTV0910_P2_TSSTATUS 0xf381 +#define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080 +#define FSTV0910_P2_TSFIFO_ERROR 0xf3810040 +#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3810010 +#define FSTV0910_P2_TSREGUL_ERROR 0xf3810004 +#define FSTV0910_P2_DIL_READY 0xf3810001 + +/*P2_TSSTATUS2*/ +#define RSTV0910_P2_TSSTATUS2 0xf382 +#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080 +#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040 +#define FSTV0910_P2_DILXX_RESET 0xf3820020 +#define FSTV0910_P2_SCRAMBDETECT 0xf3820002 + +/*P2_TSBITRATE1*/ +#define RSTV0910_P2_TSBITRATE1 0xf383 +#define FSTV0910_P2_TSFIFO_BITRATE1 0xf38300ff + +/*P2_TSBITRATE0*/ +#define RSTV0910_P2_TSBITRATE0 0xf384 +#define FSTV0910_P2_TSFIFO_BITRATE0 0xf38400ff + +/*P2_TSPACKLEN1*/ +#define RSTV0910_P2_TSPACKLEN1 0xf385 +#define FSTV0910_P2_TSFIFO_PACKCPT 0xf38500e0 + +/*P2_TSDLY2*/ +#define RSTV0910_P2_TSDLY2 0xf389 +#define FSTV0910_P2_SOFFIFO_LATENCY2 0xf389000f + +/*P2_TSDLY1*/ +#define RSTV0910_P2_TSDLY1 0xf38a +#define FSTV0910_P2_SOFFIFO_LATENCY1 0xf38a00ff + +/*P2_TSDLY0*/ +#define RSTV0910_P2_TSDLY0 0xf38b +#define FSTV0910_P2_SOFFIFO_LATENCY0 0xf38b00ff + +/*P2_TSNPDAV*/ +#define RSTV0910_P2_TSNPDAV 0xf38c +#define FSTV0910_P2_TSNPD_AVERAGE 0xf38c00ff + +/*P2_TSBUFSTAT2*/ +#define RSTV0910_P2_TSBUFSTAT2 0xf38d +#define FSTV0910_P2_TSISCR_3BYTES 0xf38d0080 +#define FSTV0910_P2_TSISCR_NEWDATA 0xf38d0040 +#define FSTV0910_P2_TSISCR_BUFSTAT2 0xf38d003f + +/*P2_TSBUFSTAT1*/ +#define RSTV0910_P2_TSBUFSTAT1 0xf38e +#define FSTV0910_P2_TSISCR_BUFSTAT1 0xf38e00ff + +/*P2_TSBUFSTAT0*/ +#define RSTV0910_P2_TSBUFSTAT0 0xf38f +#define FSTV0910_P2_TSISCR_BUFSTAT0 0xf38f00ff + +/*P2_TSDEBUGL*/ +#define RSTV0910_P2_TSDEBUGL 0xf391 +#define FSTV0910_P2_TSFIFO_ERROR_EVNT 0xf3910004 +#define FSTV0910_P2_TSFIFO_OVERFLOWM 0xf3910001 + +/*P2_TSDLYSET2*/ +#define RSTV0910_P2_TSDLYSET2 0xf392 +#define FSTV0910_P2_SOFFIFO_OFFSET 0xf39200c0 +#define FSTV0910_P2_HYSTERESIS_THRESHOLD 0xf3920030 +#define FSTV0910_P2_SOFFIFO_SYMBOFFS2 0xf392000f + +/*P2_TSDLYSET1*/ +#define RSTV0910_P2_TSDLYSET1 0xf393 +#define FSTV0910_P2_SOFFIFO_SYMBOFFS1 0xf39300ff + +/*P2_TSDLYSET0*/ +#define RSTV0910_P2_TSDLYSET0 0xf394 +#define FSTV0910_P2_SOFFIFO_SYMBOFFS0 0xf39400ff + +/*P2_ERRCTRL1*/ +#define RSTV0910_P2_ERRCTRL1 0xf398 +#define FSTV0910_P2_ERR_SOURCE1 0xf39800f0 +#define FSTV0910_P2_NUM_EVENT1 0xf3980007 + +/*P2_ERRCNT12*/ +#define RSTV0910_P2_ERRCNT12 0xf399 +#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080 +#define FSTV0910_P2_ERR_CNT12 0xf399007f + +/*P2_ERRCNT11*/ +#define RSTV0910_P2_ERRCNT11 0xf39a +#define FSTV0910_P2_ERR_CNT11 0xf39a00ff + +/*P2_ERRCNT10*/ +#define RSTV0910_P2_ERRCNT10 0xf39b +#define FSTV0910_P2_ERR_CNT10 0xf39b00ff + +/*P2_ERRCTRL2*/ +#define RSTV0910_P2_ERRCTRL2 0xf39c +#define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0 +#define FSTV0910_P2_NUM_EVENT2 0xf39c0007 + +/*P2_ERRCNT22*/ +#define RSTV0910_P2_ERRCNT22 0xf39d +#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080 +#define FSTV0910_P2_ERR_CNT22 0xf39d007f + +/*P2_ERRCNT21*/ +#define RSTV0910_P2_ERRCNT21 0xf39e +#define FSTV0910_P2_ERR_CNT21 0xf39e00ff + +/*P2_ERRCNT20*/ +#define RSTV0910_P2_ERRCNT20 0xf39f +#define FSTV0910_P2_ERR_CNT20 0xf39f00ff + +/*P2_FECSPY*/ +#define RSTV0910_P2_FECSPY 0xf3a0 +#define FSTV0910_P2_SPY_ENABLE 0xf3a00080 +#define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040 +#define FSTV0910_P2_SERIAL_MODE 0xf3a00020 +#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a00010 +#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0000c +#define FSTV0910_P2_BERMETER_LMODE 0xf3a00002 +#define FSTV0910_P2_BERMETER_RESET 0xf3a00001 + +/*P2_FSPYCFG*/ +#define RSTV0910_P2_FSPYCFG 0xf3a1 +#define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0 +#define FSTV0910_P2_RST_ON_ERROR 0xf3a10020 +#define FSTV0910_P2_ONE_SHOT 0xf3a10010 +#define FSTV0910_P2_I2C_MODE 0xf3a1000c +#define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003 + +/*P2_FSPYDATA*/ +#define RSTV0910_P2_FSPYDATA 0xf3a2 +#define FSTV0910_P2_SPY_STUFFING 0xf3a20080 +#define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020 +#define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f + +/*P2_FSPYOUT*/ +#define RSTV0910_P2_FSPYOUT 0xf3a3 +#define FSTV0910_P2_FSPY_DIRECT 0xf3a30080 +#define FSTV0910_P2_STUFF_MODE 0xf3a30007 + +/*P2_FSTATUS*/ +#define RSTV0910_P2_FSTATUS 0xf3a4 +#define FSTV0910_P2_SPY_ENDSIM 0xf3a40080 +#define FSTV0910_P2_VALID_SIM 0xf3a40040 +#define FSTV0910_P2_FOUND_SIGNAL 0xf3a40020 +#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010 +#define FSTV0910_P2_RESULT_STATE 0xf3a4000f + +/*P2_FBERCPT4*/ +#define RSTV0910_P2_FBERCPT4 0xf3a8 +#define FSTV0910_P2_FBERMETER_CPT4 0xf3a800ff + +/*P2_FBERCPT3*/ +#define RSTV0910_P2_FBERCPT3 0xf3a9 +#define FSTV0910_P2_FBERMETER_CPT3 0xf3a900ff + +/*P2_FBERCPT2*/ +#define RSTV0910_P2_FBERCPT2 0xf3aa +#define FSTV0910_P2_FBERMETER_CPT2 0xf3aa00ff + +/*P2_FBERCPT1*/ +#define RSTV0910_P2_FBERCPT1 0xf3ab +#define FSTV0910_P2_FBERMETER_CPT1 0xf3ab00ff + +/*P2_FBERCPT0*/ +#define RSTV0910_P2_FBERCPT0 0xf3ac +#define FSTV0910_P2_FBERMETER_CPT0 0xf3ac00ff + +/*P2_FBERERR2*/ +#define RSTV0910_P2_FBERERR2 0xf3ad +#define FSTV0910_P2_FBERMETER_ERR2 0xf3ad00ff + +/*P2_FBERERR1*/ +#define RSTV0910_P2_FBERERR1 0xf3ae +#define FSTV0910_P2_FBERMETER_ERR1 0xf3ae00ff + +/*P2_FBERERR0*/ +#define RSTV0910_P2_FBERERR0 0xf3af +#define FSTV0910_P2_FBERMETER_ERR0 0xf3af00ff + +/*P2_FSPYBER*/ +#define RSTV0910_P2_FSPYBER 0xf3b2 +#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010 +#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008 +#define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007 + +/*P2_SFERROR*/ +#define RSTV0910_P2_SFERROR 0xf3c1 +#define FSTV0910_P2_SFEC_REGERR_VIT 0xf3c100ff + +/*P2_SFECSTATUS*/ +#define RSTV0910_P2_SFECSTATUS 0xf3c3 +#define FSTV0910_P2_SFEC_ON 0xf3c30080 +#define FSTV0910_P2_SFEC_OFF 0xf3c30040 +#define FSTV0910_P2_LOCKEDSFEC 0xf3c30008 +#define FSTV0910_P2_SFEC_DELOCK 0xf3c30004 +#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002 +#define FSTV0910_P2_SFEC_OVFON 0xf3c30001 + +/*P2_SFKDIV12*/ +#define RSTV0910_P2_SFKDIV12 0xf3c4 +#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080 + +/*P2_SFKDIV23*/ +#define RSTV0910_P2_SFKDIV23 0xf3c5 +#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080 + +/*P2_SFKDIV34*/ +#define RSTV0910_P2_SFKDIV34 0xf3c6 +#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080 + +/*P2_SFKDIV56*/ +#define RSTV0910_P2_SFKDIV56 0xf3c7 +#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080 + +/*P2_SFKDIV67*/ +#define RSTV0910_P2_SFKDIV67 0xf3c8 +#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080 + +/*P2_SFKDIV78*/ +#define RSTV0910_P2_SFKDIV78 0xf3c9 +#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080 + +/*P2_SFSTATUS*/ +#define RSTV0910_P2_SFSTATUS 0xf3cc +#define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080 +#define FSTV0910_P2_SFEC_ERROR 0xf3cc0040 +#define FSTV0910_P2_SFEC_DATA7 0xf3cc0020 +#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc0010 +#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc0008 +#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc0004 +#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002 +#define FSTV0910_P2_SFEC_READY 0xf3cc0001 + +/*P2_SFDLYSET2*/ +#define RSTV0910_P2_SFDLYSET2 0xf3d0 +#define FSTV0910_P2_SFEC_DISABLE 0xf3d00002 + +/*P2_SFERRCTRL*/ +#define RSTV0910_P2_SFERRCTRL 0xf3d8 +#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0 +#define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007 + +/*P2_SFERRCNT2*/ +#define RSTV0910_P2_SFERRCNT2 0xf3d9 +#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080 +#define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f + +/*P2_SFERRCNT1*/ +#define RSTV0910_P2_SFERRCNT1 0xf3da +#define FSTV0910_P2_SFEC_ERR_CNT1 0xf3da00ff + +/*P2_SFERRCNT0*/ +#define RSTV0910_P2_SFERRCNT0 0xf3db +#define FSTV0910_P2_SFEC_ERR_CNT0 0xf3db00ff + +/*P1_IQCONST*/ +#define RSTV0910_P1_IQCONST 0xf400 +#define FSTV0910_P1_CONSTEL_SELECT 0xf4000060 +#define FSTV0910_P1_IQSYMB_SEL 0xf400001f + +/*P1_NOSCFG*/ +#define RSTV0910_P1_NOSCFG 0xf401 +#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020 +#define FSTV0910_P1_NOSPLH_BETA 0xf4010018 +#define FSTV0910_P1_NOSDATA_BETA 0xf4010007 + +/*P1_ISYMB*/ +#define RSTV0910_P1_ISYMB 0xf402 +#define FSTV0910_P1_I_SYMBOL 0xf40201ff + +/*P1_QSYMB*/ +#define RSTV0910_P1_QSYMB 0xf403 +#define FSTV0910_P1_Q_SYMBOL 0xf40301ff + +/*P1_AGC1CFG*/ +#define RSTV0910_P1_AGC1CFG 0xf404 +#define FSTV0910_P1_DC_FROZEN 0xf4040080 +#define FSTV0910_P1_DC_CORRECT 0xf4040040 +#define FSTV0910_P1_AMM_FROZEN 0xf4040020 +#define FSTV0910_P1_AMM_CORRECT 0xf4040010 +#define FSTV0910_P1_QUAD_FROZEN 0xf4040008 +#define FSTV0910_P1_QUAD_CORRECT 0xf4040004 + +/*P1_AGC1CN*/ +#define RSTV0910_P1_AGC1CN 0xf406 +#define FSTV0910_P1_AGC1_LOCKED 0xf4060080 +#define FSTV0910_P1_AGC1_MINPOWER 0xf4060010 +#define FSTV0910_P1_AGCOUT_FAST 0xf4060008 +#define FSTV0910_P1_AGCIQ_BETA 0xf4060007 + +/*P1_AGC1REF*/ +#define RSTV0910_P1_AGC1REF 0xf407 +#define FSTV0910_P1_AGCIQ_REF 0xf40700ff + +/*P1_IDCCOMP*/ +#define RSTV0910_P1_IDCCOMP 0xf408 +#define FSTV0910_P1_IAVERAGE_ADJ 0xf40801ff + +/*P1_QDCCOMP*/ +#define RSTV0910_P1_QDCCOMP 0xf409 +#define FSTV0910_P1_QAVERAGE_ADJ 0xf40901ff + +/*P1_POWERI*/ +#define RSTV0910_P1_POWERI 0xf40a +#define FSTV0910_P1_POWER_I 0xf40a00ff + +/*P1_POWERQ*/ +#define RSTV0910_P1_POWERQ 0xf40b +#define FSTV0910_P1_POWER_Q 0xf40b00ff + +/*P1_AGC1AMM*/ +#define RSTV0910_P1_AGC1AMM 0xf40c +#define FSTV0910_P1_AMM_VALUE 0xf40c00ff + +/*P1_AGC1QUAD*/ +#define RSTV0910_P1_AGC1QUAD 0xf40d +#define FSTV0910_P1_QUAD_VALUE 0xf40d01ff + +/*P1_AGCIQIN1*/ +#define RSTV0910_P1_AGCIQIN1 0xf40e +#define FSTV0910_P1_AGCIQ_VALUE1 0xf40e00ff + +/*P1_AGCIQIN0*/ +#define RSTV0910_P1_AGCIQIN0 0xf40f +#define FSTV0910_P1_AGCIQ_VALUE0 0xf40f00ff + +/*P1_DEMOD*/ +#define RSTV0910_P1_DEMOD 0xf410 +#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080 +#define FSTV0910_P1_SPECINV_CONTROL 0xf4100030 +#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004 +#define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003 + +/*P1_DMDMODCOD*/ +#define RSTV0910_P1_DMDMODCOD 0xf411 +#define FSTV0910_P1_MANUAL_MODCOD 0xf4110080 +#define FSTV0910_P1_DEMOD_MODCOD 0xf411007c +#define FSTV0910_P1_DEMOD_TYPE 0xf4110003 + +/*P1_DSTATUS*/ +#define RSTV0910_P1_DSTATUS 0xf412 +#define FSTV0910_P1_CAR_LOCK 0xf4120080 +#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060 +#define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008 +#define FSTV0910_P1_OVADC_DETECT 0xf4120001 + +/*P1_DSTATUS2*/ +#define RSTV0910_P1_DSTATUS2 0xf413 +#define FSTV0910_P1_DEMOD_DELOCK 0xf4130080 +#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020 +#define FSTV0910_P1_POLYPH_SATEVENT 0xf4130010 +#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4130008 +#define FSTV0910_P1_AGC2_OVERFLOW 0xf4130004 +#define FSTV0910_P1_CFR_OVERFLOW 0xf4130002 +#define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001 + +/*P1_DMDCFGMD*/ +#define RSTV0910_P1_DMDCFGMD 0xf414 +#define FSTV0910_P1_DVBS2_ENABLE 0xf4140080 +#define FSTV0910_P1_DVBS1_ENABLE 0xf4140040 +#define FSTV0910_P1_SCAN_ENABLE 0xf4140010 +#define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008 +#define FSTV0910_P1_TUN_RNG 0xf4140003 + +/*P1_DMDCFG2*/ +#define RSTV0910_P1_DMDCFG2 0xf415 +#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040 +#define FSTV0910_P1_INFINITE_RELOCK 0xf4150010 + +/*P1_DMDISTATE*/ +#define RSTV0910_P1_DMDISTATE 0xf416 +#define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080 +#define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f + +/*P1_DMDT0M*/ +#define RSTV0910_P1_DMDT0M 0xf417 +#define FSTV0910_P1_DMDT0_MIN 0xf41700ff + +/*P1_DMDSTATE*/ +#define RSTV0910_P1_DMDSTATE 0xf41b +#define FSTV0910_P1_HEADER_MODE 0xf41b0060 + +/*P1_DMDFLYW*/ +#define RSTV0910_P1_DMDFLYW 0xf41c +#define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0 +#define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f + +/*P1_DSTATUS3*/ +#define RSTV0910_P1_DSTATUS3 0xf41d +#define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080 +#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060 +#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010 + +/*P1_DMDCFG3*/ +#define RSTV0910_P1_DMDCFG3 0xf41e +#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008 + +/*P1_DMDCFG4*/ +#define RSTV0910_P1_DMDCFG4 0xf41f +#define FSTV0910_P1_DIS_VITLOCK 0xf41f0080 +#define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004 + +/*P1_CORRELMANT*/ +#define RSTV0910_P1_CORRELMANT 0xf420 +#define FSTV0910_P1_CORREL_MANT 0xf42000ff + +/*P1_CORRELABS*/ +#define RSTV0910_P1_CORRELABS 0xf421 +#define FSTV0910_P1_CORREL_ABS 0xf42100ff + +/*P1_CORRELEXP*/ +#define RSTV0910_P1_CORRELEXP 0xf422 +#define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0 +#define FSTV0910_P1_CORREL_EXP 0xf422000f + +/*P1_PLHMODCOD*/ +#define RSTV0910_P1_PLHMODCOD 0xf424 +#define FSTV0910_P1_SPECINV_DEMOD 0xf4240080 +#define FSTV0910_P1_PLH_MODCOD 0xf424007c +#define FSTV0910_P1_PLH_TYPE 0xf4240003 + +/*P1_DMDREG*/ +#define RSTV0910_P1_DMDREG 0xf425 +#define FSTV0910_P1_DECIM_PLFRAMES 0xf4250001 + +/*P1_AGCNADJ*/ +#define RSTV0910_P1_AGCNADJ 0xf426 +#define FSTV0910_P1_RADJOFF_AGC2 0xf4260080 +#define FSTV0910_P1_RADJOFF_AGC1 0xf4260040 +#define FSTV0910_P1_AGC_NADJ 0xf426013f + +/*P1_AGCKS*/ +#define RSTV0910_P1_AGCKS 0xf427 +#define FSTV0910_P1_RSADJ_MANUALCFG 0xf4270080 +#define FSTV0910_P1_RSADJ_CCMMODE 0xf4270040 +#define FSTV0910_P1_RADJ_SPSK 0xf427013f + +/*P1_AGCKQ*/ +#define RSTV0910_P1_AGCKQ 0xf428 +#define FSTV0910_P1_RADJON_DVBS1 0xf4280040 +#define FSTV0910_P1_RADJ_QPSK 0xf428013f + +/*P1_AGCK8*/ +#define RSTV0910_P1_AGCK8 0xf429 +#define FSTV0910_P1_RADJ_8PSK 0xf429013f + +/*P1_AGCK16*/ +#define RSTV0910_P1_AGCK16 0xf42a +#define FSTV0910_P1_R2ADJOFF_16APSK 0xf42a0040 +#define FSTV0910_P1_R1ADJOFF_16APSK 0xf42a0020 +#define FSTV0910_P1_RADJ_16APSK 0xf42a011f + +/*P1_AGCK32*/ +#define RSTV0910_P1_AGCK32 0xf42b +#define FSTV0910_P1_R3ADJOFF_32APSK 0xf42b0080 +#define FSTV0910_P1_R2ADJOFF_32APSK 0xf42b0040 +#define FSTV0910_P1_R1ADJOFF_32APSK 0xf42b0020 +#define FSTV0910_P1_RADJ_32APSK 0xf42b011f + +/*P1_AGC2O*/ +#define RSTV0910_P1_AGC2O 0xf42c +#define FSTV0910_P1_CSTENV_MODE 0xf42c00c0 +#define FSTV0910_P1_AGC2_COEF 0xf42c0007 + +/*P1_AGC2REF*/ +#define RSTV0910_P1_AGC2REF 0xf42d +#define FSTV0910_P1_AGC2_REF 0xf42d00ff + +/*P1_AGC1ADJ*/ +#define RSTV0910_P1_AGC1ADJ 0xf42e +#define FSTV0910_P1_AGC1_ADJUSTED 0xf42e007f + +/*P1_AGCRSADJ*/ +#define RSTV0910_P1_AGCRSADJ 0xf42f +#define FSTV0910_P1_RS_ADJUSTED 0xf42f007f + +/*P1_AGCRQADJ*/ +#define RSTV0910_P1_AGCRQADJ 0xf430 +#define FSTV0910_P1_RQ_ADJUSTED 0xf430007f + +/*P1_AGCR8ADJ*/ +#define RSTV0910_P1_AGCR8ADJ 0xf431 +#define FSTV0910_P1_R8_ADJUSTED 0xf431007f + +/*P1_AGCR1ADJ*/ +#define RSTV0910_P1_AGCR1ADJ 0xf432 +#define FSTV0910_P1_R1_ADJUSTED 0xf432007f + +/*P1_AGCR2ADJ*/ +#define RSTV0910_P1_AGCR2ADJ 0xf433 +#define FSTV0910_P1_R2_ADJUSTED 0xf433007f + +/*P1_AGCR3ADJ*/ +#define RSTV0910_P1_AGCR3ADJ 0xf434 +#define FSTV0910_P1_R3_ADJUSTED 0xf434007f + +/*P1_AGCREFADJ*/ +#define RSTV0910_P1_AGCREFADJ 0xf435 +#define FSTV0910_P1_AGC2REF_ADJUSTED 0xf435007f + +/*P1_AGC2I1*/ +#define RSTV0910_P1_AGC2I1 0xf436 +#define FSTV0910_P1_AGC2_INTEGRATOR1 0xf43600ff + +/*P1_AGC2I0*/ +#define RSTV0910_P1_AGC2I0 0xf437 +#define FSTV0910_P1_AGC2_INTEGRATOR0 0xf43700ff + +/*P1_CARCFG*/ +#define RSTV0910_P1_CARCFG 0xf438 +#define FSTV0910_P1_ROTAON 0xf4380004 +#define FSTV0910_P1_PH_DET_ALGO 0xf4380003 + +/*P1_ACLC*/ +#define RSTV0910_P1_ACLC 0xf439 +#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030 +#define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f + +/*P1_BCLC*/ +#define RSTV0910_P1_BCLC 0xf43a +#define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030 +#define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f + +/*P1_ACLCS2*/ +#define RSTV0910_P1_ACLCS2 0xf43b +#define FSTV0910_P1_CARS2_APLHA_MANTISSE 0xf43b0030 +#define FSTV0910_P1_CARS2_ALPHA_EXP 0xf43b000f + +/*P1_BCLCS2*/ +#define RSTV0910_P1_BCLCS2 0xf43c +#define FSTV0910_P1_CARS2_BETA_MANTISSE 0xf43c0030 +#define FSTV0910_P1_CARS2_BETA_EXP 0xf43c000f + +/*P1_CARFREQ*/ +#define RSTV0910_P1_CARFREQ 0xf43d +#define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0 +#define FSTV0910_P1_BETA_FREQ 0xf43d000f + +/*P1_CARHDR*/ +#define RSTV0910_P1_CARHDR 0xf43e +#define FSTV0910_P1_K_FREQ_HDR 0xf43e00ff + +/*P1_LDT*/ +#define RSTV0910_P1_LDT 0xf43f +#define FSTV0910_P1_CARLOCK_THRES 0xf43f01ff + +/*P1_LDT2*/ +#define RSTV0910_P1_LDT2 0xf440 +#define FSTV0910_P1_CARLOCK_THRES2 0xf44001ff + +/*P1_CFRICFG*/ +#define RSTV0910_P1_CFRICFG 0xf441 +#define FSTV0910_P1_NEG_CFRSTEP 0xf4410001 + +/*P1_CFRUP1*/ +#define RSTV0910_P1_CFRUP1 0xf442 +#define FSTV0910_P1_CFR_UP1 0xf44201ff + +/*P1_CFRUP0*/ +#define RSTV0910_P1_CFRUP0 0xf443 +#define FSTV0910_P1_CFR_UP0 0xf44300ff + +/*P1_CFRIBASE1*/ +#define RSTV0910_P1_CFRIBASE1 0xf444 +#define FSTV0910_P1_CFRINIT_BASE1 0xf44400ff + +/*P1_CFRIBASE0*/ +#define RSTV0910_P1_CFRIBASE0 0xf445 +#define FSTV0910_P1_CFRINIT_BASE0 0xf44500ff + +/*P1_CFRLOW1*/ +#define RSTV0910_P1_CFRLOW1 0xf446 +#define FSTV0910_P1_CFR_LOW1 0xf44601ff + +/*P1_CFRLOW0*/ +#define RSTV0910_P1_CFRLOW0 0xf447 +#define FSTV0910_P1_CFR_LOW0 0xf44700ff + +/*P1_CFRINIT1*/ +#define RSTV0910_P1_CFRINIT1 0xf448 +#define FSTV0910_P1_CFR_INIT1 0xf44801ff + +/*P1_CFRINIT0*/ +#define RSTV0910_P1_CFRINIT0 0xf449 +#define FSTV0910_P1_CFR_INIT0 0xf44900ff + +/*P1_CFRINC1*/ +#define RSTV0910_P1_CFRINC1 0xf44a +#define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080 +#define FSTV0910_P1_CFR_INC1 0xf44a003f + +/*P1_CFRINC0*/ +#define RSTV0910_P1_CFRINC0 0xf44b +#define FSTV0910_P1_CFR_INC0 0xf44b00ff + +/*P1_CFR2*/ +#define RSTV0910_P1_CFR2 0xf44c +#define FSTV0910_P1_CAR_FREQ2 0xf44c01ff + +/*P1_CFR1*/ +#define RSTV0910_P1_CFR1 0xf44d +#define FSTV0910_P1_CAR_FREQ1 0xf44d00ff + +/*P1_CFR0*/ +#define RSTV0910_P1_CFR0 0xf44e +#define FSTV0910_P1_CAR_FREQ0 0xf44e00ff + +/*P1_LDI*/ +#define RSTV0910_P1_LDI 0xf44f +#define FSTV0910_P1_LOCK_DET_INTEGR 0xf44f01ff + +/*P1_TMGCFG*/ +#define RSTV0910_P1_TMGCFG 0xf450 +#define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0 +#define FSTV0910_P1_DO_TIMING_CORR 0xf4500010 +#define FSTV0910_P1_TMG_MINFREQ 0xf4500003 + +/*P1_RTC*/ +#define RSTV0910_P1_RTC 0xf451 +#define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0 +#define FSTV0910_P1_TMGBETA_EXP 0xf451000f + +/*P1_RTCS2*/ +#define RSTV0910_P1_RTCS2 0xf452 +#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0 +#define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f + +/*P1_TMGTHRISE*/ +#define RSTV0910_P1_TMGTHRISE 0xf453 +#define FSTV0910_P1_TMGLOCK_THRISE 0xf45300ff + +/*P1_TMGTHFALL*/ +#define RSTV0910_P1_TMGTHFALL 0xf454 +#define FSTV0910_P1_TMGLOCK_THFALL 0xf45400ff + +/*P1_SFRUPRATIO*/ +#define RSTV0910_P1_SFRUPRATIO 0xf455 +#define FSTV0910_P1_SFR_UPRATIO 0xf45500ff + +/*P1_SFRLOWRATIO*/ +#define RSTV0910_P1_SFRLOWRATIO 0xf456 +#define FSTV0910_P1_SFR_LOWRATIO 0xf45600ff + +/*P1_KTTMG*/ +#define RSTV0910_P1_KTTMG 0xf457 +#define FSTV0910_P1_KT_TMG_EXP 0xf45700f0 + +/*P1_KREFTMG*/ +#define RSTV0910_P1_KREFTMG 0xf458 +#define FSTV0910_P1_KREF_TMG 0xf45800ff + +/*P1_SFRSTEP*/ +#define RSTV0910_P1_SFRSTEP 0xf459 +#define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0 +#define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f + +/*P1_TMGCFG2*/ +#define RSTV0910_P1_TMGCFG2 0xf45a +#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008 +#define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001 + +/*P1_KREFTMG2*/ +#define RSTV0910_P1_KREFTMG2 0xf45b +#define FSTV0910_P1_KREF_TMG2 0xf45b00ff + +/*P1_TMGCFG3*/ +#define RSTV0910_P1_TMGCFG3 0xf45d +#define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008 +#define FSTV0910_P1_AUTO_GUP 0xf45d0004 +#define FSTV0910_P1_AUTO_GLOW 0xf45d0002 + +/*P1_SFRINIT1*/ +#define RSTV0910_P1_SFRINIT1 0xf45e +#define FSTV0910_P1_SFR_INIT1 0xf45e00ff + +/*P1_SFRINIT0*/ +#define RSTV0910_P1_SFRINIT0 0xf45f +#define FSTV0910_P1_SFR_INIT0 0xf45f00ff + +/*P1_SFRUP1*/ +#define RSTV0910_P1_SFRUP1 0xf460 +#define FSTV0910_P1_SYMB_FREQ_UP1 0xf46000ff + +/*P1_SFRUP0*/ +#define RSTV0910_P1_SFRUP0 0xf461 +#define FSTV0910_P1_SYMB_FREQ_UP0 0xf46100ff + +/*P1_SFRLOW1*/ +#define RSTV0910_P1_SFRLOW1 0xf462 +#define FSTV0910_P1_SYMB_FREQ_LOW1 0xf46200ff + +/*P1_SFRLOW0*/ +#define RSTV0910_P1_SFRLOW0 0xf463 +#define FSTV0910_P1_SYMB_FREQ_LOW0 0xf46300ff + +/*P1_SFR3*/ +#define RSTV0910_P1_SFR3 0xf464 +#define FSTV0910_P1_SYMB_FREQ3 0xf46400ff + +/*P1_SFR2*/ +#define RSTV0910_P1_SFR2 0xf465 +#define FSTV0910_P1_SYMB_FREQ2 0xf46500ff + +/*P1_SFR1*/ +#define RSTV0910_P1_SFR1 0xf466 +#define FSTV0910_P1_SYMB_FREQ1 0xf46600ff + +/*P1_SFR0*/ +#define RSTV0910_P1_SFR0 0xf467 +#define FSTV0910_P1_SYMB_FREQ0 0xf46700ff + +/*P1_TMGREG2*/ +#define RSTV0910_P1_TMGREG2 0xf468 +#define FSTV0910_P1_TMGREG2 0xf46800ff + +/*P1_TMGREG1*/ +#define RSTV0910_P1_TMGREG1 0xf469 +#define FSTV0910_P1_TMGREG1 0xf46900ff + +/*P1_TMGREG0*/ +#define RSTV0910_P1_TMGREG0 0xf46a +#define FSTV0910_P1_TMGREG0 0xf46a00ff + +/*P1_TMGLOCK1*/ +#define RSTV0910_P1_TMGLOCK1 0xf46b +#define FSTV0910_P1_TMGLOCK_LEVEL1 0xf46b01ff + +/*P1_TMGLOCK0*/ +#define RSTV0910_P1_TMGLOCK0 0xf46c +#define FSTV0910_P1_TMGLOCK_LEVEL0 0xf46c00ff + +/*P1_TMGOBS*/ +#define RSTV0910_P1_TMGOBS 0xf46d +#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0 + +/*P1_EQUALCFG*/ +#define RSTV0910_P1_EQUALCFG 0xf46f +#define FSTV0910_P1_EQUAL_ON 0xf46f0040 +#define FSTV0910_P1_MU_EQUALDFE 0xf46f0007 + +/*P1_EQUAI1*/ +#define RSTV0910_P1_EQUAI1 0xf470 +#define FSTV0910_P1_EQUA_ACCI1 0xf47001ff + +/*P1_EQUAQ1*/ +#define RSTV0910_P1_EQUAQ1 0xf471 +#define FSTV0910_P1_EQUA_ACCQ1 0xf47101ff + +/*P1_EQUAI2*/ +#define RSTV0910_P1_EQUAI2 0xf472 +#define FSTV0910_P1_EQUA_ACCI2 0xf47201ff + +/*P1_EQUAQ2*/ +#define RSTV0910_P1_EQUAQ2 0xf473 +#define FSTV0910_P1_EQUA_ACCQ2 0xf47301ff + +/*P1_EQUAI3*/ +#define RSTV0910_P1_EQUAI3 0xf474 +#define FSTV0910_P1_EQUA_ACCI3 0xf47401ff + +/*P1_EQUAQ3*/ +#define RSTV0910_P1_EQUAQ3 0xf475 +#define FSTV0910_P1_EQUA_ACCQ3 0xf47501ff + +/*P1_EQUAI4*/ +#define RSTV0910_P1_EQUAI4 0xf476 +#define FSTV0910_P1_EQUA_ACCI4 0xf47601ff + +/*P1_EQUAQ4*/ +#define RSTV0910_P1_EQUAQ4 0xf477 +#define FSTV0910_P1_EQUA_ACCQ4 0xf47701ff + +/*P1_EQUAI5*/ +#define RSTV0910_P1_EQUAI5 0xf478 +#define FSTV0910_P1_EQUA_ACCI5 0xf47801ff + +/*P1_EQUAQ5*/ +#define RSTV0910_P1_EQUAQ5 0xf479 +#define FSTV0910_P1_EQUA_ACCQ5 0xf47901ff + +/*P1_EQUAI6*/ +#define RSTV0910_P1_EQUAI6 0xf47a +#define FSTV0910_P1_EQUA_ACCI6 0xf47a01ff + +/*P1_EQUAQ6*/ +#define RSTV0910_P1_EQUAQ6 0xf47b +#define FSTV0910_P1_EQUA_ACCQ6 0xf47b01ff + +/*P1_EQUAI7*/ +#define RSTV0910_P1_EQUAI7 0xf47c +#define FSTV0910_P1_EQUA_ACCI7 0xf47c01ff + +/*P1_EQUAQ7*/ +#define RSTV0910_P1_EQUAQ7 0xf47d +#define FSTV0910_P1_EQUA_ACCQ7 0xf47d01ff + +/*P1_EQUAI8*/ +#define RSTV0910_P1_EQUAI8 0xf47e +#define FSTV0910_P1_EQUA_ACCI8 0xf47e01ff + +/*P1_EQUAQ8*/ +#define RSTV0910_P1_EQUAQ8 0xf47f +#define FSTV0910_P1_EQUA_ACCQ8 0xf47f01ff + +/*P1_NNOSDATAT1*/ +#define RSTV0910_P1_NNOSDATAT1 0xf480 +#define FSTV0910_P1_NOSDATAT_NORMED1 0xf48000ff + +/*P1_NNOSDATAT0*/ +#define RSTV0910_P1_NNOSDATAT0 0xf481 +#define FSTV0910_P1_NOSDATAT_NORMED0 0xf48100ff + +/*P1_NNOSDATA1*/ +#define RSTV0910_P1_NNOSDATA1 0xf482 +#define FSTV0910_P1_NOSDATA_NORMED1 0xf48200ff + +/*P1_NNOSDATA0*/ +#define RSTV0910_P1_NNOSDATA0 0xf483 +#define FSTV0910_P1_NOSDATA_NORMED0 0xf48300ff + +/*P1_NNOSPLHT1*/ +#define RSTV0910_P1_NNOSPLHT1 0xf484 +#define FSTV0910_P1_NOSPLHT_NORMED1 0xf48400ff + +/*P1_NNOSPLHT0*/ +#define RSTV0910_P1_NNOSPLHT0 0xf485 +#define FSTV0910_P1_NOSPLHT_NORMED0 0xf48500ff + +/*P1_NNOSPLH1*/ +#define RSTV0910_P1_NNOSPLH1 0xf486 +#define FSTV0910_P1_NOSPLH_NORMED1 0xf48600ff + +/*P1_NNOSPLH0*/ +#define RSTV0910_P1_NNOSPLH0 0xf487 +#define FSTV0910_P1_NOSPLH_NORMED0 0xf48700ff + +/*P1_NOSDATAT1*/ +#define RSTV0910_P1_NOSDATAT1 0xf488 +#define FSTV0910_P1_NOSDATAT_UNNORMED1 0xf48800ff + +/*P1_NOSDATAT0*/ +#define RSTV0910_P1_NOSDATAT0 0xf489 +#define FSTV0910_P1_NOSDATAT_UNNORMED0 0xf48900ff + +/*P1_NNOSFRAME1*/ +#define RSTV0910_P1_NNOSFRAME1 0xf48a +#define FSTV0910_P1_NOSFRAME_NORMED1 0xf48a00ff + +/*P1_NNOSFRAME0*/ +#define RSTV0910_P1_NNOSFRAME0 0xf48b +#define FSTV0910_P1_NOSFRAME_NORMED0 0xf48b00ff + +/*P1_NNOSRAD1*/ +#define RSTV0910_P1_NNOSRAD1 0xf48c +#define FSTV0910_P1_NOSRADIAL_NORMED1 0xf48c00ff + +/*P1_NNOSRAD0*/ +#define RSTV0910_P1_NNOSRAD0 0xf48d +#define FSTV0910_P1_NOSRADIAL_NORMED0 0xf48d00ff + +/*P1_NOSCFGF1*/ +#define RSTV0910_P1_NOSCFGF1 0xf48e +#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080 +#define FSTV0910_P1_NOS_DELFRAME 0xf48e0040 +#define FSTV0910_P1_NOSDATA_MODE 0xf48e0030 +#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c +#define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003 + +/*P1_NOSCFGF2*/ +#define RSTV0910_P1_NOSCFGF2 0xf48f +#define FSTV0910_P1_DIS_NOSPILOTS 0xf48f0080 +#define FSTV0910_P1_FRAMESEL_MODCODSEL 0xf48f0060 +#define FSTV0910_P1_FRAMESEL_MODCOD 0xf48f001f + +/*P1_CAR2CFG*/ +#define RSTV0910_P1_CAR2CFG 0xf490 +#define FSTV0910_P1_ROTA2ON 0xf4900004 +#define FSTV0910_P1_PH_DET_ALGO2 0xf4900003 + +/*P1_CFR2CFR1*/ +#define RSTV0910_P1_CFR2CFR1 0xf491 +#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020 +#define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007 + +/*P1_CAR3CFG*/ +#define RSTV0910_P1_CAR3CFG 0xf492 +#define FSTV0910_P1_CARRIER23_MODE 0xf49200c0 +#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020 +#define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018 +#define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007 + +/*P1_CFR22*/ +#define RSTV0910_P1_CFR22 0xf493 +#define FSTV0910_P1_CAR2_FREQ2 0xf49301ff + +/*P1_CFR21*/ +#define RSTV0910_P1_CFR21 0xf494 +#define FSTV0910_P1_CAR2_FREQ1 0xf49400ff + +/*P1_CFR20*/ +#define RSTV0910_P1_CFR20 0xf495 +#define FSTV0910_P1_CAR2_FREQ0 0xf49500ff + +/*P1_ACLC2S2Q*/ +#define RSTV0910_P1_ACLC2S2Q 0xf497 +#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080 +#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030 +#define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f + +/*P1_ACLC2S28*/ +#define RSTV0910_P1_ACLC2S28 0xf498 +#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030 +#define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f + +/*P1_ACLC2S216A*/ +#define RSTV0910_P1_ACLC2S216A 0xf499 +#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030 +#define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f + +/*P1_ACLC2S232A*/ +#define RSTV0910_P1_ACLC2S232A 0xf49a +#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030 +#define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f + +/*P1_BCLC2S2Q*/ +#define RSTV0910_P1_BCLC2S2Q 0xf49c +#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030 +#define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f + +/*P1_BCLC2S28*/ +#define RSTV0910_P1_BCLC2S28 0xf49d +#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030 +#define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f + +/*P1_BCLC2S216A*/ +#define RSTV0910_P1_BCLC2S216A 0xf49e +#define FSTV0910_P1_DVBS2S216A_NIP 0xf49e0080 +#define FSTV0910_P1_CAR2S2_16A_BETA_M 0xf49e0030 +#define FSTV0910_P1_CAR2S2_16A_BETA_E 0xf49e000f + +/*P1_BCLC2S232A*/ +#define RSTV0910_P1_BCLC2S232A 0xf49f +#define FSTV0910_P1_DVBS2S232A_NIP 0xf49f0080 +#define FSTV0910_P1_CAR2S2_32A_BETA_M 0xf49f0030 +#define FSTV0910_P1_CAR2S2_32A_BETA_E 0xf49f000f + +/*P1_PLROOT2*/ +#define RSTV0910_P1_PLROOT2 0xf4ac +#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c +#define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003 + +/*P1_PLROOT1*/ +#define RSTV0910_P1_PLROOT1 0xf4ad +#define FSTV0910_P1_PLSCRAMB_ROOT1 0xf4ad00ff + +/*P1_PLROOT0*/ +#define RSTV0910_P1_PLROOT0 0xf4ae +#define FSTV0910_P1_PLSCRAMB_ROOT0 0xf4ae00ff + +/*P1_MODCODLST0*/ +#define RSTV0910_P1_MODCODLST0 0xf4b0 +#define FSTV0910_P1_NACCES_MODCODCH 0xf4b00001 + +/*P1_MODCODLST1*/ +#define RSTV0910_P1_MODCODLST1 0xf4b1 +#define FSTV0910_P1_SYMBRATE_FILTER 0xf4b10008 +#define FSTV0910_P1_NRESET_MODCODLST 0xf4b10004 +#define FSTV0910_P1_DIS_32PSK_9_10 0xf4b10003 + +/*P1_MODCODLST2*/ +#define RSTV0910_P1_MODCODLST2 0xf4b2 +#define FSTV0910_P1_DIS_32PSK_8_9 0xf4b200f0 +#define FSTV0910_P1_DIS_32PSK_5_6 0xf4b2000f + +/*P1_MODCODLST3*/ +#define RSTV0910_P1_MODCODLST3 0xf4b3 +#define FSTV0910_P1_DIS_32PSK_4_5 0xf4b300f0 +#define FSTV0910_P1_DIS_32PSK_3_4 0xf4b3000f + +/*P1_MODCODLST4*/ +#define RSTV0910_P1_MODCODLST4 0xf4b4 +#define FSTV0910_P1_DUMMYPL_PILOT 0xf4b40080 +#define FSTV0910_P1_DUMMYPL_NOPILOT 0xf4b40040 +#define FSTV0910_P1_DIS_16PSK_9_10 0xf4b40030 +#define FSTV0910_P1_DIS_16PSK_8_9 0xf4b4000f + +/*P1_MODCODLST5*/ +#define RSTV0910_P1_MODCODLST5 0xf4b5 +#define FSTV0910_P1_DIS_16PSK_5_6 0xf4b500f0 +#define FSTV0910_P1_DIS_16PSK_4_5 0xf4b5000f + +/*P1_MODCODLST6*/ +#define RSTV0910_P1_MODCODLST6 0xf4b6 +#define FSTV0910_P1_DIS_16PSK_3_4 0xf4b600f0 +#define FSTV0910_P1_DIS_16PSK_2_3 0xf4b6000f + +/*P1_MODCODLST7*/ +#define RSTV0910_P1_MODCODLST7 0xf4b7 +#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080 +#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030 +#define FSTV0910_P1_DIS_8PSK_8_9 0xf4b7000f + +/*P1_MODCODLST8*/ +#define RSTV0910_P1_MODCODLST8 0xf4b8 +#define FSTV0910_P1_DIS_8PSK_5_6 0xf4b800f0 +#define FSTV0910_P1_DIS_8PSK_3_4 0xf4b8000f + +/*P1_MODCODLST9*/ +#define RSTV0910_P1_MODCODLST9 0xf4b9 +#define FSTV0910_P1_DIS_8PSK_2_3 0xf4b900f0 +#define FSTV0910_P1_DIS_8PSK_3_5 0xf4b9000f + +/*P1_MODCODLSTA*/ +#define RSTV0910_P1_MODCODLSTA 0xf4ba +#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080 +#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030 +#define FSTV0910_P1_DIS_QPSK_8_9 0xf4ba000f + +/*P1_MODCODLSTB*/ +#define RSTV0910_P1_MODCODLSTB 0xf4bb +#define FSTV0910_P1_DIS_QPSK_5_6 0xf4bb00f0 +#define FSTV0910_P1_DIS_QPSK_4_5 0xf4bb000f + +/*P1_MODCODLSTC*/ +#define RSTV0910_P1_MODCODLSTC 0xf4bc +#define FSTV0910_P1_DIS_QPSK_3_4 0xf4bc00f0 +#define FSTV0910_P1_DIS_QPSK_2_3 0xf4bc000f + +/*P1_MODCODLSTD*/ +#define RSTV0910_P1_MODCODLSTD 0xf4bd +#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0 +#define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f + +/*P1_MODCODLSTE*/ +#define RSTV0910_P1_MODCODLSTE 0xf4be +#define FSTV0910_P1_DIS_QPSK_2_5 0xf4be00f0 +#define FSTV0910_P1_DIS_QPSK_1_3 0xf4be000f + +/*P1_MODCODLSTF*/ +#define RSTV0910_P1_MODCODLSTF 0xf4bf +#define FSTV0910_P1_DIS_QPSK_1_4 0xf4bf00f0 +#define FSTV0910_P1_DEMOD_INVMODLST 0xf4bf0008 +#define FSTV0910_P1_DEMODOUT_ENABLE 0xf4bf0004 +#define FSTV0910_P1_DDEMOD_NSET 0xf4bf0002 +#define FSTV0910_P1_MODCOD_NSTOCK 0xf4bf0001 + +/*P1_GAUSSR0*/ +#define RSTV0910_P1_GAUSSR0 0xf4c0 +#define FSTV0910_P1_EN_CCIMODE 0xf4c00080 +#define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f + +/*P1_CCIR0*/ +#define RSTV0910_P1_CCIR0 0xf4c1 +#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080 +#define FSTV0910_P1_R0_CCI 0xf4c1007f + +/*P1_CCIQUANT*/ +#define RSTV0910_P1_CCIQUANT 0xf4c2 +#define FSTV0910_P1_CCI_BETA 0xf4c200e0 +#define FSTV0910_P1_CCI_QUANT 0xf4c2001f + +/*P1_CCITHRES*/ +#define RSTV0910_P1_CCITHRES 0xf4c3 +#define FSTV0910_P1_CCI_THRESHOLD 0xf4c300ff + +/*P1_CCIACC*/ +#define RSTV0910_P1_CCIACC 0xf4c4 +#define FSTV0910_P1_CCI_VALUE 0xf4c400ff + +/*P1_DSTATUS4*/ +#define RSTV0910_P1_DSTATUS4 0xf4c5 +#define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080 +#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040 +#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c50020 +#define FSTV0910_P1_DMDPROG_ERROR 0xf4c50004 +#define FSTV0910_P1_CSTENV_DETECT 0xf4c50002 +#define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001 + +/*P1_DMDRESCFG*/ +#define RSTV0910_P1_DMDRESCFG 0xf4c6 +#define FSTV0910_P1_DMDRES_RESET 0xf4c60080 +#define FSTV0910_P1_DMDRES_STRALL 0xf4c60008 +#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004 +#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002 + +/*P1_DMDRESADR*/ +#define RSTV0910_P1_DMDRESADR 0xf4c7 +#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040 +#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030 +#define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f + +/*P1_DMDRESDATA7*/ +#define RSTV0910_P1_DMDRESDATA7 0xf4c8 +#define FSTV0910_P1_DMDRES_DATA7 0xf4c800ff + +/*P1_DMDRESDATA6*/ +#define RSTV0910_P1_DMDRESDATA6 0xf4c9 +#define FSTV0910_P1_DMDRES_DATA6 0xf4c900ff + +/*P1_DMDRESDATA5*/ +#define RSTV0910_P1_DMDRESDATA5 0xf4ca +#define FSTV0910_P1_DMDRES_DATA5 0xf4ca00ff + +/*P1_DMDRESDATA4*/ +#define RSTV0910_P1_DMDRESDATA4 0xf4cb +#define FSTV0910_P1_DMDRES_DATA4 0xf4cb00ff + +/*P1_DMDRESDATA3*/ +#define RSTV0910_P1_DMDRESDATA3 0xf4cc +#define FSTV0910_P1_DMDRES_DATA3 0xf4cc00ff + +/*P1_DMDRESDATA2*/ +#define RSTV0910_P1_DMDRESDATA2 0xf4cd +#define FSTV0910_P1_DMDRES_DATA2 0xf4cd00ff + +/*P1_DMDRESDATA1*/ +#define RSTV0910_P1_DMDRESDATA1 0xf4ce +#define FSTV0910_P1_DMDRES_DATA1 0xf4ce00ff + +/*P1_DMDRESDATA0*/ +#define RSTV0910_P1_DMDRESDATA0 0xf4cf +#define FSTV0910_P1_DMDRES_DATA0 0xf4cf00ff + +/*P1_FFEI1*/ +#define RSTV0910_P1_FFEI1 0xf4d0 +#define FSTV0910_P1_FFE_ACCI1 0xf4d001ff + +/*P1_FFEQ1*/ +#define RSTV0910_P1_FFEQ1 0xf4d1 +#define FSTV0910_P1_FFE_ACCQ1 0xf4d101ff + +/*P1_FFEI2*/ +#define RSTV0910_P1_FFEI2 0xf4d2 +#define FSTV0910_P1_FFE_ACCI2 0xf4d201ff + +/*P1_FFEQ2*/ +#define RSTV0910_P1_FFEQ2 0xf4d3 +#define FSTV0910_P1_FFE_ACCQ2 0xf4d301ff + +/*P1_FFEI3*/ +#define RSTV0910_P1_FFEI3 0xf4d4 +#define FSTV0910_P1_FFE_ACCI3 0xf4d401ff + +/*P1_FFEQ3*/ +#define RSTV0910_P1_FFEQ3 0xf4d5 +#define FSTV0910_P1_FFE_ACCQ3 0xf4d501ff + +/*P1_FFEI4*/ +#define RSTV0910_P1_FFEI4 0xf4d6 +#define FSTV0910_P1_FFE_ACCI4 0xf4d601ff + +/*P1_FFEQ4*/ +#define RSTV0910_P1_FFEQ4 0xf4d7 +#define FSTV0910_P1_FFE_ACCQ4 0xf4d701ff + +/*P1_FFECFG*/ +#define RSTV0910_P1_FFECFG 0xf4d8 +#define FSTV0910_P1_EQUALFFE_ON 0xf4d80040 +#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030 +#define FSTV0910_P1_MU_EQUALFFE 0xf4d80007 + +/*P1_TNRCFG2*/ +#define RSTV0910_P1_TNRCFG2 0xf4e1 +#define FSTV0910_P1_TUN_IQSWAP 0xf4e10080 + +/*P1_SMAPCOEF7*/ +#define RSTV0910_P1_SMAPCOEF7 0xf500 +#define FSTV0910_P1_DIS_QSCALE 0xf5000080 +#define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f + +/*P1_SMAPCOEF6*/ +#define RSTV0910_P1_SMAPCOEF6 0xf501 +#define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080 +#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004 +#define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002 +#define FSTV0910_P1_DIS_AB8PSK 0xf5010001 + +/*P1_SMAPCOEF5*/ +#define RSTV0910_P1_SMAPCOEF5 0xf502 +#define FSTV0910_P1_DIS_8SCALE 0xf5020080 +#define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f + +/*P1_SMAPCOEF4*/ +#define RSTV0910_P1_SMAPCOEF4 0xf503 +#define FSTV0910_P1_SMAPCOEF_16APSK_LLR12 0xf503017f + +/*P1_SMAPCOEF3*/ +#define RSTV0910_P1_SMAPCOEF3 0xf504 +#define FSTV0910_P1_SMAPCOEF_16APSK_LLR34 0xf504017f + +/*P1_SMAPCOEF2*/ +#define RSTV0910_P1_SMAPCOEF2 0xf505 +#define FSTV0910_P1_SMAPCOEF_32APSK_R2R3 0xf50501f0 +#define FSTV0910_P1_SMAPCOEF_32APSK_LLR2 0xf505010f + +/*P1_SMAPCOEF1*/ +#define RSTV0910_P1_SMAPCOEF1 0xf506 +#define FSTV0910_P1_DIS_16SCALE 0xf5060080 +#define FSTV0910_P1_SMAPCOEF_32_LLR34 0xf506017f + +/*P1_SMAPCOEF0*/ +#define RSTV0910_P1_SMAPCOEF0 0xf507 +#define FSTV0910_P1_DIS_32SCALE 0xf5070080 +#define FSTV0910_P1_SMAPCOEF_32_LLR15 0xf507017f + +/*P1_NOSTHRES1*/ +#define RSTV0910_P1_NOSTHRES1 0xf509 +#define FSTV0910_P1_NOS_THRESHOLD1 0xf50900ff + +/*P1_NOSTHRES2*/ +#define RSTV0910_P1_NOSTHRES2 0xf50a +#define FSTV0910_P1_NOS_THRESHOLD2 0xf50a00ff + +/*P1_NOSDIFF1*/ +#define RSTV0910_P1_NOSDIFF1 0xf50b +#define FSTV0910_P1_NOSTHRES1_DIFF 0xf50b00ff + +/*P1_RAINFADE*/ +#define RSTV0910_P1_RAINFADE 0xf50c +#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080 +#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070 +#define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007 + +/*P1_NOSRAMCFG*/ +#define RSTV0910_P1_NOSRAMCFG 0xf50d +#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030 +#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008 +#define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007 + +/*P1_NOSRAMPOS*/ +#define RSTV0910_P1_NOSRAMPOS 0xf50e +#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0 +#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004 +#define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003 + +/*P1_NOSRAMVAL*/ +#define RSTV0910_P1_NOSRAMVAL 0xf50f +#define FSTV0910_P1_NOSRAM_CNRVAL0 0xf50f00ff + +/*P1_DMDPLHSTAT*/ +#define RSTV0910_P1_DMDPLHSTAT 0xf520 +#define FSTV0910_P1_PLH_STATISTIC 0xf52000ff + +/*P1_LOCKTIME3*/ +#define RSTV0910_P1_LOCKTIME3 0xf522 +#define FSTV0910_P1_DEMOD_LOCKTIME3 0xf52200ff + +/*P1_LOCKTIME2*/ +#define RSTV0910_P1_LOCKTIME2 0xf523 +#define FSTV0910_P1_DEMOD_LOCKTIME2 0xf52300ff + +/*P1_LOCKTIME1*/ +#define RSTV0910_P1_LOCKTIME1 0xf524 +#define FSTV0910_P1_DEMOD_LOCKTIME1 0xf52400ff + +/*P1_LOCKTIME0*/ +#define RSTV0910_P1_LOCKTIME0 0xf525 +#define FSTV0910_P1_DEMOD_LOCKTIME0 0xf52500ff + +/*P1_VITSCALE*/ +#define RSTV0910_P1_VITSCALE 0xf532 +#define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080 +#define FSTV0910_P1_VERROR_MAXMODE 0xf5320040 +#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008 +#define FSTV0910_P1_DIS_RSFLOCK 0xf5320002 + +/*P1_FECM*/ +#define RSTV0910_P1_FECM 0xf533 +#define FSTV0910_P1_DSS_DVB 0xf5330080 +#define FSTV0910_P1_DSS_SRCH 0xf5330010 +#define FSTV0910_P1_SYNCVIT 0xf5330002 +#define FSTV0910_P1_IQINV 0xf5330001 + +/*P1_VTH12*/ +#define RSTV0910_P1_VTH12 0xf534 +#define FSTV0910_P1_VTH12 0xf53400ff + +/*P1_VTH23*/ +#define RSTV0910_P1_VTH23 0xf535 +#define FSTV0910_P1_VTH23 0xf53500ff + +/*P1_VTH34*/ +#define RSTV0910_P1_VTH34 0xf536 +#define FSTV0910_P1_VTH34 0xf53600ff + +/*P1_VTH56*/ +#define RSTV0910_P1_VTH56 0xf537 +#define FSTV0910_P1_VTH56 0xf53700ff + +/*P1_VTH67*/ +#define RSTV0910_P1_VTH67 0xf538 +#define FSTV0910_P1_VTH67 0xf53800ff + +/*P1_VTH78*/ +#define RSTV0910_P1_VTH78 0xf539 +#define FSTV0910_P1_VTH78 0xf53900ff + +/*P1_VITCURPUN*/ +#define RSTV0910_P1_VITCURPUN 0xf53a +#define FSTV0910_P1_VIT_CURPUN 0xf53a001f + +/*P1_VERROR*/ +#define RSTV0910_P1_VERROR 0xf53b +#define FSTV0910_P1_REGERR_VIT 0xf53b00ff + +/*P1_PRVIT*/ +#define RSTV0910_P1_PRVIT 0xf53c +#define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040 +#define FSTV0910_P1_E7_8VIT 0xf53c0020 +#define FSTV0910_P1_E6_7VIT 0xf53c0010 +#define FSTV0910_P1_E5_6VIT 0xf53c0008 +#define FSTV0910_P1_E3_4VIT 0xf53c0004 +#define FSTV0910_P1_E2_3VIT 0xf53c0002 +#define FSTV0910_P1_E1_2VIT 0xf53c0001 + +/*P1_VAVSRVIT*/ +#define RSTV0910_P1_VAVSRVIT 0xf53d +#define FSTV0910_P1_AMVIT 0xf53d0080 +#define FSTV0910_P1_FROZENVIT 0xf53d0040 +#define FSTV0910_P1_SNVIT 0xf53d0030 +#define FSTV0910_P1_TOVVIT 0xf53d000c +#define FSTV0910_P1_HYPVIT 0xf53d0003 + +/*P1_VSTATUSVIT*/ +#define RSTV0910_P1_VSTATUSVIT 0xf53e +#define FSTV0910_P1_PRFVIT 0xf53e0010 +#define FSTV0910_P1_LOCKEDVIT 0xf53e0008 + +/*P1_VTHINUSE*/ +#define RSTV0910_P1_VTHINUSE 0xf53f +#define FSTV0910_P1_VIT_INUSE 0xf53f00ff + +/*P1_KDIV12*/ +#define RSTV0910_P1_KDIV12 0xf540 +#define FSTV0910_P1_K_DIVIDER_12 0xf540007f + +/*P1_KDIV23*/ +#define RSTV0910_P1_KDIV23 0xf541 +#define FSTV0910_P1_K_DIVIDER_23 0xf541007f + +/*P1_KDIV34*/ +#define RSTV0910_P1_KDIV34 0xf542 +#define FSTV0910_P1_K_DIVIDER_34 0xf542007f + +/*P1_KDIV56*/ +#define RSTV0910_P1_KDIV56 0xf543 +#define FSTV0910_P1_K_DIVIDER_56 0xf543007f + +/*P1_KDIV67*/ +#define RSTV0910_P1_KDIV67 0xf544 +#define FSTV0910_P1_K_DIVIDER_67 0xf544007f + +/*P1_KDIV78*/ +#define RSTV0910_P1_KDIV78 0xf545 +#define FSTV0910_P1_K_DIVIDER_78 0xf545007f + +/*P1_TSPIDFLT1*/ +#define RSTV0910_P1_TSPIDFLT1 0xf546 +#define FSTV0910_P1_PIDFLT_ADDR 0xf54600ff + +/*P1_TSPIDFLT0*/ +#define RSTV0910_P1_TSPIDFLT0 0xf547 +#define FSTV0910_P1_PIDFLT_DATA 0xf54700ff + +/*P1_PDELCTRL0*/ +#define RSTV0910_P1_PDELCTRL0 0xf54f +#define FSTV0910_P1_ISIOBS_MODE 0xf54f0030 + +/*P1_PDELCTRL1*/ +#define RSTV0910_P1_PDELCTRL1 0xf550 +#define FSTV0910_P1_INV_MISMASK 0xf5500080 +#define FSTV0910_P1_FILTER_EN 0xf5500020 +#define FSTV0910_P1_HYSTEN 0xf5500008 +#define FSTV0910_P1_HYSTSWRST 0xf5500004 +#define FSTV0910_P1_EN_MIS00 0xf5500002 +#define FSTV0910_P1_ALGOSWRST 0xf5500001 + +/*P1_PDELCTRL2*/ +#define RSTV0910_P1_PDELCTRL2 0xf551 +#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080 +#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040 +#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020 +#define FSTV0910_P1_FRAME_MODE 0xf5510002 + +/*P1_HYSTTHRESH*/ +#define RSTV0910_P1_HYSTTHRESH 0xf554 +#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0 +#define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f + +/*P1_UPLCCST0*/ +#define RSTV0910_P1_UPLCCST0 0xf558 +#define FSTV0910_P1_UPL_CST0 0xf55800f8 +#define FSTV0910_P1_UPL_MODE 0xf5580007 + +/*P1_ISIENTRY*/ +#define RSTV0910_P1_ISIENTRY 0xf55e +#define FSTV0910_P1_ISI_ENTRY 0xf55e00ff + +/*P1_ISIBITENA*/ +#define RSTV0910_P1_ISIBITENA 0xf55f +#define FSTV0910_P1_ISI_BIT_EN 0xf55f00ff + +/*P1_MATSTR1*/ +#define RSTV0910_P1_MATSTR1 0xf560 +#define FSTV0910_P1_MATYPE_CURRENT1 0xf56000ff + +/*P1_MATSTR0*/ +#define RSTV0910_P1_MATSTR0 0xf561 +#define FSTV0910_P1_MATYPE_CURRENT0 0xf56100ff + +/*P1_UPLSTR1*/ +#define RSTV0910_P1_UPLSTR1 0xf562 +#define FSTV0910_P1_UPL_CURRENT1 0xf56200ff + +/*P1_UPLSTR0*/ +#define RSTV0910_P1_UPLSTR0 0xf563 +#define FSTV0910_P1_UPL_CURRENT0 0xf56300ff + +/*P1_DFLSTR1*/ +#define RSTV0910_P1_DFLSTR1 0xf564 +#define FSTV0910_P1_DFL_CURRENT1 0xf56400ff + +/*P1_DFLSTR0*/ +#define RSTV0910_P1_DFLSTR0 0xf565 +#define FSTV0910_P1_DFL_CURRENT0 0xf56500ff + +/*P1_SYNCSTR*/ +#define RSTV0910_P1_SYNCSTR 0xf566 +#define FSTV0910_P1_SYNC_CURRENT 0xf56600ff + +/*P1_SYNCDSTR1*/ +#define RSTV0910_P1_SYNCDSTR1 0xf567 +#define FSTV0910_P1_SYNCD_CURRENT1 0xf56700ff + +/*P1_SYNCDSTR0*/ +#define RSTV0910_P1_SYNCDSTR0 0xf568 +#define FSTV0910_P1_SYNCD_CURRENT0 0xf56800ff + +/*P1_PDELSTATUS1*/ +#define RSTV0910_P1_PDELSTATUS1 0xf569 +#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080 +#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040 +#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5690010 +#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5690008 +#define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002 +#define FSTV0910_P1_FIRST_LOCK 0xf5690001 + +/*P1_PDELSTATUS2*/ +#define RSTV0910_P1_PDELSTATUS2 0xf56a +#define FSTV0910_P1_FRAME_MODCOD 0xf56a007c +#define FSTV0910_P1_FRAME_TYPE 0xf56a0003 + +/*P1_BBFCRCKO1*/ +#define RSTV0910_P1_BBFCRCKO1 0xf56b +#define FSTV0910_P1_BBHCRC_KOCNT1 0xf56b00ff + +/*P1_BBFCRCKO0*/ +#define RSTV0910_P1_BBFCRCKO0 0xf56c +#define FSTV0910_P1_BBHCRC_KOCNT0 0xf56c00ff + +/*P1_UPCRCKO1*/ +#define RSTV0910_P1_UPCRCKO1 0xf56d +#define FSTV0910_P1_PKTCRC_KOCNT1 0xf56d00ff + +/*P1_UPCRCKO0*/ +#define RSTV0910_P1_UPCRCKO0 0xf56e +#define FSTV0910_P1_PKTCRC_KOCNT0 0xf56e00ff + +/*P1_PDELCTRL3*/ +#define RSTV0910_P1_PDELCTRL3 0xf56f +#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020 +#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010 + +/*P1_TSSTATEM*/ +#define RSTV0910_P1_TSSTATEM 0xf570 +#define FSTV0910_P1_TSDIL_ON 0xf5700080 +#define FSTV0910_P1_TSRS_ON 0xf5700020 +#define FSTV0910_P1_TSDESCRAMB_ON 0xf5700010 +#define FSTV0910_P1_TSFRAME_MODE 0xf5700008 +#define FSTV0910_P1_TS_DISABLE 0xf5700004 +#define FSTV0910_P1_TSACM_MODE 0xf5700002 +#define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001 + +/*P1_TSSTATEL*/ +#define RSTV0910_P1_TSSTATEL 0xf571 +#define FSTV0910_P1_TSNOSYNCBYTE 0xf5710080 +#define FSTV0910_P1_TSPARITY_ON 0xf5710040 +#define FSTV0910_P1_TSISSYI_ON 0xf5710008 +#define FSTV0910_P1_TSNPD_ON 0xf5710004 +#define FSTV0910_P1_TSCRC8_ON 0xf5710002 +#define FSTV0910_P1_TSDSS_PACKET 0xf5710001 + +/*P1_TSCFGH*/ +#define RSTV0910_P1_TSCFGH 0xf572 +#define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080 +#define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040 +#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5720020 +#define FSTV0910_P1_TSFIFO_DUTY50 0xf5720010 +#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5720008 +#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006 +#define FSTV0910_P1_RST_HWARE 0xf5720001 + +/*P1_TSCFGM*/ +#define RSTV0910_P1_TSCFGM 0xf573 +#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0 +#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020 +#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010 +#define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001 + +/*P1_TSCFGL*/ +#define RSTV0910_P1_TSCFGL 0xf574 +#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 +#define FSTV0910_P1_BCHERROR_MODE 0xf5740030 +#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5740008 +#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004 +#define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003 + +/*P1_TSSYNC*/ +#define RSTV0910_P1_TSSYNC 0xf575 +#define FSTV0910_P1_TSFIFO_SYNCMODE 0xf5750018 + +/*P1_TSINSDELH*/ +#define RSTV0910_P1_TSINSDELH 0xf576 +#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080 +#define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040 +#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5760010 +#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002 +#define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001 + +/*P1_TSINSDELM*/ +#define RSTV0910_P1_TSINSDELM 0xf577 +#define FSTV0910_P1_TSINS_EMODCOD 0xf5770010 +#define FSTV0910_P1_TSINS_TOKEN 0xf5770008 +#define FSTV0910_P1_TSINS_XXXERR 0xf5770004 +#define FSTV0910_P1_TSINS_MATYPE 0xf5770002 +#define FSTV0910_P1_TSINS_UPL 0xf5770001 + +/*P1_TSINSDELL*/ +#define RSTV0910_P1_TSINSDELL 0xf578 +#define FSTV0910_P1_TSINS_DFL 0xf5780080 +#define FSTV0910_P1_TSINS_SYNCD 0xf5780040 +#define FSTV0910_P1_TSINS_BLOCLEN 0xf5780020 +#define FSTV0910_P1_TSINS_SIGPCOUNT 0xf5780010 +#define FSTV0910_P1_TSINS_FIFO 0xf5780008 +#define FSTV0910_P1_TSINS_REALPACK 0xf5780004 +#define FSTV0910_P1_TSINS_TSCONFIG 0xf5780002 +#define FSTV0910_P1_TSINS_LATENCY 0xf5780001 + +/*P1_TSDIVN*/ +#define RSTV0910_P1_TSDIVN 0xf579 +#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0 +#define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007 + +/*P1_TSCFG4*/ +#define RSTV0910_P1_TSCFG4 0xf57a +#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 + +/*P1_TSSPEED*/ +#define RSTV0910_P1_TSSPEED 0xf580 +#define FSTV0910_P1_TSFIFO_OUTSPEED 0xf58000ff + +/*P1_TSSTATUS*/ +#define RSTV0910_P1_TSSTATUS 0xf581 +#define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080 +#define FSTV0910_P1_TSFIFO_ERROR 0xf5810040 +#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5810010 +#define FSTV0910_P1_TSREGUL_ERROR 0xf5810004 +#define FSTV0910_P1_DIL_READY 0xf5810001 + +/*P1_TSSTATUS2*/ +#define RSTV0910_P1_TSSTATUS2 0xf582 +#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080 +#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040 +#define FSTV0910_P1_DILXX_RESET 0xf5820020 +#define FSTV0910_P1_SCRAMBDETECT 0xf5820002 + +/*P1_TSBITRATE1*/ +#define RSTV0910_P1_TSBITRATE1 0xf583 +#define FSTV0910_P1_TSFIFO_BITRATE1 0xf58300ff + +/*P1_TSBITRATE0*/ +#define RSTV0910_P1_TSBITRATE0 0xf584 +#define FSTV0910_P1_TSFIFO_BITRATE0 0xf58400ff + +/*P1_TSPACKLEN1*/ +#define RSTV0910_P1_TSPACKLEN1 0xf585 +#define FSTV0910_P1_TSFIFO_PACKCPT 0xf58500e0 + +/*P1_TSDLY2*/ +#define RSTV0910_P1_TSDLY2 0xf589 +#define FSTV0910_P1_SOFFIFO_LATENCY2 0xf589000f + +/*P1_TSDLY1*/ +#define RSTV0910_P1_TSDLY1 0xf58a +#define FSTV0910_P1_SOFFIFO_LATENCY1 0xf58a00ff + +/*P1_TSDLY0*/ +#define RSTV0910_P1_TSDLY0 0xf58b +#define FSTV0910_P1_SOFFIFO_LATENCY0 0xf58b00ff + +/*P1_TSNPDAV*/ +#define RSTV0910_P1_TSNPDAV 0xf58c +#define FSTV0910_P1_TSNPD_AVERAGE 0xf58c00ff + +/*P1_TSBUFSTAT2*/ +#define RSTV0910_P1_TSBUFSTAT2 0xf58d +#define FSTV0910_P1_TSISCR_3BYTES 0xf58d0080 +#define FSTV0910_P1_TSISCR_NEWDATA 0xf58d0040 +#define FSTV0910_P1_TSISCR_BUFSTAT2 0xf58d003f + +/*P1_TSBUFSTAT1*/ +#define RSTV0910_P1_TSBUFSTAT1 0xf58e +#define FSTV0910_P1_TSISCR_BUFSTAT1 0xf58e00ff + +/*P1_TSBUFSTAT0*/ +#define RSTV0910_P1_TSBUFSTAT0 0xf58f +#define FSTV0910_P1_TSISCR_BUFSTAT0 0xf58f00ff + +/*P1_TSDEBUGL*/ +#define RSTV0910_P1_TSDEBUGL 0xf591 +#define FSTV0910_P1_TSFIFO_ERROR_EVNT 0xf5910004 +#define FSTV0910_P1_TSFIFO_OVERFLOWM 0xf5910001 + +/*P1_TSDLYSET2*/ +#define RSTV0910_P1_TSDLYSET2 0xf592 +#define FSTV0910_P1_SOFFIFO_OFFSET 0xf59200c0 +#define FSTV0910_P1_HYSTERESIS_THRESHOLD 0xf5920030 +#define FSTV0910_P1_SOFFIFO_SYMBOFFS2 0xf592000f + +/*P1_TSDLYSET1*/ +#define RSTV0910_P1_TSDLYSET1 0xf593 +#define FSTV0910_P1_SOFFIFO_SYMBOFFS1 0xf59300ff + +/*P1_TSDLYSET0*/ +#define RSTV0910_P1_TSDLYSET0 0xf594 +#define FSTV0910_P1_SOFFIFO_SYMBOFFS0 0xf59400ff + +/*P1_ERRCTRL1*/ +#define RSTV0910_P1_ERRCTRL1 0xf598 +#define FSTV0910_P1_ERR_SOURCE1 0xf59800f0 +#define FSTV0910_P1_NUM_EVENT1 0xf5980007 + +/*P1_ERRCNT12*/ +#define RSTV0910_P1_ERRCNT12 0xf599 +#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080 +#define FSTV0910_P1_ERR_CNT12 0xf599007f + +/*P1_ERRCNT11*/ +#define RSTV0910_P1_ERRCNT11 0xf59a +#define FSTV0910_P1_ERR_CNT11 0xf59a00ff + +/*P1_ERRCNT10*/ +#define RSTV0910_P1_ERRCNT10 0xf59b +#define FSTV0910_P1_ERR_CNT10 0xf59b00ff + +/*P1_ERRCTRL2*/ +#define RSTV0910_P1_ERRCTRL2 0xf59c +#define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0 +#define FSTV0910_P1_NUM_EVENT2 0xf59c0007 + +/*P1_ERRCNT22*/ +#define RSTV0910_P1_ERRCNT22 0xf59d +#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080 +#define FSTV0910_P1_ERR_CNT22 0xf59d007f + +/*P1_ERRCNT21*/ +#define RSTV0910_P1_ERRCNT21 0xf59e +#define FSTV0910_P1_ERR_CNT21 0xf59e00ff + +/*P1_ERRCNT20*/ +#define RSTV0910_P1_ERRCNT20 0xf59f +#define FSTV0910_P1_ERR_CNT20 0xf59f00ff + +/*P1_FECSPY*/ +#define RSTV0910_P1_FECSPY 0xf5a0 +#define FSTV0910_P1_SPY_ENABLE 0xf5a00080 +#define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040 +#define FSTV0910_P1_SERIAL_MODE 0xf5a00020 +#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a00010 +#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0000c +#define FSTV0910_P1_BERMETER_LMODE 0xf5a00002 +#define FSTV0910_P1_BERMETER_RESET 0xf5a00001 + +/*P1_FSPYCFG*/ +#define RSTV0910_P1_FSPYCFG 0xf5a1 +#define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0 +#define FSTV0910_P1_RST_ON_ERROR 0xf5a10020 +#define FSTV0910_P1_ONE_SHOT 0xf5a10010 +#define FSTV0910_P1_I2C_MODE 0xf5a1000c +#define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003 + +/*P1_FSPYDATA*/ +#define RSTV0910_P1_FSPYDATA 0xf5a2 +#define FSTV0910_P1_SPY_STUFFING 0xf5a20080 +#define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020 +#define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f + +/*P1_FSPYOUT*/ +#define RSTV0910_P1_FSPYOUT 0xf5a3 +#define FSTV0910_P1_FSPY_DIRECT 0xf5a30080 +#define FSTV0910_P1_STUFF_MODE 0xf5a30007 + +/*P1_FSTATUS*/ +#define RSTV0910_P1_FSTATUS 0xf5a4 +#define FSTV0910_P1_SPY_ENDSIM 0xf5a40080 +#define FSTV0910_P1_VALID_SIM 0xf5a40040 +#define FSTV0910_P1_FOUND_SIGNAL 0xf5a40020 +#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010 +#define FSTV0910_P1_RESULT_STATE 0xf5a4000f + +/*P1_FBERCPT4*/ +#define RSTV0910_P1_FBERCPT4 0xf5a8 +#define FSTV0910_P1_FBERMETER_CPT4 0xf5a800ff + +/*P1_FBERCPT3*/ +#define RSTV0910_P1_FBERCPT3 0xf5a9 +#define FSTV0910_P1_FBERMETER_CPT3 0xf5a900ff + +/*P1_FBERCPT2*/ +#define RSTV0910_P1_FBERCPT2 0xf5aa +#define FSTV0910_P1_FBERMETER_CPT2 0xf5aa00ff + +/*P1_FBERCPT1*/ +#define RSTV0910_P1_FBERCPT1 0xf5ab +#define FSTV0910_P1_FBERMETER_CPT1 0xf5ab00ff + +/*P1_FBERCPT0*/ +#define RSTV0910_P1_FBERCPT0 0xf5ac +#define FSTV0910_P1_FBERMETER_CPT0 0xf5ac00ff + +/*P1_FBERERR2*/ +#define RSTV0910_P1_FBERERR2 0xf5ad +#define FSTV0910_P1_FBERMETER_ERR2 0xf5ad00ff + +/*P1_FBERERR1*/ +#define RSTV0910_P1_FBERERR1 0xf5ae +#define FSTV0910_P1_FBERMETER_ERR1 0xf5ae00ff + +/*P1_FBERERR0*/ +#define RSTV0910_P1_FBERERR0 0xf5af +#define FSTV0910_P1_FBERMETER_ERR0 0xf5af00ff + +/*P1_FSPYBER*/ +#define RSTV0910_P1_FSPYBER 0xf5b2 +#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010 +#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008 +#define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007 + +/*P1_SFERROR*/ +#define RSTV0910_P1_SFERROR 0xf5c1 +#define FSTV0910_P1_SFEC_REGERR_VIT 0xf5c100ff + +/*P1_SFECSTATUS*/ +#define RSTV0910_P1_SFECSTATUS 0xf5c3 +#define FSTV0910_P1_SFEC_ON 0xf5c30080 +#define FSTV0910_P1_SFEC_OFF 0xf5c30040 +#define FSTV0910_P1_LOCKEDSFEC 0xf5c30008 +#define FSTV0910_P1_SFEC_DELOCK 0xf5c30004 +#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002 +#define FSTV0910_P1_SFEC_OVFON 0xf5c30001 + +/*P1_SFKDIV12*/ +#define RSTV0910_P1_SFKDIV12 0xf5c4 +#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080 + +/*P1_SFKDIV23*/ +#define RSTV0910_P1_SFKDIV23 0xf5c5 +#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080 + +/*P1_SFKDIV34*/ +#define RSTV0910_P1_SFKDIV34 0xf5c6 +#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080 + +/*P1_SFKDIV56*/ +#define RSTV0910_P1_SFKDIV56 0xf5c7 +#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080 + +/*P1_SFKDIV67*/ +#define RSTV0910_P1_SFKDIV67 0xf5c8 +#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080 + +/*P1_SFKDIV78*/ +#define RSTV0910_P1_SFKDIV78 0xf5c9 +#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080 + +/*P1_SFSTATUS*/ +#define RSTV0910_P1_SFSTATUS 0xf5cc +#define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080 +#define FSTV0910_P1_SFEC_ERROR 0xf5cc0040 +#define FSTV0910_P1_SFEC_DATA7 0xf5cc0020 +#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc0010 +#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc0008 +#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc0004 +#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002 +#define FSTV0910_P1_SFEC_READY 0xf5cc0001 + +/*P1_SFDLYSET2*/ +#define RSTV0910_P1_SFDLYSET2 0xf5d0 +#define FSTV0910_P1_SFEC_DISABLE 0xf5d00002 + +/*P1_SFERRCTRL*/ +#define RSTV0910_P1_SFERRCTRL 0xf5d8 +#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0 +#define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007 + +/*P1_SFERRCNT2*/ +#define RSTV0910_P1_SFERRCNT2 0xf5d9 +#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080 +#define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f + +/*P1_SFERRCNT1*/ +#define RSTV0910_P1_SFERRCNT1 0xf5da +#define FSTV0910_P1_SFEC_ERR_CNT1 0xf5da00ff + +/*P1_SFERRCNT0*/ +#define RSTV0910_P1_SFERRCNT0 0xf5db +#define FSTV0910_P1_SFEC_ERR_CNT0 0xf5db00ff + +/*RCCFG2*/ +#define RSTV0910_RCCFG2 0xf600 +#define FSTV0910_TSRCFIFO_DVBCI 0xf6000080 +#define FSTV0910_TSRCFIFO_SERIAL 0xf6000040 +#define FSTV0910_TSRCFIFO_DISABLE 0xf6000020 +#define FSTV0910_TSFIFO_2TORC 0xf6000010 +#define FSTV0910_TSRCFIFO_HSGNLOUT 0xf6000008 +#define FSTV0910_TSRCFIFO_ERRMODE 0xf6000006 + +/*RCCFG1*/ +#define RSTV0910_RCCFG1 0xf601 +#define FSTV0910_TSRCFIFO_MANSPEED 0xf60100c0 +#define FSTV0910_TSRCFIFO_PERMDATA 0xf6010020 +#define FSTV0910_TSRCFIFO_NONEWSGNL 0xf6010010 +#define FSTV0910_TSRCFIFO_INVDATA 0xf6010001 + +/*RCCFG0*/ +#define RSTV0910_RCCFG0 0xf602 +#define FSTV0910_TSRCFIFO_BCLKDEL1CK 0xf60200c0 +#define FSTV0910_TSRCFIFO_DUTY50 0xf6020010 +#define FSTV0910_TSRCFIFO_NSGNL2DATA 0xf6020008 +#define FSTV0910_TSRCFIFO_NPDSGNL 0xf6020004 + +/*RCINSDEL2*/ +#define RSTV0910_RCINSDEL2 0xf603 +#define FSTV0910_TSRCDEL_SYNCBYTE 0xf6030080 +#define FSTV0910_TSRCDEL_XXHEADER 0xf6030040 +#define FSTV0910_TSRCDEL_BBHEADER 0xf6030020 +#define FSTV0910_TSRCDEL_DATAFIELD 0xf6030010 +#define FSTV0910_TSRCINSDEL_ISCR 0xf6030008 +#define FSTV0910_TSRCINSDEL_NPD 0xf6030004 +#define FSTV0910_TSRCINSDEL_RSPARITY 0xf6030002 +#define FSTV0910_TSRCINSDEL_CRC8 0xf6030001 + +/*RCINSDEL1*/ +#define RSTV0910_RCINSDEL1 0xf604 +#define FSTV0910_TSRCINS_BBPADDING 0xf6040080 +#define FSTV0910_TSRCINS_BCHFEC 0xf6040040 +#define FSTV0910_TSRCINS_EMODCOD 0xf6040010 +#define FSTV0910_TSRCINS_TOKEN 0xf6040008 +#define FSTV0910_TSRCINS_XXXERR 0xf6040004 +#define FSTV0910_TSRCINS_MATYPE 0xf6040002 +#define FSTV0910_TSRCINS_UPL 0xf6040001 + +/*RCINSDEL0*/ +#define RSTV0910_RCINSDEL0 0xf605 +#define FSTV0910_TSRCINS_DFL 0xf6050080 +#define FSTV0910_TSRCINS_SYNCD 0xf6050040 +#define FSTV0910_TSRCINS_BLOCLEN 0xf6050020 +#define FSTV0910_TSRCINS_SIGPCOUNT 0xf6050010 +#define FSTV0910_TSRCINS_FIFO 0xf6050008 +#define FSTV0910_TSRCINS_REALPACK 0xf6050004 +#define FSTV0910_TSRCINS_TSCONFIG 0xf6050002 +#define FSTV0910_TSRCINS_LATENCY 0xf6050001 + +/*RCSTATUS*/ +#define RSTV0910_RCSTATUS 0xf606 +#define FSTV0910_TSRCFIFO_LINEOK 0xf6060080 +#define FSTV0910_TSRCFIFO_ERROR 0xf6060040 +#define FSTV0910_TSRCREGUL_ERROR 0xf6060010 +#define FSTV0910_TSRCFIFO_DEMODSEL 0xf6060008 +#define FSTV0910_TSRCFIFOSPEED_STORE 0xf6060004 +#define FSTV0910_TSRCSPEED_IMPOSSIBLE 0xf6060001 + +/*RCSPEED*/ +#define RSTV0910_RCSPEED 0xf607 +#define FSTV0910_TSRCFIFO_OUTSPEED 0xf60700ff + +/*TSGENERAL*/ +#define RSTV0910_TSGENERAL 0xf630 +#define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040 +#define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008 +#define FSTV0910_TSFIFO_PERMPARAL 0xf6300006 + +/*P1_DISIRQCFG*/ +#define RSTV0910_P1_DISIRQCFG 0xf700 +#define FSTV0910_P1_ENRXEND 0xf7000040 +#define FSTV0910_P1_ENRXFIFO8B 0xf7000020 +#define FSTV0910_P1_ENTRFINISH 0xf7000010 +#define FSTV0910_P1_ENTIMEOUT 0xf7000008 +#define FSTV0910_P1_ENTXEND 0xf7000004 +#define FSTV0910_P1_ENTXFIFO64B 0xf7000002 +#define FSTV0910_P1_ENGAPBURST 0xf7000001 + +/*P1_DISIRQSTAT*/ +#define RSTV0910_P1_DISIRQSTAT 0xf701 +#define FSTV0910_P1_IRQRXEND 0xf7010040 +#define FSTV0910_P1_IRQRXFIFO8B 0xf7010020 +#define FSTV0910_P1_IRQTRFINISH 0xf7010010 +#define FSTV0910_P1_IRQTIMEOUT 0xf7010008 +#define FSTV0910_P1_IRQTXEND 0xf7010004 +#define FSTV0910_P1_IRQTXFIFO64B 0xf7010002 +#define FSTV0910_P1_IRQGAPBURST 0xf7010001 + +/*P1_DISTXCFG*/ +#define RSTV0910_P1_DISTXCFG 0xf702 +#define FSTV0910_P1_DISTX_RESET 0xf7020080 +#define FSTV0910_P1_TIM_OFF 0xf7020040 +#define FSTV0910_P1_TIM_CMD 0xf7020030 +#define FSTV0910_P1_ENVELOP 0xf7020008 +#define FSTV0910_P1_DIS_PRECHARGE 0xf7020004 +#define FSTV0910_P1_DISEQC_MODE 0xf7020003 + +/*P1_DISTXSTATUS*/ +#define RSTV0910_P1_DISTXSTATUS 0xf703 +#define FSTV0910_P1_TX_FIFO_FULL 0xf7030040 +#define FSTV0910_P1_TX_IDLE 0xf7030020 +#define FSTV0910_P1_GAP_BURST 0xf7030010 +#define FSTV0910_P1_TX_FIFO64B 0xf7030008 +#define FSTV0910_P1_TX_END 0xf7030004 +#define FSTV0910_P1_TR_TIMEOUT 0xf7030002 +#define FSTV0910_P1_TR_FINISH 0xf7030001 + +/*P1_DISTXBYTES*/ +#define RSTV0910_P1_DISTXBYTES 0xf704 +#define FSTV0910_P1_TXFIFO_BYTES 0xf70400ff + +/*P1_DISTXFIFO*/ +#define RSTV0910_P1_DISTXFIFO 0xf705 +#define FSTV0910_P1_DISEQC_TX_FIFO 0xf70500ff + +/*P1_DISTXF22*/ +#define RSTV0910_P1_DISTXF22 0xf706 +#define FSTV0910_P1_F22TX 0xf70600ff + +/*P1_DISTIMEOCFG*/ +#define RSTV0910_P1_DISTIMEOCFG 0xf708 +#define FSTV0910_P1_RXCHOICE 0xf7080006 +#define FSTV0910_P1_TIMEOUT_OFF 0xf7080001 + +/*P1_DISTIMEOUT*/ +#define RSTV0910_P1_DISTIMEOUT 0xf709 +#define FSTV0910_P1_TIMEOUT_COUNT 0xf70900ff + +/*P1_DISRXCFG*/ +#define RSTV0910_P1_DISRXCFG 0xf70a +#define FSTV0910_P1_DISRX_RESET 0xf70a0080 +#define FSTV0910_P1_EXTENVELOP 0xf70a0040 +#define FSTV0910_P1_PINSELECT 0xf70a0038 +#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a0004 +#define FSTV0910_P1_SIGNED_RXIN 0xf70a0002 +#define FSTV0910_P1_DISRX_ON 0xf70a0001 + +/*P1_DISRXSTAT1*/ +#define RSTV0910_P1_DISRXSTAT1 0xf70b +#define FSTV0910_P1_RXEND 0xf70b0080 +#define FSTV0910_P1_RXACTIVE 0xf70b0040 +#define FSTV0910_P1_RXDETECT 0xf70b0020 +#define FSTV0910_P1_CONTTONE 0xf70b0010 +#define FSTV0910_P1_8BFIFOREADY 0xf70b0008 +#define FSTV0910_P1_FIFOEMPTY 0xf70b0004 + +/*P1_DISRXSTAT0*/ +#define RSTV0910_P1_DISRXSTAT0 0xf70c +#define FSTV0910_P1_RXFAIL 0xf70c0080 +#define FSTV0910_P1_FIFOPFAIL 0xf70c0040 +#define FSTV0910_P1_RXNONBYTE 0xf70c0020 +#define FSTV0910_P1_FIFOOVF 0xf70c0010 +#define FSTV0910_P1_SHORT22K 0xf70c0008 +#define FSTV0910_P1_RXMSGLOST 0xf70c0004 + +/*P1_DISRXBYTES*/ +#define RSTV0910_P1_DISRXBYTES 0xf70d +#define FSTV0910_P1_RXFIFO_BYTES 0xf70d001f + +/*P1_DISRXPARITY1*/ +#define RSTV0910_P1_DISRXPARITY1 0xf70e +#define FSTV0910_P1_DISRX_PARITY1 0xf70e00ff + +/*P1_DISRXPARITY0*/ +#define RSTV0910_P1_DISRXPARITY0 0xf70f +#define FSTV0910_P1_DISRX_PARITY0 0xf70f00ff + +/*P1_DISRXFIFO*/ +#define RSTV0910_P1_DISRXFIFO 0xf710 +#define FSTV0910_P1_DISEQC_RX_FIFO 0xf71000ff + +/*P1_DISRXDC1*/ +#define RSTV0910_P1_DISRXDC1 0xf711 +#define FSTV0910_P1_DC_VALUE1 0xf7110103 + +/*P1_DISRXDC0*/ +#define RSTV0910_P1_DISRXDC0 0xf712 +#define FSTV0910_P1_DC_VALUE0 0xf71200ff + +/*P1_DISRXF221*/ +#define RSTV0910_P1_DISRXF221 0xf714 +#define FSTV0910_P1_F22RX1 0xf714000f + +/*P1_DISRXF220*/ +#define RSTV0910_P1_DISRXF220 0xf715 +#define FSTV0910_P1_F22RX0 0xf71500ff + +/*P1_DISRXF100*/ +#define RSTV0910_P1_DISRXF100 0xf716 +#define FSTV0910_P1_F100RX 0xf71600ff + +/*P1_DISRXSHORT22K*/ +#define RSTV0910_P1_DISRXSHORT22K 0xf71c +#define FSTV0910_P1_SHORT22K_LENGTH 0xf71c001f + +/*P1_ACRPRESC*/ +#define RSTV0910_P1_ACRPRESC 0xf71e +#define FSTV0910_P1_ACR_PRESC 0xf71e0007 + +/*P1_ACRDIV*/ +#define RSTV0910_P1_ACRDIV 0xf71f +#define FSTV0910_P1_ACR_DIV 0xf71f00ff + +/*P2_DISIRQCFG*/ +#define RSTV0910_P2_DISIRQCFG 0xf740 +#define FSTV0910_P2_ENRXEND 0xf7400040 +#define FSTV0910_P2_ENRXFIFO8B 0xf7400020 +#define FSTV0910_P2_ENTRFINISH 0xf7400010 +#define FSTV0910_P2_ENTIMEOUT 0xf7400008 +#define FSTV0910_P2_ENTXEND 0xf7400004 +#define FSTV0910_P2_ENTXFIFO64B 0xf7400002 +#define FSTV0910_P2_ENGAPBURST 0xf7400001 + +/*P2_DISIRQSTAT*/ +#define RSTV0910_P2_DISIRQSTAT 0xf741 +#define FSTV0910_P2_IRQRXEND 0xf7410040 +#define FSTV0910_P2_IRQRXFIFO8B 0xf7410020 +#define FSTV0910_P2_IRQTRFINISH 0xf7410010 +#define FSTV0910_P2_IRQTIMEOUT 0xf7410008 +#define FSTV0910_P2_IRQTXEND 0xf7410004 +#define FSTV0910_P2_IRQTXFIFO64B 0xf7410002 +#define FSTV0910_P2_IRQGAPBURST 0xf7410001 + +/*P2_DISTXCFG*/ +#define RSTV0910_P2_DISTXCFG 0xf742 +#define FSTV0910_P2_DISTX_RESET 0xf7420080 +#define FSTV0910_P2_TIM_OFF 0xf7420040 +#define FSTV0910_P2_TIM_CMD 0xf7420030 +#define FSTV0910_P2_ENVELOP 0xf7420008 +#define FSTV0910_P2_DIS_PRECHARGE 0xf7420004 +#define FSTV0910_P2_DISEQC_MODE 0xf7420003 + +/*P2_DISTXSTATUS*/ +#define RSTV0910_P2_DISTXSTATUS 0xf743 +#define FSTV0910_P2_TX_FIFO_FULL 0xf7430040 +#define FSTV0910_P2_TX_IDLE 0xf7430020 +#define FSTV0910_P2_GAP_BURST 0xf7430010 +#define FSTV0910_P2_TX_FIFO64B 0xf7430008 +#define FSTV0910_P2_TX_END 0xf7430004 +#define FSTV0910_P2_TR_TIMEOUT 0xf7430002 +#define FSTV0910_P2_TR_FINISH 0xf7430001 + +/*P2_DISTXBYTES*/ +#define RSTV0910_P2_DISTXBYTES 0xf744 +#define FSTV0910_P2_TXFIFO_BYTES 0xf74400ff + +/*P2_DISTXFIFO*/ +#define RSTV0910_P2_DISTXFIFO 0xf745 +#define FSTV0910_P2_DISEQC_TX_FIFO 0xf74500ff + +/*P2_DISTXF22*/ +#define RSTV0910_P2_DISTXF22 0xf746 +#define FSTV0910_P2_F22TX 0xf74600ff + +/*P2_DISTIMEOCFG*/ +#define RSTV0910_P2_DISTIMEOCFG 0xf748 +#define FSTV0910_P2_RXCHOICE 0xf7480006 +#define FSTV0910_P2_TIMEOUT_OFF 0xf7480001 + +/*P2_DISTIMEOUT*/ +#define RSTV0910_P2_DISTIMEOUT 0xf749 +#define FSTV0910_P2_TIMEOUT_COUNT 0xf74900ff + +/*P2_DISRXCFG*/ +#define RSTV0910_P2_DISRXCFG 0xf74a +#define FSTV0910_P2_DISRX_RESET 0xf74a0080 +#define FSTV0910_P2_EXTENVELOP 0xf74a0040 +#define FSTV0910_P2_PINSELECT 0xf74a0038 +#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a0004 +#define FSTV0910_P2_SIGNED_RXIN 0xf74a0002 +#define FSTV0910_P2_DISRX_ON 0xf74a0001 + +/*P2_DISRXSTAT1*/ +#define RSTV0910_P2_DISRXSTAT1 0xf74b +#define FSTV0910_P2_RXEND 0xf74b0080 +#define FSTV0910_P2_RXACTIVE 0xf74b0040 +#define FSTV0910_P2_RXDETECT 0xf74b0020 +#define FSTV0910_P2_CONTTONE 0xf74b0010 +#define FSTV0910_P2_8BFIFOREADY 0xf74b0008 +#define FSTV0910_P2_FIFOEMPTY 0xf74b0004 + +/*P2_DISRXSTAT0*/ +#define RSTV0910_P2_DISRXSTAT0 0xf74c +#define FSTV0910_P2_RXFAIL 0xf74c0080 +#define FSTV0910_P2_FIFOPFAIL 0xf74c0040 +#define FSTV0910_P2_RXNONBYTE 0xf74c0020 +#define FSTV0910_P2_FIFOOVF 0xf74c0010 +#define FSTV0910_P2_SHORT22K 0xf74c0008 +#define FSTV0910_P2_RXMSGLOST 0xf74c0004 + +/*P2_DISRXBYTES*/ +#define RSTV0910_P2_DISRXBYTES 0xf74d +#define FSTV0910_P2_RXFIFO_BYTES 0xf74d001f + +/*P2_DISRXPARITY1*/ +#define RSTV0910_P2_DISRXPARITY1 0xf74e +#define FSTV0910_P2_DISRX_PARITY1 0xf74e00ff + +/*P2_DISRXPARITY0*/ +#define RSTV0910_P2_DISRXPARITY0 0xf74f +#define FSTV0910_P2_DISRX_PARITY0 0xf74f00ff + +/*P2_DISRXFIFO*/ +#define RSTV0910_P2_DISRXFIFO 0xf750 +#define FSTV0910_P2_DISEQC_RX_FIFO 0xf75000ff + +/*P2_DISRXDC1*/ +#define RSTV0910_P2_DISRXDC1 0xf751 +#define FSTV0910_P2_DC_VALUE1 0xf7510103 + +/*P2_DISRXDC0*/ +#define RSTV0910_P2_DISRXDC0 0xf752 +#define FSTV0910_P2_DC_VALUE0 0xf75200ff + +/*P2_DISRXF221*/ +#define RSTV0910_P2_DISRXF221 0xf754 +#define FSTV0910_P2_F22RX1 0xf754000f + +/*P2_DISRXF220*/ +#define RSTV0910_P2_DISRXF220 0xf755 +#define FSTV0910_P2_F22RX0 0xf75500ff + +/*P2_DISRXF100*/ +#define RSTV0910_P2_DISRXF100 0xf756 +#define FSTV0910_P2_F100RX 0xf75600ff + +/*P2_DISRXSHORT22K*/ +#define RSTV0910_P2_DISRXSHORT22K 0xf75c +#define FSTV0910_P2_SHORT22K_LENGTH 0xf75c001f + +/*P2_ACRPRESC*/ +#define RSTV0910_P2_ACRPRESC 0xf75e +#define FSTV0910_P2_ACR_PRESC 0xf75e0007 + +/*P2_ACRDIV*/ +#define RSTV0910_P2_ACRDIV 0xf75f +#define FSTV0910_P2_ACR_DIV 0xf75f00ff + +/*P1_NBITER_NF1*/ +#define RSTV0910_P1_NBITER_NF1 0xfa00 +#define FSTV0910_P1_NBITER_NF_QPSK_1_4 0xfa0000ff + +/*P1_NBITER_NF2*/ +#define RSTV0910_P1_NBITER_NF2 0xfa01 +#define FSTV0910_P1_NBITER_NF_QPSK_1_3 0xfa0100ff + +/*P1_NBITER_NF3*/ +#define RSTV0910_P1_NBITER_NF3 0xfa02 +#define FSTV0910_P1_NBITER_NF_QPSK_2_5 0xfa0200ff + +/*P1_NBITER_NF4*/ +#define RSTV0910_P1_NBITER_NF4 0xfa03 +#define FSTV0910_P1_NBITER_NF_QPSK_1_2 0xfa0300ff + +/*P1_NBITER_NF5*/ +#define RSTV0910_P1_NBITER_NF5 0xfa04 +#define FSTV0910_P1_NBITER_NF_QPSK_3_5 0xfa0400ff + +/*P1_NBITER_NF6*/ +#define RSTV0910_P1_NBITER_NF6 0xfa05 +#define FSTV0910_P1_NBITER_NF_QPSK_2_3 0xfa0500ff + +/*P1_NBITER_NF7*/ +#define RSTV0910_P1_NBITER_NF7 0xfa06 +#define FSTV0910_P1_NBITER_NF_QPSK_3_4 0xfa0600ff + +/*P1_NBITER_NF8*/ +#define RSTV0910_P1_NBITER_NF8 0xfa07 +#define FSTV0910_P1_NBITER_NF_QPSK_4_5 0xfa0700ff + +/*P1_NBITER_NF9*/ +#define RSTV0910_P1_NBITER_NF9 0xfa08 +#define FSTV0910_P1_NBITER_NF_QPSK_5_6 0xfa0800ff + +/*P1_NBITER_NF10*/ +#define RSTV0910_P1_NBITER_NF10 0xfa09 +#define FSTV0910_P1_NBITER_NF_QPSK_8_9 0xfa0900ff + +/*P1_NBITER_NF11*/ +#define RSTV0910_P1_NBITER_NF11 0xfa0a +#define FSTV0910_P1_NBITER_NF_QPSK_9_10 0xfa0a00ff + +/*P1_NBITER_NF12*/ +#define RSTV0910_P1_NBITER_NF12 0xfa0b +#define FSTV0910_P1_NBITER_NF_8PSK_3_5 0xfa0b00ff + +/*P1_NBITER_NF13*/ +#define RSTV0910_P1_NBITER_NF13 0xfa0c +#define FSTV0910_P1_NBITER_NF_8PSK_2_3 0xfa0c00ff + +/*P1_NBITER_NF14*/ +#define RSTV0910_P1_NBITER_NF14 0xfa0d +#define FSTV0910_P1_NBITER_NF_8PSK_3_4 0xfa0d00ff + +/*P1_NBITER_NF15*/ +#define RSTV0910_P1_NBITER_NF15 0xfa0e +#define FSTV0910_P1_NBITER_NF_8PSK_5_6 0xfa0e00ff + +/*P1_NBITER_NF16*/ +#define RSTV0910_P1_NBITER_NF16 0xfa0f +#define FSTV0910_P1_NBITER_NF_8PSK_8_9 0xfa0f00ff + +/*P1_NBITER_NF17*/ +#define RSTV0910_P1_NBITER_NF17 0xfa10 +#define FSTV0910_P1_NBITER_NF_8PSK_9_10 0xfa1000ff + +/*P1_NBITER_NF18*/ +#define RSTV0910_P1_NBITER_NF18 0xfa11 +#define FSTV0910_P1_NBITER_NF_16APSK_2_3 0xfa1100ff + +/*P1_NBITER_NF19*/ +#define RSTV0910_P1_NBITER_NF19 0xfa12 +#define FSTV0910_P1_NBITER_NF_16APSK_3_4 0xfa1200ff + +/*P1_NBITER_NF20*/ +#define RSTV0910_P1_NBITER_NF20 0xfa13 +#define FSTV0910_P1_NBITER_NF_16APSK_4_5 0xfa1300ff + +/*P1_NBITER_NF21*/ +#define RSTV0910_P1_NBITER_NF21 0xfa14 +#define FSTV0910_P1_NBITER_NF_16APSK_5_6 0xfa1400ff + +/*P1_NBITER_NF22*/ +#define RSTV0910_P1_NBITER_NF22 0xfa15 +#define FSTV0910_P1_NBITER_NF_16APSK_8_9 0xfa1500ff + +/*P1_NBITER_NF23*/ +#define RSTV0910_P1_NBITER_NF23 0xfa16 +#define FSTV0910_P1_NBITER_NF_16APSK_9_10 0xfa1600ff + +/*P1_NBITER_NF24*/ +#define RSTV0910_P1_NBITER_NF24 0xfa17 +#define FSTV0910_P1_NBITER_NF_32APSK_3_4 0xfa1700ff + +/*P1_NBITER_NF25*/ +#define RSTV0910_P1_NBITER_NF25 0xfa18 +#define FSTV0910_P1_NBITER_NF_32APSK_4_5 0xfa1800ff + +/*P1_NBITER_NF26*/ +#define RSTV0910_P1_NBITER_NF26 0xfa19 +#define FSTV0910_P1_NBITER_NF_32APSK_5_6 0xfa1900ff + +/*P1_NBITER_NF27*/ +#define RSTV0910_P1_NBITER_NF27 0xfa1a +#define FSTV0910_P1_NBITER_NF_32APSK_8_9 0xfa1a00ff + +/*P1_NBITER_NF28*/ +#define RSTV0910_P1_NBITER_NF28 0xfa1b +#define FSTV0910_P1_NBITER_NF_32APSK_9_10 0xfa1b00ff + +/*P1_NBITER_SF1*/ +#define RSTV0910_P1_NBITER_SF1 0xfa1c +#define FSTV0910_P1_NBITER_SF_QPSK_1_4 0xfa1c00ff + +/*P1_NBITER_SF2*/ +#define RSTV0910_P1_NBITER_SF2 0xfa1d +#define FSTV0910_P1_NBITER_SF_QPSK_1_3 0xfa1d00ff + +/*P1_NBITER_SF3*/ +#define RSTV0910_P1_NBITER_SF3 0xfa1e +#define FSTV0910_P1_NBITER_SF_QPSK_2_5 0xfa1e00ff + +/*P1_NBITER_SF4*/ +#define RSTV0910_P1_NBITER_SF4 0xfa1f +#define FSTV0910_P1_NBITER_SF_QPSK_1_2 0xfa1f00ff + +/*P1_NBITER_SF5*/ +#define RSTV0910_P1_NBITER_SF5 0xfa20 +#define FSTV0910_P1_NBITER_SF_QPSK_3_5 0xfa2000ff + +/*P1_NBITER_SF6*/ +#define RSTV0910_P1_NBITER_SF6 0xfa21 +#define FSTV0910_P1_NBITER_SF_QPSK_2_3 0xfa2100ff + +/*P1_NBITER_SF7*/ +#define RSTV0910_P1_NBITER_SF7 0xfa22 +#define FSTV0910_P1_NBITER_SF_QPSK_3_4 0xfa2200ff + +/*P1_NBITER_SF8*/ +#define RSTV0910_P1_NBITER_SF8 0xfa23 +#define FSTV0910_P1_NBITER_SF_QPSK_4_5 0xfa2300ff + +/*P1_NBITER_SF9*/ +#define RSTV0910_P1_NBITER_SF9 0xfa24 +#define FSTV0910_P1_NBITER_SF_QPSK_5_6 0xfa2400ff + +/*P1_NBITER_SF10*/ +#define RSTV0910_P1_NBITER_SF10 0xfa25 +#define FSTV0910_P1_NBITER_SF_QPSK_8_9 0xfa2500ff + +/*P1_NBITER_SF12*/ +#define RSTV0910_P1_NBITER_SF12 0xfa26 +#define FSTV0910_P1_NBITER_SF_8PSK_3_5 0xfa2600ff + +/*P1_NBITER_SF13*/ +#define RSTV0910_P1_NBITER_SF13 0xfa27 +#define FSTV0910_P1_NBITER_SF_8PSK_2_3 0xfa2700ff + +/*P1_NBITER_SF14*/ +#define RSTV0910_P1_NBITER_SF14 0xfa28 +#define FSTV0910_P1_NBITER_SF_8PSK_3_4 0xfa2800ff + +/*P1_NBITER_SF15*/ +#define RSTV0910_P1_NBITER_SF15 0xfa29 +#define FSTV0910_P1_NBITER_SF_8PSK_5_6 0xfa2900ff + +/*P1_NBITER_SF16*/ +#define RSTV0910_P1_NBITER_SF16 0xfa2a +#define FSTV0910_P1_NBITER_SF_8PSK_8_9 0xfa2a00ff + +/*P1_NBITER_SF18*/ +#define RSTV0910_P1_NBITER_SF18 0xfa2b +#define FSTV0910_P1_NBITER_SF_16APSK_2_3 0xfa2b00ff + +/*P1_NBITER_SF19*/ +#define RSTV0910_P1_NBITER_SF19 0xfa2c +#define FSTV0910_P1_NBITER_SF_16APSK_3_4 0xfa2c00ff + +/*P1_NBITER_SF20*/ +#define RSTV0910_P1_NBITER_SF20 0xfa2d +#define FSTV0910_P1_NBITER_SF_16APSK_4_5 0xfa2d00ff + +/*P1_NBITER_SF21*/ +#define RSTV0910_P1_NBITER_SF21 0xfa2e +#define FSTV0910_P1_NBITER_SF_16APSK_5_6 0xfa2e00ff + +/*P1_NBITER_SF22*/ +#define RSTV0910_P1_NBITER_SF22 0xfa2f +#define FSTV0910_P1_NBITER_SF_16APSK_8_9 0xfa2f00ff + +/*P1_NBITER_SF24*/ +#define RSTV0910_P1_NBITER_SF24 0xfa30 +#define FSTV0910_P1_NBITER_SF_32APSK_3_4 0xfa3000ff + +/*P1_NBITER_SF25*/ +#define RSTV0910_P1_NBITER_SF25 0xfa31 +#define FSTV0910_P1_NBITER_SF_32APSK_4_5 0xfa3100ff + +/*P1_NBITER_SF26*/ +#define RSTV0910_P1_NBITER_SF26 0xfa32 +#define FSTV0910_P1_NBITER_SF_32APSK_5_6 0xfa3200ff + +/*P1_NBITER_SF27*/ +#define RSTV0910_P1_NBITER_SF27 0xfa33 +#define FSTV0910_P1_NBITER_SF_32APSK_8_9 0xfa3300ff + +/*SELSATUR6*/ +#define RSTV0910_SELSATUR6 0xfa34 +#define FSTV0910_SSAT_SF27 0xfa340008 +#define FSTV0910_SSAT_SF26 0xfa340004 +#define FSTV0910_SSAT_SF25 0xfa340002 +#define FSTV0910_SSAT_SF24 0xfa340001 + +/*SELSATUR5*/ +#define RSTV0910_SELSATUR5 0xfa35 +#define FSTV0910_SSAT_SF22 0xfa350080 +#define FSTV0910_SSAT_SF21 0xfa350040 +#define FSTV0910_SSAT_SF20 0xfa350020 +#define FSTV0910_SSAT_SF19 0xfa350010 +#define FSTV0910_SSAT_SF18 0xfa350008 +#define FSTV0910_SSAT_SF16 0xfa350004 +#define FSTV0910_SSAT_SF15 0xfa350002 +#define FSTV0910_SSAT_SF14 0xfa350001 + +/*SELSATUR4*/ +#define RSTV0910_SELSATUR4 0xfa36 +#define FSTV0910_SSAT_SF13 0xfa360080 +#define FSTV0910_SSAT_SF12 0xfa360040 +#define FSTV0910_SSAT_SF10 0xfa360020 +#define FSTV0910_SSAT_SF9 0xfa360010 +#define FSTV0910_SSAT_SF8 0xfa360008 +#define FSTV0910_SSAT_SF7 0xfa360004 +#define FSTV0910_SSAT_SF6 0xfa360002 +#define FSTV0910_SSAT_SF5 0xfa360001 + +/*SELSATUR3*/ +#define RSTV0910_SELSATUR3 0xfa37 +#define FSTV0910_SSAT_SF4 0xfa370080 +#define FSTV0910_SSAT_SF3 0xfa370040 +#define FSTV0910_SSAT_SF2 0xfa370020 +#define FSTV0910_SSAT_SF1 0xfa370010 +#define FSTV0910_SSAT_NF28 0xfa370008 +#define FSTV0910_SSAT_NF27 0xfa370004 +#define FSTV0910_SSAT_NF26 0xfa370002 +#define FSTV0910_SSAT_NF25 0xfa370001 + +/*SELSATUR2*/ +#define RSTV0910_SELSATUR2 0xfa38 +#define FSTV0910_SSAT_NF24 0xfa380080 +#define FSTV0910_SSAT_NF23 0xfa380040 +#define FSTV0910_SSAT_NF22 0xfa380020 +#define FSTV0910_SSAT_NF21 0xfa380010 +#define FSTV0910_SSAT_NF20 0xfa380008 +#define FSTV0910_SSAT_NF19 0xfa380004 +#define FSTV0910_SSAT_NF18 0xfa380002 +#define FSTV0910_SSAT_NF17 0xfa380001 + +/*SELSATUR1*/ +#define RSTV0910_SELSATUR1 0xfa39 +#define FSTV0910_SSAT_NF16 0xfa390080 +#define FSTV0910_SSAT_NF15 0xfa390040 +#define FSTV0910_SSAT_NF14 0xfa390020 +#define FSTV0910_SSAT_NF13 0xfa390010 +#define FSTV0910_SSAT_NF12 0xfa390008 +#define FSTV0910_SSAT_NF11 0xfa390004 +#define FSTV0910_SSAT_NF10 0xfa390002 +#define FSTV0910_SSAT_NF9 0xfa390001 + +/*SELSATUR0*/ +#define RSTV0910_SELSATUR0 0xfa3a +#define FSTV0910_SSAT_NF8 0xfa3a0080 +#define FSTV0910_SSAT_NF7 0xfa3a0040 +#define FSTV0910_SSAT_NF6 0xfa3a0020 +#define FSTV0910_SSAT_NF5 0xfa3a0010 +#define FSTV0910_SSAT_NF4 0xfa3a0008 +#define FSTV0910_SSAT_NF3 0xfa3a0004 +#define FSTV0910_SSAT_NF2 0xfa3a0002 +#define FSTV0910_SSAT_NF1 0xfa3a0001 + +/*GAINLLR_NF1*/ +#define RSTV0910_GAINLLR_NF1 0xfa40 +#define FSTV0910_GAINLLR_NF_QPSK_1_4 0xfa40007f + +/*GAINLLR_NF2*/ +#define RSTV0910_GAINLLR_NF2 0xfa41 +#define FSTV0910_GAINLLR_NF_QPSK_1_3 0xfa41007f + +/*GAINLLR_NF3*/ +#define RSTV0910_GAINLLR_NF3 0xfa42 +#define FSTV0910_GAINLLR_NF_QPSK_2_5 0xfa42007f + +/*GAINLLR_NF4*/ +#define RSTV0910_GAINLLR_NF4 0xfa43 +#define FSTV0910_GAINLLR_NF_QPSK_1_2 0xfa43007f + +/*GAINLLR_NF5*/ +#define RSTV0910_GAINLLR_NF5 0xfa44 +#define FSTV0910_GAINLLR_NF_QPSK_3_5 0xfa44007f + +/*GAINLLR_NF6*/ +#define RSTV0910_GAINLLR_NF6 0xfa45 +#define FSTV0910_GAINLLR_NF_QPSK_2_3 0xfa45007f + +/*GAINLLR_NF7*/ +#define RSTV0910_GAINLLR_NF7 0xfa46 +#define FSTV0910_GAINLLR_NF_QPSK_3_4 0xfa46007f + +/*GAINLLR_NF8*/ +#define RSTV0910_GAINLLR_NF8 0xfa47 +#define FSTV0910_GAINLLR_NF_QPSK_4_5 0xfa47007f + +/*GAINLLR_NF9*/ +#define RSTV0910_GAINLLR_NF9 0xfa48 +#define FSTV0910_GAINLLR_NF_QPSK_5_6 0xfa48007f + +/*GAINLLR_NF10*/ +#define RSTV0910_GAINLLR_NF10 0xfa49 +#define FSTV0910_GAINLLR_NF_QPSK_8_9 0xfa49007f + +/*GAINLLR_NF11*/ +#define RSTV0910_GAINLLR_NF11 0xfa4a +#define FSTV0910_GAINLLR_NF_QPSK_9_10 0xfa4a007f + +/*GAINLLR_NF12*/ +#define RSTV0910_GAINLLR_NF12 0xfa4b +#define FSTV0910_GAINLLR_NF_8PSK_3_5 0xfa4b007f + +/*GAINLLR_NF13*/ +#define RSTV0910_GAINLLR_NF13 0xfa4c +#define FSTV0910_GAINLLR_NF_8PSK_2_3 0xfa4c007f + +/*GAINLLR_NF14*/ +#define RSTV0910_GAINLLR_NF14 0xfa4d +#define FSTV0910_GAINLLR_NF_8PSK_3_4 0xfa4d007f + +/*GAINLLR_NF15*/ +#define RSTV0910_GAINLLR_NF15 0xfa4e +#define FSTV0910_GAINLLR_NF_8PSK_5_6 0xfa4e007f + +/*GAINLLR_NF16*/ +#define RSTV0910_GAINLLR_NF16 0xfa4f +#define FSTV0910_GAINLLR_NF_8PSK_8_9 0xfa4f007f + +/*GAINLLR_NF17*/ +#define RSTV0910_GAINLLR_NF17 0xfa50 +#define FSTV0910_GAINLLR_NF_8PSK_9_10 0xfa50007f + +/*GAINLLR_NF18*/ +#define RSTV0910_GAINLLR_NF18 0xfa51 +#define FSTV0910_GAINLLR_NF_16APSK_2_3 0xfa51007f + +/*GAINLLR_NF19*/ +#define RSTV0910_GAINLLR_NF19 0xfa52 +#define FSTV0910_GAINLLR_NF_16APSK_3_4 0xfa52007f + +/*GAINLLR_NF20*/ +#define RSTV0910_GAINLLR_NF20 0xfa53 +#define FSTV0910_GAINLLR_NF_16APSK_4_5 0xfa53007f + +/*GAINLLR_NF21*/ +#define RSTV0910_GAINLLR_NF21 0xfa54 +#define FSTV0910_GAINLLR_NF_16APSK_5_6 0xfa54007f + +/*GAINLLR_NF22*/ +#define RSTV0910_GAINLLR_NF22 0xfa55 +#define FSTV0910_GAINLLR_NF_16APSK_8_9 0xfa55007f + +/*GAINLLR_NF23*/ +#define RSTV0910_GAINLLR_NF23 0xfa56 +#define FSTV0910_GAINLLR_NF_16APSK_9_10 0xfa56007f + +/*GAINLLR_NF24*/ +#define RSTV0910_GAINLLR_NF24 0xfa57 +#define FSTV0910_GAINLLR_NF_32APSK_3_4 0xfa57007f + +/*GAINLLR_NF25*/ +#define RSTV0910_GAINLLR_NF25 0xfa58 +#define FSTV0910_GAINLLR_NF_32APSK_4_5 0xfa58007f + +/*GAINLLR_NF26*/ +#define RSTV0910_GAINLLR_NF26 0xfa59 +#define FSTV0910_GAINLLR_NF_32APSK_5_6 0xfa59007f + +/*GAINLLR_NF27*/ +#define RSTV0910_GAINLLR_NF27 0xfa5a +#define FSTV0910_GAINLLR_NF_32APSK_8_9 0xfa5a007f + +/*GAINLLR_NF28*/ +#define RSTV0910_GAINLLR_NF28 0xfa5b +#define FSTV0910_GAINLLR_NF_32APSK_9_10 0xfa5b007f + +/*GAINLLR_SF1*/ +#define RSTV0910_GAINLLR_SF1 0xfa5c +#define FSTV0910_GAINLLR_SF_QPSK_1_4 0xfa5c007f + +/*GAINLLR_SF2*/ +#define RSTV0910_GAINLLR_SF2 0xfa5d +#define FSTV0910_GAINLLR_SF_QPSK_1_3 0xfa5d007f + +/*GAINLLR_SF3*/ +#define RSTV0910_GAINLLR_SF3 0xfa5e +#define FSTV0910_GAINLLR_SF_QPSK_2_5 0xfa5e007f + +/*GAINLLR_SF4*/ +#define RSTV0910_GAINLLR_SF4 0xfa5f +#define FSTV0910_GAINLLR_SF_QPSK_1_2 0xfa5f007f + +/*GAINLLR_SF5*/ +#define RSTV0910_GAINLLR_SF5 0xfa60 +#define FSTV0910_GAINLLR_SF_QPSK_3_5 0xfa60007f + +/*GAINLLR_SF6*/ +#define RSTV0910_GAINLLR_SF6 0xfa61 +#define FSTV0910_GAINLLR_SF_QPSK_2_3 0xfa61007f + +/*GAINLLR_SF7*/ +#define RSTV0910_GAINLLR_SF7 0xfa62 +#define FSTV0910_GAINLLR_SF_QPSK_3_4 0xfa62007f + +/*GAINLLR_SF8*/ +#define RSTV0910_GAINLLR_SF8 0xfa63 +#define FSTV0910_GAINLLR_SF_QPSK_4_5 0xfa63007f + +/*GAINLLR_SF9*/ +#define RSTV0910_GAINLLR_SF9 0xfa64 +#define FSTV0910_GAINLLR_SF_QPSK_5_6 0xfa64007f + +/*GAINLLR_SF10*/ +#define RSTV0910_GAINLLR_SF10 0xfa65 +#define FSTV0910_GAINLLR_SF_QPSK_8_9 0xfa65007f + +/*GAINLLR_SF12*/ +#define RSTV0910_GAINLLR_SF12 0xfa66 +#define FSTV0910_GAINLLR_SF_8PSK_3_5 0xfa66007f + +/*GAINLLR_SF13*/ +#define RSTV0910_GAINLLR_SF13 0xfa67 +#define FSTV0910_GAINLLR_SF_8PSK_2_3 0xfa67007f + +/*GAINLLR_SF14*/ +#define RSTV0910_GAINLLR_SF14 0xfa68 +#define FSTV0910_GAINLLR_SF_8PSK_3_4 0xfa68007f + +/*GAINLLR_SF15*/ +#define RSTV0910_GAINLLR_SF15 0xfa69 +#define FSTV0910_GAINLLR_SF_8PSK_5_6 0xfa69007f + +/*GAINLLR_SF16*/ +#define RSTV0910_GAINLLR_SF16 0xfa6a +#define FSTV0910_GAINLLR_SF_8PSK_8_9 0xfa6a007f + +/*GAINLLR_SF18*/ +#define RSTV0910_GAINLLR_SF18 0xfa6b +#define FSTV0910_GAINLLR_SF_16APSK_2_3 0xfa6b007f + +/*GAINLLR_SF19*/ +#define RSTV0910_GAINLLR_SF19 0xfa6c +#define FSTV0910_GAINLLR_SF_16APSK_3_4 0xfa6c007f + +/*GAINLLR_SF20*/ +#define RSTV0910_GAINLLR_SF20 0xfa6d +#define FSTV0910_GAINLLR_SF_16APSK_4_5 0xfa6d007f + +/*GAINLLR_SF21*/ +#define RSTV0910_GAINLLR_SF21 0xfa6e +#define FSTV0910_GAINLLR_SF_16APSK_5_6 0xfa6e007f + +/*GAINLLR_SF22*/ +#define RSTV0910_GAINLLR_SF22 0xfa6f +#define FSTV0910_GAINLLR_SF_16APSK_8_9 0xfa6f007f + +/*GAINLLR_SF24*/ +#define RSTV0910_GAINLLR_SF24 0xfa70 +#define FSTV0910_GAINLLR_SF_32APSK_3_4 0xfa70007f + +/*GAINLLR_SF25*/ +#define RSTV0910_GAINLLR_SF25 0xfa71 +#define FSTV0910_GAINLLR_SF_32APSK_4_5 0xfa71007f + +/*GAINLLR_SF26*/ +#define RSTV0910_GAINLLR_SF26 0xfa72 +#define FSTV0910_GAINLLR_SF_32APSK_5_6 0xfa72007f + +/*GAINLLR_SF27*/ +#define RSTV0910_GAINLLR_SF27 0xfa73 +#define FSTV0910_GAINLLR_SF_32APSK_8_9 0xfa73007f + +/*CFGEXT*/ +#define RSTV0910_CFGEXT 0xfa80 +#define FSTV0910_BYPBCH 0xfa800040 +#define FSTV0910_BYPLDPC 0xfa800020 +#define FSTV0910_SHORTMULT 0xfa800004 + +/*GENCFG*/ +#define RSTV0910_GENCFG 0xfa86 +#define FSTV0910_BROADCAST 0xfa860010 +#define FSTV0910_CROSSINPUT 0xfa860002 +#define FSTV0910_DDEMOD 0xfa860001 + +/*LDPCERR1*/ +#define RSTV0910_LDPCERR1 0xfa96 +#define FSTV0910_LDPC_ERRORS1 0xfa9600ff + +/*LDPCERR0*/ +#define RSTV0910_LDPCERR0 0xfa97 +#define FSTV0910_LDPC_ERRORS0 0xfa9700ff + +/*BCHERR*/ +#define RSTV0910_BCHERR 0xfa98 +#define FSTV0910_ERRORFLAG 0xfa980010 +#define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f + +/*P1_MAXEXTRAITER*/ +#define RSTV0910_P1_MAXEXTRAITER 0xfab1 +#define FSTV0910_P1_MAX_EXTRA_ITER 0xfab100ff + +/*P2_MAXEXTRAITER*/ +#define RSTV0910_P2_MAXEXTRAITER 0xfab6 +#define FSTV0910_P2_MAX_EXTRA_ITER 0xfab600ff + +/*P1_STATUSITER*/ +#define RSTV0910_P1_STATUSITER 0xfabc +#define FSTV0910_P1_STATUS_ITER 0xfabc00ff + +/*P1_STATUSMAXITER*/ +#define RSTV0910_P1_STATUSMAXITER 0xfabd +#define FSTV0910_P1_STATUS_MAX_ITER 0xfabd00ff + +/*P2_STATUSITER*/ +#define RSTV0910_P2_STATUSITER 0xfabe +#define FSTV0910_P2_STATUS_ITER 0xfabe00ff + +/*P2_STATUSMAXITER*/ +#define RSTV0910_P2_STATUSMAXITER 0xfabf +#define FSTV0910_P2_STATUS_MAX_ITER 0xfabf00ff + +/*P2_NBITER_NF1*/ +#define RSTV0910_P2_NBITER_NF1 0xfac0 +#define FSTV0910_P2_NBITER_NF_QPSK_1_4 0xfac000ff + +/*P2_NBITER_NF2*/ +#define RSTV0910_P2_NBITER_NF2 0xfac1 +#define FSTV0910_P2_NBITER_NF_QPSK_1_3 0xfac100ff + +/*P2_NBITER_NF3*/ +#define RSTV0910_P2_NBITER_NF3 0xfac2 +#define FSTV0910_P2_NBITER_NF_QPSK_2_5 0xfac200ff + +/*P2_NBITER_NF4*/ +#define RSTV0910_P2_NBITER_NF4 0xfac3 +#define FSTV0910_P2_NBITER_NF_QPSK_1_2 0xfac300ff + +/*P2_NBITER_NF5*/ +#define RSTV0910_P2_NBITER_NF5 0xfac4 +#define FSTV0910_P2_NBITER_NF_QPSK_3_5 0xfac400ff + +/*P2_NBITER_NF6*/ +#define RSTV0910_P2_NBITER_NF6 0xfac5 +#define FSTV0910_P2_NBITER_NF_QPSK_2_3 0xfac500ff + +/*P2_NBITER_NF7*/ +#define RSTV0910_P2_NBITER_NF7 0xfac6 +#define FSTV0910_P2_NBITER_NF_QPSK_3_4 0xfac600ff + +/*P2_NBITER_NF8*/ +#define RSTV0910_P2_NBITER_NF8 0xfac7 +#define FSTV0910_P2_NBITER_NF_QPSK_4_5 0xfac700ff + +/*P2_NBITER_NF9*/ +#define RSTV0910_P2_NBITER_NF9 0xfac8 +#define FSTV0910_P2_NBITER_NF_QPSK_5_6 0xfac800ff + +/*P2_NBITER_NF10*/ +#define RSTV0910_P2_NBITER_NF10 0xfac9 +#define FSTV0910_P2_NBITER_NF_QPSK_8_9 0xfac900ff + +/*P2_NBITER_NF11*/ +#define RSTV0910_P2_NBITER_NF11 0xfaca +#define FSTV0910_P2_NBITER_NF_QPSK_9_10 0xfaca00ff + +/*P2_NBITER_NF12*/ +#define RSTV0910_P2_NBITER_NF12 0xfacb +#define FSTV0910_P2_NBITER_NF_8PSK_3_5 0xfacb00ff + +/*P2_NBITER_NF13*/ +#define RSTV0910_P2_NBITER_NF13 0xfacc +#define FSTV0910_P2_NBITER_NF_8PSK_2_3 0xfacc00ff + +/*P2_NBITER_NF14*/ +#define RSTV0910_P2_NBITER_NF14 0xfacd +#define FSTV0910_P2_NBITER_NF_8PSK_3_4 0xfacd00ff + +/*P2_NBITER_NF15*/ +#define RSTV0910_P2_NBITER_NF15 0xface +#define FSTV0910_P2_NBITER_NF_8PSK_5_6 0xface00ff + +/*P2_NBITER_NF16*/ +#define RSTV0910_P2_NBITER_NF16 0xfacf +#define FSTV0910_P2_NBITER_NF_8PSK_8_9 0xfacf00ff + +/*P2_NBITER_NF17*/ +#define RSTV0910_P2_NBITER_NF17 0xfad0 +#define FSTV0910_P2_NBITER_NF_8PSK_9_10 0xfad000ff + +/*P2_NBITER_NF18*/ +#define RSTV0910_P2_NBITER_NF18 0xfad1 +#define FSTV0910_P2_NBITER_NF_16APSK_2_3 0xfad100ff + +/*P2_NBITER_NF19*/ +#define RSTV0910_P2_NBITER_NF19 0xfad2 +#define FSTV0910_P2_NBITER_NF_16APSK_3_4 0xfad200ff + +/*P2_NBITER_NF20*/ +#define RSTV0910_P2_NBITER_NF20 0xfad3 +#define FSTV0910_P2_NBITER_NF_16APSK_4_5 0xfad300ff + +/*P2_NBITER_NF21*/ +#define RSTV0910_P2_NBITER_NF21 0xfad4 +#define FSTV0910_P2_NBITER_NF_16APSK_5_6 0xfad400ff + +/*P2_NBITER_NF22*/ +#define RSTV0910_P2_NBITER_NF22 0xfad5 +#define FSTV0910_P2_NBITER_NF_16APSK_8_9 0xfad500ff + +/*P2_NBITER_NF23*/ +#define RSTV0910_P2_NBITER_NF23 0xfad6 +#define FSTV0910_P2_NBITER_NF_16APSK_9_10 0xfad600ff + +/*P2_NBITER_NF24*/ +#define RSTV0910_P2_NBITER_NF24 0xfad7 +#define FSTV0910_P2_NBITER_NF_32APSK_3_4 0xfad700ff + +/*P2_NBITER_NF25*/ +#define RSTV0910_P2_NBITER_NF25 0xfad8 +#define FSTV0910_P2_NBITER_NF_32APSK_4_5 0xfad800ff + +/*P2_NBITER_NF26*/ +#define RSTV0910_P2_NBITER_NF26 0xfad9 +#define FSTV0910_P2_NBITER_NF_32APSK_5_6 0xfad900ff + +/*P2_NBITER_NF27*/ +#define RSTV0910_P2_NBITER_NF27 0xfada +#define FSTV0910_P2_NBITER_NF_32APSK_8_9 0xfada00ff + +/*P2_NBITER_NF28*/ +#define RSTV0910_P2_NBITER_NF28 0xfadb +#define FSTV0910_P2_NBITER_NF_32APSK_9_10 0xfadb00ff + +/*P2_NBITER_SF1*/ +#define RSTV0910_P2_NBITER_SF1 0xfadc +#define FSTV0910_P2_NBITER_SF_QPSK_1_4 0xfadc00ff + +/*P2_NBITER_SF2*/ +#define RSTV0910_P2_NBITER_SF2 0xfadd +#define FSTV0910_P2_NBITER_SF_QPSK_1_3 0xfadd00ff + +/*P2_NBITER_SF3*/ +#define RSTV0910_P2_NBITER_SF3 0xfade +#define FSTV0910_P2_NBITER_SF_QPSK_2_5 0xfade00ff + +/*P2_NBITER_SF4*/ +#define RSTV0910_P2_NBITER_SF4 0xfadf +#define FSTV0910_P2_NBITER_SF_QPSK_1_2 0xfadf00ff + +/*P2_NBITER_SF5*/ +#define RSTV0910_P2_NBITER_SF5 0xfae0 +#define FSTV0910_P2_NBITER_SF_QPSK_3_5 0xfae000ff + +/*P2_NBITER_SF6*/ +#define RSTV0910_P2_NBITER_SF6 0xfae1 +#define FSTV0910_P2_NBITER_SF_QPSK_2_3 0xfae100ff + +/*P2_NBITER_SF7*/ +#define RSTV0910_P2_NBITER_SF7 0xfae2 +#define FSTV0910_P2_NBITER_SF_QPSK_3_4 0xfae200ff + +/*P2_NBITER_SF8*/ +#define RSTV0910_P2_NBITER_SF8 0xfae3 +#define FSTV0910_P2_NBITER_SF_QPSK_4_5 0xfae300ff + +/*P2_NBITER_SF9*/ +#define RSTV0910_P2_NBITER_SF9 0xfae4 +#define FSTV0910_P2_NBITER_SF_QPSK_5_6 0xfae400ff + +/*P2_NBITER_SF10*/ +#define RSTV0910_P2_NBITER_SF10 0xfae5 +#define FSTV0910_P2_NBITER_SF_QPSK_8_9 0xfae500ff + +/*P2_NBITER_SF12*/ +#define RSTV0910_P2_NBITER_SF12 0xfae6 +#define FSTV0910_P2_NBITER_SF_8PSK_3_5 0xfae600ff + +/*P2_NBITER_SF13*/ +#define RSTV0910_P2_NBITER_SF13 0xfae7 +#define FSTV0910_P2_NBITER_SF_8PSK_2_3 0xfae700ff + +/*P2_NBITER_SF14*/ +#define RSTV0910_P2_NBITER_SF14 0xfae8 +#define FSTV0910_P2_NBITER_SF_8PSK_3_4 0xfae800ff + +/*P2_NBITER_SF15*/ +#define RSTV0910_P2_NBITER_SF15 0xfae9 +#define FSTV0910_P2_NBITER_SF_8PSK_5_6 0xfae900ff + +/*P2_NBITER_SF16*/ +#define RSTV0910_P2_NBITER_SF16 0xfaea +#define FSTV0910_P2_NBITER_SF_8PSK_8_9 0xfaea00ff + +/*P2_NBITER_SF18*/ +#define RSTV0910_P2_NBITER_SF18 0xfaeb +#define FSTV0910_P2_NBITER_SF_16APSK_2_3 0xfaeb00ff + +/*P2_NBITER_SF19*/ +#define RSTV0910_P2_NBITER_SF19 0xfaec +#define FSTV0910_P2_NBITER_SF_16APSK_3_4 0xfaec00ff + +/*P2_NBITER_SF20*/ +#define RSTV0910_P2_NBITER_SF20 0xfaed +#define FSTV0910_P2_NBITER_SF_16APSK_4_5 0xfaed00ff + +/*P2_NBITER_SF21*/ +#define RSTV0910_P2_NBITER_SF21 0xfaee +#define FSTV0910_P2_NBITER_SF_16APSK_5_6 0xfaee00ff + +/*P2_NBITER_SF22*/ +#define RSTV0910_P2_NBITER_SF22 0xfaef +#define FSTV0910_P2_NBITER_SF_16APSK_8_9 0xfaef00ff + +/*P2_NBITER_SF24*/ +#define RSTV0910_P2_NBITER_SF24 0xfaf0 +#define FSTV0910_P2_NBITER_SF_32APSK_3_4 0xfaf000ff + +/*P2_NBITER_SF25*/ +#define RSTV0910_P2_NBITER_SF25 0xfaf1 +#define FSTV0910_P2_NBITER_SF_32APSK_4_5 0xfaf100ff + +/*P2_NBITER_SF26*/ +#define RSTV0910_P2_NBITER_SF26 0xfaf2 +#define FSTV0910_P2_NBITER_SF_32APSK_5_6 0xfaf200ff + +/*P2_NBITER_SF27*/ +#define RSTV0910_P2_NBITER_SF27 0xfaf3 +#define FSTV0910_P2_NBITER_SF_32APSK_8_9 0xfaf300ff + +/*TSTRES0*/ +#define RSTV0910_TSTRES0 0xff11 +#define FSTV0910_FRESFEC 0xff110080 +#define FSTV0910_FRESSYM1 0xff110008 +#define FSTV0910_FRESSYM2 0xff110004 + +/*TSTOUT*/ +#define RSTV0910_TSTOUT 0xff12 +#define FSTV0910_TS 0xff12003e +#define FSTV0910_TEST_OUT 0xff120001 + +/*TSTIN*/ +#define RSTV0910_TSTIN 0xff13 +#define FSTV0910_TEST_IN 0xff130080 + +/*P2_TSTDMD*/ +#define RSTV0910_P2_TSTDMD 0xff20 +#define FSTV0910_P2_CFRINIT_INVZIGZAG 0xff200008 + +/*P2_TCTL1*/ +#define RSTV0910_P2_TCTL1 0xff24 +#define FSTV0910_P2_TST_IQSYMBSEL 0xff24001f + +/*P2_TCTL4*/ +#define RSTV0910_P2_TCTL4 0xff28 +#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0 + +/*P2_TPKTDELIN*/ +#define RSTV0910_P2_TPKTDELIN 0xff37 +#define FSTV0910_P2_CFG_RSPARITYON 0xff370080 + +/*P1_TSTDMD*/ +#define RSTV0910_P1_TSTDMD 0xff40 +#define FSTV0910_P1_CFRINIT_INVZIGZAG 0xff400008 + +/*P1_TCTL1*/ +#define RSTV0910_P1_TCTL1 0xff44 +#define FSTV0910_P1_TST_IQSYMBSEL 0xff44001f + +/*P1_TCTL4*/ +#define RSTV0910_P1_TCTL4 0xff48 +#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0 + +/*P1_TPKTDELIN*/ +#define RSTV0910_P1_TPKTDELIN 0xff57 +#define FSTV0910_P1_CFG_RSPARITYON 0xff570080 + +/*TSTTSRS*/ +#define RSTV0910_TSTTSRS 0xff6d +#define FSTV0910_TSTRS_DISRS2 0xff6d0002 +#define FSTV0910_TSTRS_DISRS1 0xff6d0001 + +#define STV0910_NBREGS 975 +#define STV0910_NBFIELDS 1818 -- cgit v1.2.3 From 13c81489622b866f4b4fcbd51707ab4c09e1c8db Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:55 -0400 Subject: media: dvb-frontends/stv0910: Fix possible buffer overflow Fixes smatch error: drivers/media/dvb-frontends/stv0910.c:715 dvbs2_nbch() error: buffer overflow 'nbch[fectype]' 2 <= 28 Also, fixes the nbch array table by adding the DUMMY_PLF element at the top to match the enums (table element order was off by one before). Patch sent upstream aswell. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 9dfcaf5e067f..85439d3b725e 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -671,6 +671,7 @@ static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) { static u32 nbch[][2] = { + { 0, 0}, /* DUMMY_PLF */ {16200, 3240}, /* QPSK_1_4, */ {21600, 5400}, /* QPSK_1_3, */ {25920, 6480}, /* QPSK_2_5, */ @@ -703,7 +704,7 @@ static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) if (mod_cod >= DVBS2_QPSK_1_4 && mod_cod <= DVBS2_32APSK_9_10 && fectype <= DVBS2_16K) - return nbch[fectype][mod_cod]; + return nbch[mod_cod][fectype]; return 64800; } -- cgit v1.2.3 From ea71c62bdef59004a2fd835545cd02bbeb699f83 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:56 -0400 Subject: media: dvb-frontends/stv0910: add multistream (ISI) and PLS capabilities Implements stream_id filter and scrambling code setup in start() and also sets FE_CAN_MULTISTREAM in frontend_ops. This enables the driver to properly receive and handle multistream transponders, functionality has been reported working fine by testers with access to such streams, in conjunction with VDR on the userspace side. The code snippet originates from the original vendor's dddvb driver package and has been made working properly with the current in-kernel DVB core API. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 85439d3b725e..dc848ebe1a44 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -119,6 +119,8 @@ struct stv { int is_standard_broadcast; int is_vcm; + u32 cur_scrambling_code; + u32 last_bernumerator; u32 last_berdenominator; u8 berscale; @@ -965,6 +967,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) s32 freq; u8 reg_dmdcfgmd; u16 symb; + u32 scrambling_code = 1; if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) return -EINVAL; @@ -978,6 +981,28 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) init_search_param(state); + if (p->stream_id != NO_STREAM_ID_FILTER) { + /* Backwards compatibility to "crazy" API. + * PRBS X root cannot be 0, so this should always work. + */ + if (p->stream_id & 0xffffff00) + scrambling_code = p->stream_id >> 8; + write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, + p->stream_id & 0xff); + write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, + 0xff); + } + + if (scrambling_code != state->cur_scrambling_code) { + write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff, + scrambling_code & 0xff); + write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff, + (scrambling_code >> 8) & 0xff); + write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff, + (scrambling_code >> 16) & 0x07); + state->cur_scrambling_code = scrambling_code; + } + if (p->symbol_rate <= 1000000) { /* SR <=1Msps */ state->demod_timeout = 3000; state->fec_timeout = 2000; @@ -1597,7 +1622,8 @@ static struct dvb_frontend_ops stv0910_ops = { .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | FE_CAN_QPSK | - FE_CAN_2G_MODULATION + FE_CAN_2G_MODULATION | + FE_CAN_MULTISTREAM }, .sleep = sleep, .release = release, @@ -1655,6 +1681,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->search_range = 16000000; state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ state->receive_mode = RCVMODE_NONE; + state->cur_scrambling_code = (~0U); state->single = cfg->single ? 1 : 0; base = match_base(i2c, cfg->adr); -- cgit v1.2.3 From 19bb3b718f02ff2fa38e3222cf62c9c3f46d2527 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:57 -0400 Subject: media: dvb-frontends/stv0910: Add demod-only signal strength reporting Original code at least has some signed/unsigned issues, resulting in values like 32dBm. Implement signal strength readout to work without asking the attached tuner, and use a lookup table instead of log calc. Values reported appear plausible, gathered from feedback from several testers. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index dc848ebe1a44..dc4d829bb47a 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -135,7 +135,7 @@ struct sinit_table { struct slookup { s16 value; - u16 reg_value; + u32 reg_value; }; static inline int i2c_write(struct i2c_adapter *adap, u8 adr, @@ -327,6 +327,25 @@ struct slookup s2_sn_lookup[] = { { 510, 463 }, /*C/N=51.0dB*/ }; +struct slookup padc_lookup[] = { + { 0, 118000 }, /* PADC=+0dBm */ + { -100, 93600 }, /* PADC=-1dBm */ + { -200, 74500 }, /* PADC=-2dBm */ + { -300, 59100 }, /* PADC=-3dBm */ + { -400, 47000 }, /* PADC=-4dBm */ + { -500, 37300 }, /* PADC=-5dBm */ + { -600, 29650 }, /* PADC=-6dBm */ + { -700, 23520 }, /* PADC=-7dBm */ + { -900, 14850 }, /* PADC=-9dBm */ + { -1100, 9380 }, /* PADC=-11dBm */ + { -1300, 5910 }, /* PADC=-13dBm */ + { -1500, 3730 }, /* PADC=-15dBm */ + { -1700, 2354 }, /* PADC=-17dBm */ + { -1900, 1485 }, /* PADC=-19dBm */ + { -2000, 1179 }, /* PADC=-20dBm */ + { -2100, 1000 }, /* PADC=-21dBm */ +}; + /********************************************************************* * Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame *********************************************************************/ @@ -567,7 +586,7 @@ static int tracking_optimization(struct stv *state) } static s32 table_lookup(struct slookup *table, - int table_size, u16 reg_value) + int table_size, u32 reg_value) { s32 value; int imin = 0; @@ -1300,11 +1319,32 @@ static int read_ber(struct dvb_frontend *fe) static void read_signal_strength(struct dvb_frontend *fe) { - /* FIXME: add signal strength algo */ struct stv *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; + s64 strength; + u8 reg[2]; + u16 agc; + s32 padc, power = 0; + int i; - p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, reg, 2); + + agc = (((u32) reg[0]) << 8) | reg[1]; + + for (i = 0; i < 5; i += 1) { + read_regs(state, RSTV0910_P2_POWERI + state->regoff, reg, 2); + power += (u32) reg[0] * (u32) reg[0] + + (u32) reg[1] * (u32) reg[1]; + usleep_range(3000, 4000); + } + power /= 5; + + padc = table_lookup(padc_lookup, ARRAY_SIZE(padc_lookup), power) + 352; + + strength = (padc - agc); + + p->strength.stat[0].scale = FE_SCALE_DECIBEL; + p->strength.stat[0].uvalue = strength; } static int read_status(struct dvb_frontend *fe, enum fe_status *status) -- cgit v1.2.3 From 2f4675c00375864007968236b8f1fa6b636a809a Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:58 -0400 Subject: media: dvb-frontends/stv0910: Add missing set_frontend fe-op This was missing from the frontend_ops. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index dc4d829bb47a..7e8a460449c5 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1668,6 +1668,7 @@ static struct dvb_frontend_ops stv0910_ops = { .sleep = sleep, .release = release, .i2c_gate_ctrl = gate_ctrl, + .set_frontend = set_parameters, .get_frontend_algo = get_algo, .get_frontend = get_frontend, .tune = tune, -- cgit v1.2.3 From 44173fda45ba25af84ae5c3e9b745bb286163730 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:20:59 -0400 Subject: media: dvb-frontends: add ST STV6111 DVB-S/S2 tuner frontend driver This adds a frontend driver for the ST STV6111 DVB-S/S2 tuners. Like the stv0910 demod frontend driver, this driver originates from the Digital Devices' dddvb vendor driver package as of version 0.9.29, and was cleaned up aswell. No functionality had to be removed though. Any camel case has been converted to kernel_case, fixup patch has been proposed upstream. Permission to reuse and mainline the driver code was formally granted by Ralph Metzler . Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 9 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/stv6111.c | 674 ++++++++++++++++++++++++++++++++++ drivers/media/dvb-frontends/stv6111.h | 20 + 4 files changed, 704 insertions(+) create mode 100644 drivers/media/dvb-frontends/stv6111.c create mode 100644 drivers/media/dvb-frontends/stv6111.h (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 773de5e264e3..d2d3160abdf7 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -44,6 +44,15 @@ config DVB_STV6110x help A Silicon tuner that supports DVB-S and DVB-S2 modes +config DVB_STV6111 + tristate "STV6111 based tuners" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + A Silicon tuner that supports DVB-S and DVB-S2 modes + + Say Y when you want to support these frontends. + config DVB_M88DS3103 tristate "Montage Technology M88DS3103" depends on DVB_CORE && I2C && I2C_MUX diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index c302b2d07499..e8bf1d873485 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -111,6 +111,7 @@ obj-$(CONFIG_DVB_CXD2841ER) += cxd2841er.o obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_STV0910) += stv0910.o +obj-$(CONFIG_DVB_STV6111) += stv6111.o obj-$(CONFIG_DVB_SI2165) += si2165.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_SP2) += sp2.o diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c new file mode 100644 index 000000000000..ce5b5ff936d5 --- /dev/null +++ b/drivers/media/dvb-frontends/stv6111.c @@ -0,0 +1,674 @@ +/* + * Driver for the ST STV6111 tuner + * + * Copyright (C) 2014 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stv6111.h" + +#include "dvb_frontend.h" + +struct stv { + struct i2c_adapter *i2c; + u8 adr; + + u8 reg[11]; + u32 ref_freq; + u32 frequency; +}; + +struct slookup { + s16 value; + u16 reg_value; +}; + +static struct slookup lnagain_nf_lookup[] = { + /*Gain *100dB*/ /*Reg*/ + { 2572, 0 }, + { 2575, 1 }, + { 2580, 2 }, + { 2588, 3 }, + { 2596, 4 }, + { 2611, 5 }, + { 2633, 6 }, + { 2664, 7 }, + { 2701, 8 }, + { 2753, 9 }, + { 2816, 10 }, + { 2902, 11 }, + { 2995, 12 }, + { 3104, 13 }, + { 3215, 14 }, + { 3337, 15 }, + { 3492, 16 }, + { 3614, 17 }, + { 3731, 18 }, + { 3861, 19 }, + { 3988, 20 }, + { 4124, 21 }, + { 4253, 22 }, + { 4386, 23 }, + { 4505, 24 }, + { 4623, 25 }, + { 4726, 26 }, + { 4821, 27 }, + { 4903, 28 }, + { 4979, 29 }, + { 5045, 30 }, + { 5102, 31 } +}; + +static struct slookup lnagain_iip3_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 1548, 0 }, + { 1552, 1 }, + { 1569, 2 }, + { 1565, 3 }, + { 1577, 4 }, + { 1594, 5 }, + { 1627, 6 }, + { 1656, 7 }, + { 1700, 8 }, + { 1748, 9 }, + { 1805, 10 }, + { 1896, 11 }, + { 1995, 12 }, + { 2113, 13 }, + { 2233, 14 }, + { 2366, 15 }, + { 2543, 16 }, + { 2687, 17 }, + { 2842, 18 }, + { 2999, 19 }, + { 3167, 20 }, + { 3342, 21 }, + { 3507, 22 }, + { 3679, 23 }, + { 3827, 24 }, + { 3970, 25 }, + { 4094, 26 }, + { 4210, 27 }, + { 4308, 28 }, + { 4396, 29 }, + { 4468, 30 }, + { 4535, 31 } +}; + +static struct slookup gain_rfagc_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 4870, 0x3000 }, + { 4850, 0x3C00 }, + { 4800, 0x4500 }, + { 4750, 0x4800 }, + { 4700, 0x4B00 }, + { 4650, 0x4D00 }, + { 4600, 0x4F00 }, + { 4550, 0x5100 }, + { 4500, 0x5200 }, + { 4420, 0x5500 }, + { 4316, 0x5800 }, + { 4200, 0x5B00 }, + { 4119, 0x5D00 }, + { 3999, 0x6000 }, + { 3950, 0x6100 }, + { 3876, 0x6300 }, + { 3755, 0x6600 }, + { 3641, 0x6900 }, + { 3567, 0x6B00 }, + { 3425, 0x6F00 }, + { 3350, 0x7100 }, + { 3236, 0x7400 }, + { 3118, 0x7700 }, + { 3004, 0x7A00 }, + { 2917, 0x7C00 }, + { 2776, 0x7F00 }, + { 2635, 0x8200 }, + { 2516, 0x8500 }, + { 2406, 0x8800 }, + { 2290, 0x8B00 }, + { 2170, 0x8E00 }, + { 2073, 0x9100 }, + { 1949, 0x9400 }, + { 1836, 0x9700 }, + { 1712, 0x9A00 }, + { 1631, 0x9C00 }, + { 1515, 0x9F00 }, + { 1400, 0xA200 }, + { 1323, 0xA400 }, + { 1203, 0xA700 }, + { 1091, 0xAA00 }, + { 1011, 0xAC00 }, + { 904, 0xAF00 }, + { 787, 0xB200 }, + { 685, 0xB500 }, + { 571, 0xB800 }, + { 464, 0xBB00 }, + { 374, 0xBE00 }, + { 275, 0xC200 }, + { 181, 0xC600 }, + { 102, 0xCC00 }, + { 49, 0xD900 } +}; + +/* + * This table is 6 dB too low comapred to the others (probably created with + * a different BB_MAG setting) + */ +static struct slookup gain_channel_agc_nf_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 7082, 0x3000 }, + { 7052, 0x4000 }, + { 7007, 0x4600 }, + { 6954, 0x4A00 }, + { 6909, 0x4D00 }, + { 6833, 0x5100 }, + { 6753, 0x5400 }, + { 6659, 0x5700 }, + { 6561, 0x5A00 }, + { 6472, 0x5C00 }, + { 6366, 0x5F00 }, + { 6259, 0x6100 }, + { 6151, 0x6400 }, + { 6026, 0x6700 }, + { 5920, 0x6900 }, + { 5835, 0x6B00 }, + { 5770, 0x6C00 }, + { 5681, 0x6E00 }, + { 5596, 0x7000 }, + { 5503, 0x7200 }, + { 5429, 0x7300 }, + { 5319, 0x7500 }, + { 5220, 0x7700 }, + { 5111, 0x7900 }, + { 4983, 0x7B00 }, + { 4876, 0x7D00 }, + { 4755, 0x7F00 }, + { 4635, 0x8100 }, + { 4499, 0x8300 }, + { 4405, 0x8500 }, + { 4323, 0x8600 }, + { 4233, 0x8800 }, + { 4156, 0x8A00 }, + { 4038, 0x8C00 }, + { 3935, 0x8E00 }, + { 3823, 0x9000 }, + { 3712, 0x9200 }, + { 3601, 0x9500 }, + { 3511, 0x9700 }, + { 3413, 0x9900 }, + { 3309, 0x9B00 }, + { 3213, 0x9D00 }, + { 3088, 0x9F00 }, + { 2992, 0xA100 }, + { 2878, 0xA400 }, + { 2769, 0xA700 }, + { 2645, 0xAA00 }, + { 2538, 0xAD00 }, + { 2441, 0xB000 }, + { 2350, 0xB600 }, + { 2237, 0xBA00 }, + { 2137, 0xBF00 }, + { 2039, 0xC500 }, + { 1938, 0xDF00 }, + { 1927, 0xFF00 } +}; + +static struct slookup gain_channel_agc_iip3_lookup[] = { + /*Gain *100dB*/ /*reg*/ + { 7070, 0x3000 }, + { 7028, 0x4000 }, + { 7019, 0x4600 }, + { 6900, 0x4A00 }, + { 6811, 0x4D00 }, + { 6763, 0x5100 }, + { 6690, 0x5400 }, + { 6644, 0x5700 }, + { 6617, 0x5A00 }, + { 6598, 0x5C00 }, + { 6462, 0x5F00 }, + { 6348, 0x6100 }, + { 6197, 0x6400 }, + { 6154, 0x6700 }, + { 6098, 0x6900 }, + { 5893, 0x6B00 }, + { 5812, 0x6C00 }, + { 5773, 0x6E00 }, + { 5723, 0x7000 }, + { 5661, 0x7200 }, + { 5579, 0x7300 }, + { 5460, 0x7500 }, + { 5308, 0x7700 }, + { 5099, 0x7900 }, + { 4910, 0x7B00 }, + { 4800, 0x7D00 }, + { 4785, 0x7F00 }, + { 4635, 0x8100 }, + { 4466, 0x8300 }, + { 4314, 0x8500 }, + { 4295, 0x8600 }, + { 4144, 0x8800 }, + { 3920, 0x8A00 }, + { 3889, 0x8C00 }, + { 3771, 0x8E00 }, + { 3655, 0x9000 }, + { 3446, 0x9200 }, + { 3298, 0x9500 }, + { 3083, 0x9700 }, + { 3015, 0x9900 }, + { 2833, 0x9B00 }, + { 2746, 0x9D00 }, + { 2632, 0x9F00 }, + { 2598, 0xA100 }, + { 2480, 0xA400 }, + { 2236, 0xA700 }, + { 2171, 0xAA00 }, + { 2060, 0xAD00 }, + { 1999, 0xB000 }, + { 1974, 0xB600 }, + { 1820, 0xBA00 }, + { 1741, 0xBF00 }, + { 1655, 0xC500 }, + { 1444, 0xDF00 }, + { 1325, 0xFF00 }, +}; + +static inline u32 muldiv32(u32 a, u32 b, u32 c) +{ + u64 tmp64; + + tmp64 = (u64)a * (u64)b; + do_div(tmp64, c); + + return (u32) tmp64; +} + +static int i2c_read(struct i2c_adapter *adap, + u8 adr, u8 *msg, int len, u8 *answ, int alen) +{ + struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, + .buf = msg, .len = len}, + { .addr = adr, .flags = I2C_M_RD, + .buf = answ, .len = alen } }; + if (i2c_transfer(adap, msgs, 2) != 2) { + dev_err(&adap->dev, "i2c read error\n"); + return -EIO; + } + return 0; +} + +static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) +{ + struct i2c_msg msg = {.addr = adr, .flags = 0, + .buf = data, .len = len}; + + if (i2c_transfer(adap, &msg, 1) != 1) { + dev_err(&adap->dev, "i2c write error\n"); + return -EIO; + } + return 0; +} + +static int write_regs(struct stv *state, int reg, int len) +{ + u8 d[12]; + + memcpy(&d[1], &state->reg[reg], len); + d[0] = reg; + return i2c_write(state->i2c, state->adr, d, len + 1); +} + +static int write_reg(struct stv *state, u8 reg, u8 val) +{ + u8 d[2] = {reg, val}; + + return i2c_write(state->i2c, state->adr, d, 2); +} + +static int read_reg(struct stv *state, u8 reg, u8 *val) +{ + return i2c_read(state->i2c, state->adr, ®, 1, val, 1); +} + +static int wait_for_call_done(struct stv *state, u8 mask) +{ + int status = 0; + u32 lock_retry_count = 10; + + while (lock_retry_count > 0) { + u8 regval; + + status = read_reg(state, 9, ®val); + if (status < 0) + return status; + + if ((regval & mask) == 0) + break; + usleep_range(4000, 6000); + lock_retry_count -= 1; + + status = -EIO; + } + return status; +} + +static void init_state(struct stv *state) +{ + u32 clkdiv = 0; + u32 agcmode = 0; + u32 agcref = 2; + u32 agcset = 0xffffffff; + u32 bbmode = 0xffffffff; + + state->reg[0] = 0x08; + state->reg[1] = 0x41; + state->reg[2] = 0x8f; + state->reg[3] = 0x00; + state->reg[4] = 0xce; + state->reg[5] = 0x54; + state->reg[6] = 0x55; + state->reg[7] = 0x45; + state->reg[8] = 0x46; + state->reg[9] = 0xbd; + state->reg[10] = 0x11; + + state->ref_freq = 16000; + + if (clkdiv <= 3) + state->reg[0x00] |= (clkdiv & 0x03); + if (agcmode <= 3) { + state->reg[0x03] |= (agcmode << 5); + if (agcmode == 0x01) + state->reg[0x01] |= 0x30; + } + if (bbmode <= 3) + state->reg[0x01] = (state->reg[0x01] & ~0x30) | (bbmode << 4); + if (agcref <= 7) + state->reg[0x03] |= agcref; + if (agcset <= 31) + state->reg[0x02] = (state->reg[0x02] & ~0x1F) | agcset | 0x40; +} + +static int attach_init(struct stv *state) +{ + if (write_regs(state, 0, 11)) + return -ENODEV; + return 0; +} + +static void release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + +static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency) +{ + struct stv *state = fe->tuner_priv; + u32 index = (cutoff_frequency + 999999) / 1000000; + + if (index < 6) + index = 6; + if (index > 50) + index = 50; + if ((state->reg[0x08] & ~0xFC) == ((index-6) << 2)) + return 0; + + state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index-6) << 2); + state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08; + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + write_regs(state, 0x08, 2); + wait_for_call_done(state, 0x08); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + return 0; +} + +static int set_lof(struct stv *state, u32 local_frequency, u32 cutoff_frequency) +{ + u32 index = (cutoff_frequency + 999999) / 1000000; + u32 frequency = (local_frequency + 500) / 1000; + u32 p = 1, psel = 0, fvco, div, frac; + u8 icp, tmp; + + if (index < 6) + index = 6; + if (index > 50) + index = 50; + + if (frequency <= 1300000) { + p = 4; + psel = 1; + } else { + p = 2; + psel = 0; + } + fvco = frequency * p; + div = fvco / state->ref_freq; + frac = fvco % state->ref_freq; + frac = muldiv32(frac, 0x40000, state->ref_freq); + + icp = 0; + if (fvco < 2700000) + icp = 0; + else if (fvco < 2950000) + icp = 1; + else if (fvco < 3300000) + icp = 2; + else if (fvco < 3700000) + icp = 3; + else if (fvco < 4200000) + icp = 5; + else if (fvco < 4800000) + icp = 6; + else + icp = 7; + + state->reg[0x02] |= 0x80; /* LNA IIP3 Mode */ + + state->reg[0x03] = (state->reg[0x03] & ~0x80) | (psel << 7); + state->reg[0x04] = (div & 0xFF); + state->reg[0x05] = (((div >> 8) & 0x01) | ((frac & 0x7F) << 1)) & 0xff; + state->reg[0x06] = ((frac >> 7) & 0xFF); + state->reg[0x07] = (state->reg[0x07] & ~0x07) | ((frac >> 15) & 0x07); + state->reg[0x07] = (state->reg[0x07] & ~0xE0) | (icp << 5); + + state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2); + /* Start cal vco,CF */ + state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x0C; + write_regs(state, 2, 8); + + wait_for_call_done(state, 0x0C); + + usleep_range(10000, 12000); + + read_reg(state, 0x03, &tmp); + if (tmp & 0x10) { + state->reg[0x02] &= ~0x80; /* LNA NF Mode */ + write_regs(state, 2, 1); + } + read_reg(state, 0x08, &tmp); + + state->frequency = frequency; + + return 0; +} + +static int set_params(struct dvb_frontend *fe) +{ + struct stv *state = fe->tuner_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 freq, cutoff; + + if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2) + return -EINVAL; + + freq = p->frequency * 1000; + cutoff = 5000000 + muldiv32(p->symbol_rate, 135, 200); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + set_lof(state, freq, cutoff); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + return 0; +} + +static s32 table_lookup(struct slookup *table, int table_size, u16 reg_value) +{ + s32 gain; + s32 reg_diff; + int imin = 0; + int imax = table_size - 1; + int i; + + /* Assumes Table[0].RegValue < Table[imax].RegValue */ + if (reg_value <= table[0].reg_value) + gain = table[0].value; + else if (reg_value >= table[imax].reg_value) + gain = table[imax].value; + else { + while (imax-imin > 1) { + i = (imax + imin) / 2; + if ((table[imin].reg_value <= reg_value) && + (reg_value <= table[i].reg_value)) + imax = i; + else + imin = i; + } + reg_diff = table[imax].reg_value - table[imin].reg_value; + gain = table[imin].value; + if (reg_diff != 0) + gain += ((s32) (reg_value - table[imin].reg_value) * + (s32)(table[imax].value + - table[imin].value))/(reg_diff); + } + return gain; +} + +static int get_rf_strength(struct dvb_frontend *fe, u16 *st) +{ + struct stv *state = fe->tuner_priv; + u16 rfagc = *st; + s32 gain; + + if ((state->reg[0x03] & 0x60) == 0) { + /* RF Mode, Read AGC ADC */ + u8 reg = 0; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + write_reg(state, 0x02, state->reg[0x02] | 0x20); + read_reg(state, 2, ®); + if (reg & 0x20) + read_reg(state, 2, ®); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if ((state->reg[0x02] & 0x80) == 0) + /* NF */ + gain = table_lookup(lnagain_nf_lookup, + ARRAY_SIZE(lnagain_nf_lookup), reg & 0x1F); + else + /* IIP3 */ + gain = table_lookup(lnagain_iip3_lookup, + ARRAY_SIZE(lnagain_iip3_lookup), reg & 0x1F); + + gain += table_lookup(gain_rfagc_lookup, + ARRAY_SIZE(gain_rfagc_lookup), rfagc); + gain -= 2400; + } else { + /* Channel Mode */ + if ((state->reg[0x02] & 0x80) == 0) { + /* NF */ + gain = table_lookup(gain_channel_agc_nf_lookup, + ARRAY_SIZE(gain_channel_agc_nf_lookup), rfagc); + gain += 600; + } else { + /* IIP3 */ + gain = table_lookup(gain_channel_agc_iip3_lookup, + ARRAY_SIZE(gain_channel_agc_iip3_lookup), + rfagc); + } + } + + if (state->frequency > 0) + /* Tilt correction ( 0.00016 dB/MHz ) */ + gain -= ((((s32)(state->frequency / 1000) - 1550) * 2) / 12); + + /* + (BBGain * 10); */ + gain += (s32)((state->reg[0x01] & 0xC0) >> 6) * 600 - 1300; + + if (gain < 0) + gain = 0; + else if (gain > 10000) + gain = 10000; + + *st = 10000 - gain; + + return 0; +} + +static struct dvb_tuner_ops tuner_ops = { + .info = { + .name = "STV6111", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0 + }, + .set_params = set_params, + .release = release, + .get_rf_strength = get_rf_strength, + .set_bandwidth = set_bandwidth, +}; + +struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr) +{ + struct stv *state; + int stat; + + state = kzalloc(sizeof(struct stv), GFP_KERNEL); + if (!state) + return NULL; + state->adr = adr; + state->i2c = i2c; + memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops)); + init_state(state); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + stat = attach_init(state); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + if (stat < 0) { + kfree(state); + return 0; + } + fe->tuner_priv = state; + return fe; +} +EXPORT_SYMBOL_GPL(stv6111_attach); + +MODULE_DESCRIPTION("STV6111 driver"); +MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/stv6111.h b/drivers/media/dvb-frontends/stv6111.h new file mode 100644 index 000000000000..066dd70c9426 --- /dev/null +++ b/drivers/media/dvb-frontends/stv6111.h @@ -0,0 +1,20 @@ +#ifndef _STV6111_H_ +#define _STV6111_H_ + +#if IS_REACHABLE(CONFIG_DVB_STV6111) + +extern struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr); + +#else + +static inline struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr) +{ + pr_warn("%s: Driver disabled by Kconfig\n", __func__); + return NULL; +} + +#endif /* CONFIG_DVB_STV6111 */ + +#endif /* _STV6111_H_ */ -- cgit v1.2.3 From 76103bac71580090aef05a6dd22d25159da04089 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:21:00 -0400 Subject: media: ddbridge: return stv09xx id in port_has_stv0900_aa() The returned value is required for further evaluation of the exact demodulator chip (stv090x or stv0910). Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index cd1723e79a07..3fbac7bee2d4 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1480,10 +1480,9 @@ static int port_has_stv0900(struct ddb_port *port) return 1; } -static int port_has_stv0900_aa(struct ddb_port *port) +static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) { - u8 val; - if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) + if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) return 0; return 1; } @@ -1530,7 +1529,7 @@ static void ddb_port_probe(struct ddb_port *port) { struct ddb *dev = port->dev; char *modname = "NO MODULE"; - u8 xo2_type, xo2_id, cxd_id; + u8 xo2_type, xo2_id, cxd_id, stv_id; port->class = DDB_PORT_NONE; @@ -1622,7 +1621,7 @@ static void ddb_port_probe(struct ddb_port *port) port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBS_ST; ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); - } else if (port_has_stv0900_aa(port)) { + } else if (port_has_stv0900_aa(port, &stv_id)) { modname = "DUAL DVB-S2"; port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBS_ST_AA; -- cgit v1.2.3 From df3082df7da27b66ea2f2cb2350781fd18c1a220 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:21:01 -0400 Subject: media: ddbridge: support for CineS2 V7(A) and DuoFlex S2 V4 hardware This adds all required glue code to support - in conjunction with the new stv0910 and stv6111 demod/tuner drivers and additionally the lnbh25 LNB controller driver - all current DVB-S/S2 hardware (bridges and flex modules) from Digital Devices like the DD CineS2 V7 and V7A, current S2 V4 DuoFlex modules, and probably all upcoming devices based on this STV0910/STV6111/LNBH25 hardware stack. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/Kconfig | 4 + drivers/media/pci/ddbridge/ddbridge-core.c | 135 ++++++++++++++++++++++++++++- drivers/media/pci/ddbridge/ddbridge.h | 2 + 3 files changed, 138 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index ffed78c2ffb4..c79a58fa5fc3 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -8,6 +8,9 @@ config DVB_DDBRIDGE select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT + select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for cards with the Digital Devices PCI express bridge: @@ -20,5 +23,6 @@ config DVB_DDBRIDGE - CineCTv6 and DuoFlex CT (STV0367-based) - CineCTv7 and DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based) - MaxA8 series + - CineS2 V7/V7A and DuoFlex S2 V4 (ST STV0910-based) Say Y if you own such a card and want to use it. diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 3fbac7bee2d4..b3fc6a875279 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -45,6 +45,9 @@ #include "stv0367_priv.h" #include "cxd2841er.h" #include "tda18212.h" +#include "stv0910.h" +#include "stv6111.h" +#include "lnbh25.h" static int xo2_speed = 2; module_param(xo2_speed, int, 0444); @@ -920,6 +923,71 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) return 0; } +static struct stv0910_cfg stv0910_p = { + .adr = 0x68, + .parallel = 1, + .rptlvl = 4, + .clk = 30000000, +}; + +static struct lnbh25_config lnbh25_cfg = { + .i2c_address = 0x0c << 1, + .data2_config = LNBH25_TEN +}; + +static int demod_attach_stv0910(struct ddb_input *input, int type) +{ + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct device *dev = &input->port->dev->pdev->dev; + struct stv0910_cfg cfg = stv0910_p; + struct lnbh25_config lnbcfg = lnbh25_cfg; + + if (type) + cfg.parallel = 2; + input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); + if (!input->fe) { + cfg.adr = 0x6c; + input->fe = dvb_attach(stv0910_attach, i2c, + &cfg, (input->nr & 1)); + } + if (!input->fe) { + dev_err(dev, "No STV0910 found!\n"); + return -ENODEV; + } + + /* attach lnbh25 - leftshift by one as the lnbh25 driver expects 8bit + * i2c addresses + */ + lnbcfg.i2c_address = (((input->nr & 1) ? 0x0d : 0x0c) << 1); + if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1); + if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + dev_err(dev, "No LNBH25 found!\n"); + return -ENODEV; + } + } + + return 0; +} + +static int tuner_attach_stv6111(struct ddb_input *input, int type) +{ + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct device *dev = &input->port->dev->pdev->dev; + struct dvb_frontend *fe; + u8 adr = (type ? 0 : 4) + ((input->nr & 1) ? 0x63 : 0x60); + + fe = dvb_attach(stv6111_attach, input->fe, i2c, adr); + if (!fe) { + fe = dvb_attach(stv6111_attach, input->fe, i2c, adr & ~4); + if (!fe) { + dev_err(dev, "No STV6111 found at 0x%02x!\n", adr); + return -ENODEV; + } + } + return 0; +} + static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, int (*start_feed)(struct dvb_demux_feed *), int (*stop_feed)(struct dvb_demux_feed *), @@ -1086,6 +1154,36 @@ static int dvb_input_attach(struct ddb_input *input) return -ENODEV; } break; + case DDB_TUNER_XO2_DVBS_STV0910: + if (demod_attach_stv0910(input, 0) < 0) + return -ENODEV; + if (tuner_attach_stv6111(input, 0) < 0) + return -ENODEV; + if (input->fe) { + if (dvb_register_frontend(adap, input->fe) < 0) + return -ENODEV; + } + break; + case DDB_TUNER_DVBS_STV0910_PR: + if (demod_attach_stv0910(input, 1) < 0) + return -ENODEV; + if (tuner_attach_stv6111(input, 1) < 0) + return -ENODEV; + if (input->fe) { + if (dvb_register_frontend(adap, input->fe) < 0) + return -ENODEV; + } + break; + case DDB_TUNER_DVBS_STV0910_P: + if (demod_attach_stv0910(input, 0) < 0) + return -ENODEV; + if (tuner_attach_stv6111(input, 1) < 0) + return -ENODEV; + if (input->fe) { + if (dvb_register_frontend(adap, input->fe) < 0) + return -ENODEV; + } + break; case DDB_TUNER_DVBCT_TR: if (demod_attach_drxk(input) < 0) return -ENODEV; @@ -1548,8 +1646,8 @@ static void ddb_port_probe(struct ddb_port *port) init_xo2(port); switch (xo2_id >> 2) { case 0: - modname = "DUAL DVB-S2 (unsupported)"; - port->class = DDB_PORT_NONE; + modname = "DUAL DVB-S2"; + port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_XO2_DVBS_STV0910; break; case 1: @@ -1624,7 +1722,18 @@ static void ddb_port_probe(struct ddb_port *port) } else if (port_has_stv0900_aa(port, &stv_id)) { modname = "DUAL DVB-S2"; port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_DVBS_ST_AA; + switch (stv_id) { + case 0x51: + if (dev->info->ts_quirks & TS_QUIRK_REVERSED && + port->nr == 0) + port->type = DDB_TUNER_DVBS_STV0910_PR; + else + port->type = DDB_TUNER_DVBS_STV0910_P; + break; + default: + port->type = DDB_TUNER_DVBS_ST_AA; + break; + } ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); } else if (port_has_drxks(port)) { modname = "DUAL DVB-C/T"; @@ -2140,6 +2249,24 @@ static const struct ddb_info ddb_v6_5 = { .port_num = 4, }; +static const struct ddb_info ddb_v7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 DVB adapter", + .port_num = 4, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + +static const struct ddb_info ddb_v7a = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", + .port_num = 4, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + static const struct ddb_info ddb_dvbct = { .type = DDB_OCTOPUS, .name = "Digital Devices DVBCT V6.1 DVB adapter", @@ -2232,6 +2359,8 @@ static const struct pci_device_id ddb_id_tbl[] = { DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), + DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a), DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 4a0e3283d646..4783a17175a8 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -160,6 +160,8 @@ struct ddb_port { #define DDB_TUNER_DVBCT2_SONY_P 7 #define DDB_TUNER_DVBC2T2_SONY_P 8 #define DDB_TUNER_ISDBT_SONY_P 9 +#define DDB_TUNER_DVBS_STV0910_P 10 +#define DDB_TUNER_DVBS_STV0910_PR 14 #define DDB_TUNER_DVBC2T2I_SONY_P 15 #define DDB_TUNER_DVBCT_TR 16 #define DDB_TUNER_DVBCT_ST 17 -- cgit v1.2.3 From 7914505949a2c897b595f1a734106c8895151d66 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 3 Jul 2017 13:21:02 -0400 Subject: media: ddbridge: stv0910 single demod mode module option Adds a stv0910_single modparm which, when set, configures the stv0910 to run in single demodulator mode, currently intended for high bit rate testing. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index b3fc6a875279..e762396730db 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -53,6 +53,10 @@ static int xo2_speed = 2; module_param(xo2_speed, int, 0444); MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); +static int stv0910_single; +module_param(stv0910_single, int, 0444); +MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /* MSI had problems with lost interrupts, fixed but needs testing */ @@ -942,6 +946,9 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) struct stv0910_cfg cfg = stv0910_p; struct lnbh25_config lnbcfg = lnbh25_cfg; + if (stv0910_single) + cfg.single = 1; + if (type) cfg.parallel = 2; input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); -- cgit v1.2.3 From 3658ea39f910ecd469eb0f4966422e85080ef4fc Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 9 Jul 2017 12:36:45 -0400 Subject: media: dvb-frontends/stv0367: DDB frontend status inquiry fixup Return 0 instead of -EINVAL in get_frontend if no demod mode is active. This fixes ie. dvb-fe-tool getting confused and assuming a DVBv3 FE on idle frontends when the FE has been put to sleep using sleep(). Also, in read_status(), don't immediately return when no demod is active, so the remaining code has a chance to clear the signal statistics. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0367.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index 8ac0f598978d..59c1aad256c2 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -3090,7 +3090,7 @@ static int stv0367ddb_read_status(struct dvb_frontend *fe, { struct stv0367_state *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &fe->dtv_property_cache; - int ret; + int ret = 0; switch (state->activedemod) { case demod_ter: @@ -3100,7 +3100,7 @@ static int stv0367ddb_read_status(struct dvb_frontend *fe, ret = stv0367cab_read_status(fe, status); break; default: - return 0; + break; } /* stop and report on *_read_status failure */ @@ -3138,7 +3138,7 @@ static int stv0367ddb_get_frontend(struct dvb_frontend *fe, break; } - return -EINVAL; + return 0; } static int stv0367ddb_sleep(struct dvb_frontend *fe) -- cgit v1.2.3 From 8d08a4c1aae8857c46079d329023753611218518 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 17:41:08 -0400 Subject: media: dvb-ttusb-budget: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index 361e40b56045..22a488d3749d 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -1640,7 +1640,7 @@ static void frontend_init(struct ttusb* ttusb) -static struct i2c_algorithm ttusb_dec_algo = { +static const struct i2c_algorithm ttusb_dec_algo = { .master_xfer = master_xfer, .functionality = functionality, }; -- cgit v1.2.3 From 830a45a2f44852fb7e1b49f95c7c5703816d9d94 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 18:04:24 -0400 Subject: media: usbvision: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c index 38749331e7df..68acafb6bb95 100644 --- a/drivers/media/usb/usbvision/usbvision-i2c.c +++ b/drivers/media/usb/usbvision/usbvision-i2c.c @@ -163,7 +163,7 @@ static u32 functionality(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ -static struct i2c_algorithm usbvision_algo = { +static const struct i2c_algorithm usbvision_algo = { .master_xfer = usbvision_i2c_xfer, .smbus_xfer = NULL, .functionality = functionality, -- cgit v1.2.3 From 19779f40520104423ec34581623f032affa08579 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 18:24:19 -0400 Subject: media: dib9000: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib9000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index c95fff4f9582..17c6f15c7e68 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -1714,12 +1714,12 @@ static u32 dib9000_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm dib9000_tuner_algo = { +static const struct i2c_algorithm dib9000_tuner_algo = { .master_xfer = dib9000_tuner_xfer, .functionality = dib9000_i2c_func, }; -static struct i2c_algorithm dib9000_component_bus_algo = { +static const struct i2c_algorithm dib9000_component_bus_algo = { .master_xfer = dib9000_fw_component_bus_xfer, .functionality = dib9000_i2c_func, }; -- cgit v1.2.3 From ea925e4db10467fd9dceaac66817c8582c1f2c66 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 18:09:16 -0400 Subject: media: saa7146: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146/saa7146_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/saa7146/saa7146_i2c.c b/drivers/media/common/saa7146/saa7146_i2c.c index 239a2db35068..75897f95e4b4 100644 --- a/drivers/media/common/saa7146/saa7146_i2c.c +++ b/drivers/media/common/saa7146/saa7146_i2c.c @@ -395,7 +395,7 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in /* i2c-adapter helper functions */ /* exported algorithm data */ -static struct i2c_algorithm saa7146_algo = { +static const struct i2c_algorithm saa7146_algo = { .master_xfer = saa7146_i2c_xfer, .functionality = saa7146_i2c_func, }; -- cgit v1.2.3 From 8e10fd851cb3e9723786703e3db45a2320b33a0e Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 18:14:38 -0400 Subject: media: marvell-ccic: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/cafe-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index 77890bd0deab..063fd43f8539 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -326,7 +326,7 @@ static u32 cafe_smbus_func(struct i2c_adapter *adapter) I2C_FUNC_SMBUS_WRITE_BYTE_DATA; } -static struct i2c_algorithm cafe_smbus_algo = { +static const struct i2c_algorithm cafe_smbus_algo = { .smbus_xfer = cafe_smbus_xfer, .functionality = cafe_smbus_func }; -- cgit v1.2.3 From a76f094a47aca13ea1666297f138c2e66c605d5b Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 18:18:15 -0400 Subject: media: dib7000p: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib7000p.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 1caa04d8f60f..0fbaabe43682 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2388,7 +2388,7 @@ static u32 dib7000p_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm dib7090_tuner_xfer_algo = { +static const struct i2c_algorithm dib7090_tuner_xfer_algo = { .master_xfer = dib7090_tuner_xfer, .functionality = dib7000p_i2c_func, }; -- cgit v1.2.3 From 053aa4a8339c4f271f9f667e637b8c7f015cb95b Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 20:57:06 -0400 Subject: media: s5h1420: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/s5h1420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index cba9bff05b12..fd427a29c001 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -864,7 +864,7 @@ static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c return i2c_transfer(state->i2c, m, 1 + num) == 1 + num ? num : -EIO; } -static struct i2c_algorithm s5h1420_tuner_i2c_algo = { +static const struct i2c_algorithm s5h1420_tuner_i2c_algo = { .master_xfer = s5h1420_tuner_i2c_tuner_xfer, .functionality = s5h1420_tuner_i2c_func, }; -- cgit v1.2.3 From 28e83542cd8cac67ebea9b29a3b18941739aa178 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:00:33 -0400 Subject: media: dib8000: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib8000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index e501ec964df1..a179a3f6563d 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -1880,7 +1880,7 @@ static u32 dib8096p_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm dib8096p_tuner_xfer_algo = { +static const struct i2c_algorithm dib8096p_tuner_xfer_algo = { .master_xfer = dib8096p_tuner_xfer, .functionality = dib8096p_i2c_func, }; -- cgit v1.2.3 From c51df136e5d12dc50954ed454f90b5df718f299d Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:03:52 -0400 Subject: media: zd1301_demod: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/zd1301_demod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/zd1301_demod.c b/drivers/media/dvb-frontends/zd1301_demod.c index fcf5f69de0c5..84a2b25a574a 100644 --- a/drivers/media/dvb-frontends/zd1301_demod.c +++ b/drivers/media/dvb-frontends/zd1301_demod.c @@ -445,7 +445,7 @@ static u32 zd1301_demod_i2c_functionality(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm zd1301_demod_i2c_algorithm = { +static const struct i2c_algorithm zd1301_demod_i2c_algorithm = { .master_xfer = zd1301_demod_i2c_master_xfer, .functionality = zd1301_demod_i2c_functionality, }; -- cgit v1.2.3 From 6ac8b81ec996228e41a8bb1f14450adf8b697913 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:06:51 -0400 Subject: media: cx24123: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24123.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index 4ae3d922a8e8..1d59d1d3bd82 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -1032,7 +1032,7 @@ static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_I2C; } -static struct i2c_algorithm cx24123_tuner_i2c_algo = { +static const struct i2c_algorithm cx24123_tuner_i2c_algo = { .master_xfer = cx24123_tuner_i2c_tuner_xfer, .functionality = cx24123_tuner_i2c_func, }; -- cgit v1.2.3 From 618e8aac3d7ccbf49b170181a6f3a418ba6e5419 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:15:36 -0400 Subject: media: ddbridge: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index e762396730db..ec41804d78c7 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -207,7 +207,7 @@ static u32 ddb_i2c_functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm ddb_i2c_algo = { +static const struct i2c_algorithm ddb_i2c_algo = { .master_xfer = ddb_i2c_master_xfer, .functionality = ddb_i2c_functionality, }; -- cgit v1.2.3 From 3c13978ead17b7421b0d6dc76d2db9dc12fc1844 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:19:36 -0400 Subject: media: dm1105: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/dm1105/dm1105.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 1d41934cfaf5..36e94f81aba5 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -571,7 +571,7 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_I2C; } -static struct i2c_algorithm dm1105_algo = { +static const struct i2c_algorithm dm1105_algo = { .master_xfer = dm1105_i2c_xfer, .functionality = functionality, }; -- cgit v1.2.3 From e46ab9dc4a2bffad9f49123136b22f6eec88a82c Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:10:00 -0400 Subject: media: mantis: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/mantis_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c index d72ee47dc6e4..496c10dfc4df 100644 --- a/drivers/media/pci/mantis/mantis_i2c.c +++ b/drivers/media/pci/mantis/mantis_i2c.c @@ -212,7 +212,7 @@ static u32 mantis_i2c_func(struct i2c_adapter *adapter) return I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm mantis_algo = { +static const struct i2c_algorithm mantis_algo = { .master_xfer = mantis_i2c_xfer, .functionality = mantis_i2c_func, }; -- cgit v1.2.3 From 62055056da6a722ab770d45bad63ed41dfb4f283 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sun, 9 Jul 2017 21:12:37 -0400 Subject: media: ngene: constify i2c_algorithm structure Check for i2c_algorithm structures that are only stored in the algo field of an i2c_adapter structure. This field is declared const, so i2c_algorithm structures that have this property can be declared as const also. This issue was identified using Coccinelle and the following semantic patch: @r disable optional_qualifier@ identifier i; position p; @@ static struct i2c_algorithm i@p = { ... }; @ok@ identifier r.i; struct i2c_adapter e; position p; @@ e.algo = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; @@ i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct i2c_algorithm i = { ... }; Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ngene/ngene-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c index fbf36353c701..3004947f300b 100644 --- a/drivers/media/pci/ngene/ngene-i2c.c +++ b/drivers/media/pci/ngene/ngene-i2c.c @@ -150,7 +150,7 @@ static u32 ngene_i2c_functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm ngene_i2c_algo = { +static const struct i2c_algorithm ngene_i2c_algo = { .master_xfer = ngene_i2c_master_xfer, .functionality = ngene_i2c_functionality, }; -- cgit v1.2.3 From d0a0548adeee87ac2d7890d15dfd3800db2099e6 Mon Sep 17 00:00:00 2001 From: Akihiro Tsukada Date: Mon, 10 Jul 2017 04:40:13 -0400 Subject: media: media/dvb: earth-pt3: fix hang-up in a rare case When a user starts and stops filtering at a demux device too quickly in a very short interval, the user process hangs in uninterruptible sleep, due to an inconsistency of kthread status in the driver. The kthread can be stopped before it starts running its thread function, but the invocation status was partly managed in the kthread function, which resulted in a double kthread_stop() of one kthread. Signed-off-by: Akihiro Tsukada Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pt3/pt3.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c index e8b5d0992157..34044a45fecc 100644 --- a/drivers/media/pci/pt3/pt3.c +++ b/drivers/media/pci/pt3/pt3.c @@ -472,7 +472,6 @@ static int pt3_fetch_thread(void *data) } dev_dbg(adap->dvb_adap.device, "PT3: [%s] exited\n", adap->thread->comm); - adap->thread = NULL; return 0; } @@ -486,6 +485,7 @@ static int pt3_start_streaming(struct pt3_adapter *adap) if (IS_ERR(thread)) { int ret = PTR_ERR(thread); + adap->thread = NULL; dev_warn(adap->dvb_adap.device, "PT3 (adap:%d, dmx:%d): failed to start kthread\n", adap->dvb_adap.num, adap->dmxdev.dvbdev->id); @@ -508,6 +508,7 @@ static int pt3_stop_streaming(struct pt3_adapter *adap) /* kill the fetching thread */ ret = kthread_stop(adap->thread); + adap->thread = NULL; return ret; } @@ -520,14 +521,8 @@ static int pt3_start_feed(struct dvb_demux_feed *feed) adap = container_of(feed->demux, struct pt3_adapter, demux); adap->num_feeds++; - if (adap->thread) + if (adap->num_feeds > 1) return 0; - if (adap->num_feeds != 1) { - dev_warn(adap->dvb_adap.device, - "%s: unmatched start/stop_feed in adap:%i/dmx:%i\n", - __func__, adap->dvb_adap.num, adap->dmxdev.dvbdev->id); - adap->num_feeds = 1; - } return pt3_start_streaming(adap); -- cgit v1.2.3 From 3802c1bc2c127e9396d95a274a6bd6fcb5c9a397 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Jul 2017 09:54:27 -0400 Subject: media: dvb-frontends/cxd2841er: make several arrays static Don't populate arrays on the stack but make them static. Makes the object code smaller: Before: text data bss dec hex filename 89299 21704 64 111067 1b1db cxd2841er.o After: text data bss dec hex filename 85823 23432 64 109319 1ab07 cxd2841er.o Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cxd2841er.c | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index 12bff778c97f..c5e1b4dd0765 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -2178,42 +2178,42 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, u32 iffreq, ifhz; u8 data[MAX_WRITE_REGSIZE]; - const uint8_t nominalRate8bw[3][5] = { + static const uint8_t nominalRate8bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - const uint8_t nominalRate7bw[3][5] = { + static const uint8_t nominalRate7bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - const uint8_t nominalRate6bw[3][5] = { + static const uint8_t nominalRate6bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ }; - const uint8_t nominalRate5bw[3][5] = { + static const uint8_t nominalRate5bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ }; - const uint8_t nominalRate17bw[3][5] = { + static const uint8_t nominalRate17bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x58, 0xE2, 0xAF, 0xE0, 0xBC}, /* 20.5MHz XTal */ {0x68, 0x0F, 0xA2, 0x32, 0xD0}, /* 24MHz XTal */ {0x58, 0xE2, 0xAF, 0xE0, 0xBC} /* 41MHz XTal */ }; - const uint8_t itbCoef8bw[3][14] = { + static const uint8_t itbCoef8bw[3][14] = { {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, @@ -2222,7 +2222,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ }; - const uint8_t itbCoef7bw[3][14] = { + static const uint8_t itbCoef7bw[3][14] = { {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, @@ -2231,7 +2231,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ }; - const uint8_t itbCoef6bw[3][14] = { + static const uint8_t itbCoef6bw[3][14] = { {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, @@ -2240,7 +2240,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ }; - const uint8_t itbCoef5bw[3][14] = { + static const uint8_t itbCoef5bw[3][14] = { {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, @@ -2249,7 +2249,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ }; - const uint8_t itbCoef17bw[3][14] = { + static const uint8_t itbCoef17bw[3][14] = { {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B, 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99}, /* 20.5MHz XTal */ {0x33, 0x8E, 0x2B, 0x97, 0x2D, 0x95, 0x37, 0x8B, @@ -2423,32 +2423,32 @@ static int cxd2841er_sleep_tc_to_active_t_band( { u8 data[MAX_WRITE_REGSIZE]; u32 iffreq, ifhz; - u8 nominalRate8bw[3][5] = { + static const u8 nominalRate8bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - u8 nominalRate7bw[3][5] = { + static const u8 nominalRate7bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - u8 nominalRate6bw[3][5] = { + static const u8 nominalRate6bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ }; - u8 nominalRate5bw[3][5] = { + static const u8 nominalRate5bw[3][5] = { /* TRCG Nominal Rate [37:0] */ {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ }; - u8 itbCoef8bw[3][14] = { + static const u8 itbCoef8bw[3][14] = { {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5, @@ -2456,7 +2456,7 @@ static int cxd2841er_sleep_tc_to_active_t_band( {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ }; - u8 itbCoef7bw[3][14] = { + static const u8 itbCoef7bw[3][14] = { {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2, @@ -2464,7 +2464,7 @@ static int cxd2841er_sleep_tc_to_active_t_band( {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ }; - u8 itbCoef6bw[3][14] = { + static const u8 itbCoef6bw[3][14] = { {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, @@ -2472,7 +2472,7 @@ static int cxd2841er_sleep_tc_to_active_t_band( {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ }; - u8 itbCoef5bw[3][14] = { + static const u8 itbCoef5bw[3][14] = { {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, @@ -2652,39 +2652,39 @@ static int cxd2841er_sleep_tc_to_active_i_band( u8 data[3]; /* TRCG Nominal Rate */ - u8 nominalRate8bw[3][5] = { + static const u8 nominalRate8bw[3][5] = { {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x11, 0xB8, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - u8 nominalRate7bw[3][5] = { + static const u8 nominalRate7bw[3][5] = { {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x14, 0x40, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - u8 nominalRate6bw[3][5] = { + static const u8 nominalRate6bw[3][5] = { {0x14, 0x2E, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ {0x17, 0xA0, 0x00, 0x00, 0x00}, /* 24MHz XTal */ {0x14, 0x2E, 0x00, 0x00, 0x00} /* 41MHz XTal */ }; - u8 itbCoef8bw[3][14] = { + static const u8 itbCoef8bw[3][14] = { {0x00}, /* 20.5MHz XTal */ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz Xtal */ {0x0}, /* 41MHz XTal */ }; - u8 itbCoef7bw[3][14] = { + static const u8 itbCoef7bw[3][14] = { {0x00}, /* 20.5MHz XTal */ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz Xtal */ {0x00}, /* 41MHz XTal */ }; - u8 itbCoef6bw[3][14] = { + static const u8 itbCoef6bw[3][14] = { {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, -- cgit v1.2.3 From d4a06464c20540a2c266a371b1602d300b99f11e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 11 Jul 2017 13:20:02 -0400 Subject: media: staging: fbtft: make const array gamma_par_mask static Don't populate array gamma_par_mask on the stack but instead make it static. Makes the object code smaller by 148 bytes: Before: text data bss dec hex filename 2993 1104 0 4097 1001 drivers/staging/fbtft/fb_st7789v.o After: text data bss dec hex filename 2757 1192 0 3949 f6d drivers/staging/fbtft/fb_st7789v.o Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/xirlink_cit.c | 2 +- drivers/staging/fbtft/fb_st7789v.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c index b600ea6460d3..68656e7986c7 100644 --- a/drivers/media/usb/gspca/xirlink_cit.c +++ b/drivers/media/usb/gspca/xirlink_cit.c @@ -1315,7 +1315,7 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val) break; case CIT_MODEL1: { int i; - const unsigned short sa[] = { + static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a }; for (i = 0; i < cit_model1_ntries; i++) diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index 8935a97ec048..a5d7c87557f8 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -189,7 +189,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves) * The masks are the same for both positive and negative voltage * gamma curves. */ - const u8 gamma_par_mask[] = { + static const u8 gamma_par_mask[] = { 0xFF, /* V63[3:0], V0[3:0]*/ 0x3F, /* V1[5:0] */ 0x3F, /* V2[5:0] */ -- cgit v1.2.3 From bd2355b8efc684e3ab74f8a5284d1dfaa9384056 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Tue, 11 Jul 2017 17:06:05 -0400 Subject: media: dvb-frontends/cxd2841er: do sleep on delivery system change Discovered using w_scan when scanning DVB-T/T2: When w_scan goes from -T to -T2, it does so without stopping the frontend using .sleep. Due to this, the demod operation mode isn't re-setup, but as it still is in STATE_ACTIVE_TC, PLP and T2 Profile are set up, but only retune_active() is called, leaving the demod in T mode, thus not operable on any T2 frequency. Fix this by putting the demod to sleep if priv->system isn't equal to p->delsys. To properly accomplish this, sleep_tc() is split into sleep_tc() and shutdown_tc(), where sleep_tc() will only perform the sleep operation, while shutdown_tc() additionally performs the full demod shutdown (to keep the behaviour when the .sleep FE_OP is called). Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cxd2841er.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index c5e1b4dd0765..0ab1fc845927 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -487,6 +487,8 @@ static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv); static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv); +static int cxd2841er_sleep_tc(struct dvb_frontend *fe); + static int cxd2841er_retune_active(struct cxd2841er_priv *priv, struct dtv_frontend_properties *p) { @@ -3378,6 +3380,14 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe) if (priv->flags & CXD2841ER_EARLY_TUNE) cxd2841er_tuner_set(fe); + /* deconfigure/put demod to sleep on delsys switch if active */ + if (priv->state == STATE_ACTIVE_TC && + priv->system != p->delivery_system) { + dev_dbg(&priv->i2c->dev, "%s(): old_delsys=%d, new_delsys=%d -> sleep\n", + __func__, priv->system, p->delivery_system); + cxd2841er_sleep_tc(fe); + } + if (p->delivery_system == SYS_DVBT) { priv->system = SYS_DVBT; switch (priv->state) { @@ -3594,6 +3604,7 @@ static int cxd2841er_sleep_tc(struct dvb_frontend *fe) struct cxd2841er_priv *priv = fe->demodulator_priv; dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + if (priv->state == STATE_ACTIVE_TC) { switch (priv->system) { case SYS_DVBT: @@ -3619,7 +3630,17 @@ static int cxd2841er_sleep_tc(struct dvb_frontend *fe) __func__, priv->state); return -EINVAL; } - cxd2841er_sleep_tc_to_shutdown(priv); + return 0; +} + +static int cxd2841er_shutdown_tc(struct dvb_frontend *fe) +{ + struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + + if (!cxd2841er_sleep_tc(fe)) + cxd2841er_sleep_tc_to_shutdown(priv); return 0; } @@ -3968,7 +3989,7 @@ static struct dvb_frontend_ops cxd2841er_t_c_ops = { .symbol_rate_max = 11700000 }, .init = cxd2841er_init_tc, - .sleep = cxd2841er_sleep_tc, + .sleep = cxd2841er_shutdown_tc, .release = cxd2841er_release, .set_frontend = cxd2841er_set_frontend_tc, .get_frontend = cxd2841er_get_frontend, -- cgit v1.2.3 From 7f0337086e4564ccdc4ed3ba15747f6e9fb4cf71 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 13 Jul 2017 07:34:28 -0400 Subject: media: drxd: make const arrays slowIncrDecLUT and fastIncrDecLUT static Don't populate arrays slowIncrDecLUT and fastIncrDecLUT on the stack but instead make them static. Makes the object code smaller by over 100 bytes: text data bss dec hex filename 27776 832 64 28672 7000 drxd_hard.o text data bss dec hex filename 27530 976 64 28570 6f9a drxd_hard.o Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drxd_hard.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 17638e08835a..7d04400b18dd 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c @@ -638,8 +638,10 @@ static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg) /* == Speed == */ { const u16 maxRur = 8; - const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 }; - const u16 fastIncrDecLUT[] = { 14, 15, 15, 16, + static const u16 slowIncrDecLUT[] = { + 3, 4, 4, 5, 6 }; + const u16 fastIncrDecLUT[] = { + 14, 15, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, -- cgit v1.2.3 From 679cfbb158912ea94c0f450f729124c49826f137 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 13 Jul 2017 07:44:03 -0400 Subject: media: drxj: make several const arrays static Don't populate const arrays on the stack but instead make them static. Makes the object code smaller by over 1800 bytes: Before: text data bss dec hex filename 94100 9160 0 103260 1935c drxj.o After: text data bss dec hex filename 91044 10400 0 101444 18c44 drxj.o Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drx39xyj/drxj.c | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 14040c915dbb..499ccff557bf 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -5489,7 +5489,7 @@ static int set_vsb_leak_n_gain(struct drx_demod_instance *demod) struct i2c_device_addr *dev_addr = NULL; int rc; - const u8 vsb_ffe_leak_gain_ram0[] = { + static const u8 vsb_ffe_leak_gain_ram0[] = { DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */ DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */ DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */ @@ -5620,7 +5620,7 @@ static int set_vsb_leak_n_gain(struct drx_demod_instance *demod) DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */ }; - const u8 vsb_ffe_leak_gain_ram1[] = { + static const u8 vsb_ffe_leak_gain_ram1[] = { DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */ DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */ DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */ @@ -5710,7 +5710,7 @@ static int set_vsb(struct drx_demod_instance *demod) struct drxj_data *ext_attr = NULL; u16 cmd_result = 0; u16 cmd_param = 0; - const u8 vsb_taps_re[] = { + static const u8 vsb_taps_re[] = { DRXJ_16TO8(-2), /* re0 */ DRXJ_16TO8(4), /* re1 */ DRXJ_16TO8(1), /* re2 */ @@ -6666,7 +6666,7 @@ static int set_qam16(struct drx_demod_instance *demod) { struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - const u8 qam_dq_qual_fun[] = { + static const u8 qam_dq_qual_fun[] = { DRXJ_16TO8(2), /* fun0 */ DRXJ_16TO8(2), /* fun1 */ DRXJ_16TO8(2), /* fun2 */ @@ -6674,7 +6674,7 @@ static int set_qam16(struct drx_demod_instance *demod) DRXJ_16TO8(3), /* fun4 */ DRXJ_16TO8(3), /* fun5 */ }; - const u8 qam_eq_cma_rad[] = { + static const u8 qam_eq_cma_rad[] = { DRXJ_16TO8(13517), /* RAD0 */ DRXJ_16TO8(13517), /* RAD1 */ DRXJ_16TO8(13517), /* RAD2 */ @@ -6901,7 +6901,7 @@ static int set_qam32(struct drx_demod_instance *demod) { struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - const u8 qam_dq_qual_fun[] = { + static const u8 qam_dq_qual_fun[] = { DRXJ_16TO8(3), /* fun0 */ DRXJ_16TO8(3), /* fun1 */ DRXJ_16TO8(3), /* fun2 */ @@ -6909,7 +6909,7 @@ static int set_qam32(struct drx_demod_instance *demod) DRXJ_16TO8(4), /* fun4 */ DRXJ_16TO8(4), /* fun5 */ }; - const u8 qam_eq_cma_rad[] = { + static const u8 qam_eq_cma_rad[] = { DRXJ_16TO8(6707), /* RAD0 */ DRXJ_16TO8(6707), /* RAD1 */ DRXJ_16TO8(6707), /* RAD2 */ @@ -7136,7 +7136,8 @@ static int set_qam64(struct drx_demod_instance *demod) { struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - const u8 qam_dq_qual_fun[] = { /* this is hw reset value. no necessary to re-write */ + static const u8 qam_dq_qual_fun[] = { + /* this is hw reset value. no necessary to re-write */ DRXJ_16TO8(4), /* fun0 */ DRXJ_16TO8(4), /* fun1 */ DRXJ_16TO8(4), /* fun2 */ @@ -7144,7 +7145,7 @@ static int set_qam64(struct drx_demod_instance *demod) DRXJ_16TO8(6), /* fun4 */ DRXJ_16TO8(6), /* fun5 */ }; - const u8 qam_eq_cma_rad[] = { + static const u8 qam_eq_cma_rad[] = { DRXJ_16TO8(13336), /* RAD0 */ DRXJ_16TO8(12618), /* RAD1 */ DRXJ_16TO8(11988), /* RAD2 */ @@ -7371,7 +7372,7 @@ static int set_qam128(struct drx_demod_instance *demod) { struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - const u8 qam_dq_qual_fun[] = { + static const u8 qam_dq_qual_fun[] = { DRXJ_16TO8(6), /* fun0 */ DRXJ_16TO8(6), /* fun1 */ DRXJ_16TO8(6), /* fun2 */ @@ -7379,7 +7380,7 @@ static int set_qam128(struct drx_demod_instance *demod) DRXJ_16TO8(9), /* fun4 */ DRXJ_16TO8(9), /* fun5 */ }; - const u8 qam_eq_cma_rad[] = { + static const u8 qam_eq_cma_rad[] = { DRXJ_16TO8(6164), /* RAD0 */ DRXJ_16TO8(6598), /* RAD1 */ DRXJ_16TO8(6394), /* RAD2 */ @@ -7606,7 +7607,7 @@ static int set_qam256(struct drx_demod_instance *demod) { struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr; int rc; - const u8 qam_dq_qual_fun[] = { + static const u8 qam_dq_qual_fun[] = { DRXJ_16TO8(8), /* fun0 */ DRXJ_16TO8(8), /* fun1 */ DRXJ_16TO8(8), /* fun2 */ @@ -7614,7 +7615,7 @@ static int set_qam256(struct drx_demod_instance *demod) DRXJ_16TO8(12), /* fun4 */ DRXJ_16TO8(12), /* fun5 */ }; - const u8 qam_eq_cma_rad[] = { + static const u8 qam_eq_cma_rad[] = { DRXJ_16TO8(12345), /* RAD0 */ DRXJ_16TO8(12345), /* RAD1 */ DRXJ_16TO8(13626), /* RAD2 */ @@ -7862,7 +7863,7 @@ set_qam(struct drx_demod_instance *demod, /* parameter */ NULL, /* result */ NULL }; - const u8 qam_a_taps[] = { + static const u8 qam_a_taps[] = { DRXJ_16TO8(-1), /* re0 */ DRXJ_16TO8(1), /* re1 */ DRXJ_16TO8(1), /* re2 */ @@ -7892,7 +7893,7 @@ set_qam(struct drx_demod_instance *demod, DRXJ_16TO8(-40), /* re26 */ DRXJ_16TO8(619) /* re27 */ }; - const u8 qam_b64_taps[] = { + static const u8 qam_b64_taps[] = { DRXJ_16TO8(0), /* re0 */ DRXJ_16TO8(-2), /* re1 */ DRXJ_16TO8(1), /* re2 */ @@ -7922,7 +7923,7 @@ set_qam(struct drx_demod_instance *demod, DRXJ_16TO8(-46), /* re26 */ DRXJ_16TO8(614) /* re27 */ }; - const u8 qam_b256_taps[] = { + static const u8 qam_b256_taps[] = { DRXJ_16TO8(-2), /* re0 */ DRXJ_16TO8(4), /* re1 */ DRXJ_16TO8(1), /* re2 */ @@ -7952,7 +7953,7 @@ set_qam(struct drx_demod_instance *demod, DRXJ_16TO8(-32), /* re26 */ DRXJ_16TO8(628) /* re27 */ }; - const u8 qam_c_taps[] = { + static const u8 qam_c_taps[] = { DRXJ_16TO8(-3), /* re0 */ DRXJ_16TO8(3), /* re1 */ DRXJ_16TO8(2), /* re2 */ -- cgit v1.2.3 From 6e4e4447d446f692b8528cecefae2ff5110bf877 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 13 Jul 2017 08:00:20 -0400 Subject: media: dib0090: make const array dib0090_tuning_table_cband_7090e_aci static Don't populate array dib0090_tuning_table_cband_7090e_aci on the stack but instead make it static. Makes the object code smaller by over 180 bytes: Before: text data bss dec hex filename 40052 7320 192 47564 b9cc dib0090.o After: text data bss dec hex filename 39780 7408 192 47380 b914 dib0090.o Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0090.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 33af14df27bd..ae53a199b7af 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -2052,7 +2052,7 @@ int dib0090_update_tuning_table_7090(struct dvb_frontend *fe, struct dib0090_state *state = fe->tuner_priv; const struct dib0090_tuning *tune = dib0090_tuning_table_cband_7090e_sensitivity; - const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { + static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = { { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB }, { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB }, { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB }, -- cgit v1.2.3 From 10e81bcddea6c77c0b2a1d7c6be59dba5794fa0a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 13 Jul 2017 11:23:48 -0400 Subject: media: Remove useless curly braces and parentheses Simplify the code to satisfy Linux coding style. Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 760e3e424e23..c51e2e5636f3 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -591,9 +591,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, &entity->pads[i].graph_obj); /* invoke entity_notify callbacks */ - list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) { - (notify)->notify(entity, notify->notify_data); - } + list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) + notify->notify(entity, notify->notify_data); if (mdev->entity_internal_idx_max >= mdev->pm_count_walk.ent_enum.idx_max) { -- cgit v1.2.3 From 552636be7afc86531d1931b5104d7002850d3af7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 13 Jul 2017 11:23:49 -0400 Subject: media: devnode: Rename mdev argument as devnode Historically, mdev argument name was being used on both struct media_device and struct media_devnode. Recently most occurrences of mdev referring to struct media_devnode were replaced by devnode, which makes more sense. Fix the last remaining occurrence. Fixes: 163f1e93e9950 ("[media] media-devnode: fix namespace mess") Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c51e2e5636f3..fce91b543c14 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -537,9 +537,9 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); * Registration/unregistration */ -static void media_device_release(struct media_devnode *mdev) +static void media_device_release(struct media_devnode *devnode) { - dev_dbg(mdev->parent, "Media device released\n"); + dev_dbg(devnode->parent, "Media device released\n"); } /** -- cgit v1.2.3 From d105d083448e79ec3f4b1d3f501b869a4515a1d0 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Fri, 14 Jul 2017 17:23:36 -0400 Subject: media: dvb-frontends/stv0367: improve QAM fe_status While cab_state->state gives a quite accurate indication of the demod signal status, it might be incorrect if cab_algo() wasn't able to determine the exact status, with cab_algo() being the only place where this status was updated from, and it is only called upon tuning to new parameters passed to set_frontend(). Thus, the status will be wrong until the demod is retuned. With the cab_signal_type parsing in read_status(), this results in unusual fe_states like FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK, which, while userspace applications check for FE_HAS_LOCK and work fine, leads to missing CNR or UCB stats. Fix this by re-reading CAB_FSM_STATUS and updating cab_state->state() in read_status(). While at it, refactor the fsm/qamfeclock and the fsm->signaltype parsing into separate functions to make things cleaner and deduplicate code. Also, assume full QAM FEC lock equals full FE_STATUS. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0367.c | 148 +++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index 59c1aad256c2..bc6eb0ab733e 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -2149,6 +2149,71 @@ static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz) return regsym; } +static u32 stv0367cab_fsm_status(struct stv0367_state *state) +{ + return stv0367_readbits(state, F367CAB_FSM_STATUS); +} + +static u32 stv0367cab_qamfec_lock(struct stv0367_state *state) +{ + return stv0367_readbits(state, + (state->cab_state->qamfec_status_reg ? + state->cab_state->qamfec_status_reg : + F367CAB_QAMFEC_LOCK)); +} + +static +enum stv0367_cab_signal_type stv0367cab_fsm_signaltype(u32 qam_fsm_status) +{ + enum stv0367_cab_signal_type signaltype = FE_CAB_NOAGC; + + switch (qam_fsm_status) { + case 1: + signaltype = FE_CAB_NOAGC; + break; + case 2: + signaltype = FE_CAB_NOTIMING; + break; + case 3: + signaltype = FE_CAB_TIMINGOK; + break; + case 4: + signaltype = FE_CAB_NOCARRIER; + break; + case 5: + signaltype = FE_CAB_CARRIEROK; + break; + case 7: + signaltype = FE_CAB_NOBLIND; + break; + case 8: + signaltype = FE_CAB_BLINDOK; + break; + case 10: + signaltype = FE_CAB_NODEMOD; + break; + case 11: + signaltype = FE_CAB_DEMODOK; + break; + case 12: + signaltype = FE_CAB_DEMODOK; + break; + case 13: + signaltype = FE_CAB_NODEMOD; + break; + case 14: + signaltype = FE_CAB_NOBLIND; + break; + case 15: + signaltype = FE_CAB_NOSIGNAL; + break; + default: + break; + } + + return signaltype; +} + static int stv0367cab_read_status(struct dvb_frontend *fe, enum fe_status *status) { @@ -2158,22 +2223,26 @@ static int stv0367cab_read_status(struct dvb_frontend *fe, *status = 0; - if (state->cab_state->state > FE_CAB_NOSIGNAL) - *status |= FE_HAS_SIGNAL; + /* update cab_state->state from QAM_FSM_STATUS */ + state->cab_state->state = stv0367cab_fsm_signaltype( + stv0367cab_fsm_status(state)); - if (state->cab_state->state > FE_CAB_NOCARRIER) - *status |= FE_HAS_CARRIER; + if (stv0367cab_qamfec_lock(state)) { + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI + | FE_HAS_SYNC | FE_HAS_LOCK; + dprintk("%s: stv0367 has locked\n", __func__); + } else { + if (state->cab_state->state > FE_CAB_NOSIGNAL) + *status |= FE_HAS_SIGNAL; - if (state->cab_state->state >= FE_CAB_DEMODOK) - *status |= FE_HAS_VITERBI; + if (state->cab_state->state > FE_CAB_NOCARRIER) + *status |= FE_HAS_CARRIER; - if (state->cab_state->state >= FE_CAB_DATAOK) - *status |= FE_HAS_SYNC; + if (state->cab_state->state >= FE_CAB_DEMODOK) + *status |= FE_HAS_VITERBI; - if (stv0367_readbits(state, (state->cab_state->qamfec_status_reg ? - state->cab_state->qamfec_status_reg : F367CAB_QAMFEC_LOCK))) { - *status |= FE_HAS_LOCK; - dprintk("%s: stv0367 has locked\n", __func__); + if (state->cab_state->state >= FE_CAB_DATAOK) + *status |= FE_HAS_SYNC; } return 0; @@ -2374,7 +2443,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, LockTime = 0; stv0367_writereg(state, R367CAB_CTRL_1, 0x00); do { - QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS); + QAM_Lock = stv0367cab_fsm_status(state); if ((LockTime >= (DemodTimeOut - EQLTimeOut)) && (QAM_Lock == 0x04)) /* @@ -2435,10 +2504,7 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, do { usleep_range(5000, 7000); LockTime += 5; - QAMFEC_Lock = stv0367_readbits(state, - (state->cab_state->qamfec_status_reg ? - state->cab_state->qamfec_status_reg : - F367CAB_QAMFEC_LOCK)); + QAMFEC_Lock = stv0367cab_qamfec_lock(state); } while (!QAMFEC_Lock && (LockTime < FECTimeOut)); } else QAMFEC_Lock = 0; @@ -2474,52 +2540,8 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, cab_state->locked = 1; /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/ - } else { - switch (QAM_Lock) { - case 1: - signalType = FE_CAB_NOAGC; - break; - case 2: - signalType = FE_CAB_NOTIMING; - break; - case 3: - signalType = FE_CAB_TIMINGOK; - break; - case 4: - signalType = FE_CAB_NOCARRIER; - break; - case 5: - signalType = FE_CAB_CARRIEROK; - break; - case 7: - signalType = FE_CAB_NOBLIND; - break; - case 8: - signalType = FE_CAB_BLINDOK; - break; - case 10: - signalType = FE_CAB_NODEMOD; - break; - case 11: - signalType = FE_CAB_DEMODOK; - break; - case 12: - signalType = FE_CAB_DEMODOK; - break; - case 13: - signalType = FE_CAB_NODEMOD; - break; - case 14: - signalType = FE_CAB_NOBLIND; - break; - case 15: - signalType = FE_CAB_NOSIGNAL; - break; - default: - break; - } - - } + } else + signalType = stv0367cab_fsm_signaltype(QAM_Lock); /* Set the AGC control values to tracking values */ stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum); -- cgit v1.2.3 From a004b70e70d3fca8ea021ad51ebf8e614049332c Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:02 -0400 Subject: media: dvb_ca_en50221: Refactored dvb_ca_en50221_thread Refactored "dvb_ca_en50221_thread" by moving the state machine into the new function "dvb_ca_en50221_thread_state_machine". This reduces the thread function size and reduces the structural complexity and of course gives us more space to meet the line length goal in the new function. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 363 +++++++++++++++++--------------- 1 file changed, 198 insertions(+), 165 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 17970cdd55fa..e2f35b7c59dd 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1063,207 +1063,240 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) ca->delay = curdelay; } - - /** - * Kernel thread which monitors CA slots for CAM changes, and performs data transfers. + * Thread state machine for one CA slot to perform the data transfer. + * + * @ca: CA instance. + * @slot: Slot to process. */ -static int dvb_ca_en50221_thread(void *data) +static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, + int slot) { - struct dvb_ca_private *ca = data; - int slot; + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int flags; int status; int pktcount; void *rxbuf; - dprintk("%s\n", __func__); + mutex_lock(&sl->slot_lock); - /* choose the correct initial delay */ - dvb_ca_en50221_thread_update_delay(ca); + /* check the cam status + deal with CAMCHANGEs */ + while (dvb_ca_en50221_check_camstatus(ca, slot)) { + /* clear down an old CI slot if necessary */ + if (sl->slot_state != DVB_CA_SLOTSTATE_NONE) + dvb_ca_en50221_slot_shutdown(ca, slot); - /* main loop */ - while (!kthread_should_stop()) { - /* sleep for a bit */ - if (!ca->wakeup) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(ca->delay); - if (kthread_should_stop()) - return 0; - } - ca->wakeup = 0; + /* if a CAM is NOW present, initialise it */ + if (sl->camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) + sl->slot_state = DVB_CA_SLOTSTATE_UNINITIALISED; - /* go through all the slots processing them */ - for (slot = 0; slot < ca->slot_count; slot++) { - - mutex_lock(&ca->slot_info[slot].slot_lock); - - // check the cam status + deal with CAMCHANGEs - while (dvb_ca_en50221_check_camstatus(ca, slot)) { - /* clear down an old CI slot if necessary */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) - dvb_ca_en50221_slot_shutdown(ca, slot); - - /* if a CAM is NOW present, initialise it */ - if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED; - } + /* we've handled one CAMCHANGE */ + dvb_ca_en50221_thread_update_delay(ca); + atomic_dec(&sl->camchange_count); + } - /* we've handled one CAMCHANGE */ - dvb_ca_en50221_thread_update_delay(ca); - atomic_dec(&ca->slot_info[slot].camchange_count); - } + /* CAM state machine */ + switch (sl->slot_state) { + case DVB_CA_SLOTSTATE_NONE: + case DVB_CA_SLOTSTATE_INVALID: + /* no action needed */ + break; - // CAM state machine - switch (ca->slot_info[slot].slot_state) { - case DVB_CA_SLOTSTATE_NONE: - case DVB_CA_SLOTSTATE_INVALID: - // no action needed - break; + case DVB_CA_SLOTSTATE_UNINITIALISED: + sl->slot_state = DVB_CA_SLOTSTATE_WAITREADY; + ca->pub->slot_reset(ca->pub, slot); + sl->timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); + break; - case DVB_CA_SLOTSTATE_UNINITIALISED: - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY; - ca->pub->slot_reset(ca->pub, slot); - ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); - break; + case DVB_CA_SLOTSTATE_WAITREADY: + if (time_after(jiffies, sl->timeout)) { + pr_err("dvb_ca adaptor %d: PC card did not respond :(\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); + break; + } + /* + * no other action needed; will automatically change state when + * ready + */ + break; - case DVB_CA_SLOTSTATE_WAITREADY: - if (time_after(jiffies, ca->slot_info[slot].timeout)) { - pr_err("dvb_ca adaptor %d: PC card did not respond :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; + case DVB_CA_SLOTSTATE_VALIDATE: + if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { + /* + * we need this extra check for annoying interfaces like + * the budget-av + */ + if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) + && (ca->pub->poll_slot_status)) { + status = ca->pub->poll_slot_status(ca->pub, + slot, 0); + if (!(status & + DVB_CA_EN50221_POLL_CAM_PRESENT)) { + sl->slot_state = DVB_CA_SLOTSTATE_NONE; dvb_ca_en50221_thread_update_delay(ca); break; } - // no other action needed; will automatically change state when ready - break; + } - case DVB_CA_SLOTSTATE_VALIDATE: - if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - - pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - if (dvb_ca_en50221_set_configoption(ca, slot) != 0) { - pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - if (ca->pub->write_cam_control(ca->pub, slot, - CTRLIF_COMMAND, CMDREG_RS) != 0) { - pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - dprintk("DVB CAM validated successfully\n"); + pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); + break; + } + if (dvb_ca_en50221_set_configoption(ca, slot) != 0) { + pr_err("dvb_ca adapter %d: Unable to initialise CAM :(\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); + break; + } + if (ca->pub->write_cam_control(ca->pub, slot, + CTRLIF_COMMAND, + CMDREG_RS) != 0) { + pr_err("dvb_ca adapter %d: Unable to reset CAM IF\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); + break; + } + dprintk("DVB CAM validated successfully\n"); - ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR; - ca->wakeup = 1; - break; + sl->timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); + sl->slot_state = DVB_CA_SLOTSTATE_WAITFR; + ca->wakeup = 1; + break; - case DVB_CA_SLOTSTATE_WAITFR: - if (time_after(jiffies, ca->slot_info[slot].timeout)) { - pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } + case DVB_CA_SLOTSTATE_WAITFR: + if (time_after(jiffies, sl->timeout)) { + pr_err("dvb_ca adapter %d: DVB CAM did not respond :(\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); + break; + } - flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); - if (flags & STATUSREG_FR) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - ca->wakeup = 1; - } - break; + flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + if (flags & STATUSREG_FR) { + sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT; + ca->wakeup = 1; + } + break; - case DVB_CA_SLOTSTATE_LINKINIT: - if (dvb_ca_en50221_link_init(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - - pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = - DVB_CA_SLOTSTATE_UNINITIALISED; + case DVB_CA_SLOTSTATE_LINKINIT: + if (dvb_ca_en50221_link_init(ca, slot) != 0) { + /* + * we need this extra check for annoying interfaces like + * the budget-av + */ + if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) + && (ca->pub->poll_slot_status)) { + status = ca->pub->poll_slot_status(ca->pub, + slot, 0); + if (!(status & + DVB_CA_EN50221_POLL_CAM_PRESENT)) { + sl->slot_state = DVB_CA_SLOTSTATE_NONE; dvb_ca_en50221_thread_update_delay(ca); break; } + } - if (ca->slot_info[slot].rx_buffer.data == NULL) { - rxbuf = vmalloc(RX_BUFFER_SIZE); - if (rxbuf == NULL) { - pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE); - } + pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", + ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_UNINITIALISED; + dvb_ca_en50221_thread_update_delay(ca); + break; + } - ca->pub->slot_ts_enable(ca->pub, slot); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING; - dvb_ca_en50221_thread_update_delay(ca); - pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", + if (!sl->rx_buffer.data) { + rxbuf = vmalloc(RX_BUFFER_SIZE); + if (!rxbuf) { + pr_err("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num); + sl->slot_state = DVB_CA_SLOTSTATE_INVALID; + dvb_ca_en50221_thread_update_delay(ca); break; + } + dvb_ringbuffer_init(&sl->rx_buffer, rxbuf, + RX_BUFFER_SIZE); + } - case DVB_CA_SLOTSTATE_RUNNING: - if (!ca->open) - break; + ca->pub->slot_ts_enable(ca->pub, slot); + sl->slot_state = DVB_CA_SLOTSTATE_RUNNING; + dvb_ca_en50221_thread_update_delay(ca); + pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", + ca->dvbdev->adapter->num); + break; - // poll slots for data - pktcount = 0; - while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) { - if (!ca->open) - break; - - /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */ - if (dvb_ca_en50221_check_camstatus(ca, slot)) { - // we dont want to sleep on the next iteration so we can handle the cam change - ca->wakeup = 1; - break; - } - - /* check if we've hit our limit this time */ - if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) { - // dont sleep; there is likely to be more data to read - ca->wakeup = 1; - break; - } - } + case DVB_CA_SLOTSTATE_RUNNING: + if (!ca->open) + break; + + /* poll slots for data */ + pktcount = 0; + while (dvb_ca_en50221_read_data(ca, slot, NULL, 0) > 0) { + if (!ca->open) + break; + + /* + * if a CAMCHANGE occurred at some point, do not do any + * more processing of this slot + */ + if (dvb_ca_en50221_check_camstatus(ca, slot)) { + /* + * we dont want to sleep on the next iteration + * so we can handle the cam change + */ + ca->wakeup = 1; break; } - mutex_unlock(&ca->slot_info[slot].slot_lock); + /* check if we've hit our limit this time */ + if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) { + /* + * dont sleep; there is likely to be more data + * to read + */ + ca->wakeup = 1; + break; + } + } + break; + } + + mutex_unlock(&sl->slot_lock); +} + +/** + * Kernel thread which monitors CA slots for CAM changes, and performs data + * transfers. + */ +static int dvb_ca_en50221_thread(void *data) +{ + struct dvb_ca_private *ca = data; + int slot; + + dprintk("%s\n", __func__); + + /* choose the correct initial delay */ + dvb_ca_en50221_thread_update_delay(ca); + + /* main loop */ + while (!kthread_should_stop()) { + /* sleep for a bit */ + if (!ca->wakeup) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(ca->delay); + if (kthread_should_stop()) + return 0; } + ca->wakeup = 0; + + /* go through all the slots processing them */ + for (slot = 0; slot < ca->slot_count; slot++) + dvb_ca_en50221_thread_state_machine(ca, slot); } return 0; -- cgit v1.2.3 From 5d023252cbe4d5164ec812f179b8b2b7fe55f476 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:03 -0400 Subject: media: dvb_ca_en50221: New function dvb_ca_en50221_poll_cam_gone The CAM poll code for the budget-av is exactly the same on several places. Extracting the code to a new function improves maintainability. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 66 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index e2f35b7c59dd..bb6aa0f86c07 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1063,6 +1063,37 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) ca->delay = curdelay; } +/** + * Poll if the CAM is gone. + * + * @ca: CA instance. + * @slot: Slot to process. + * @return: 0 .. no change + * 1 .. CAM state changed + */ + +static int dvb_ca_en50221_poll_cam_gone(struct dvb_ca_private *ca, int slot) +{ + int changed = 0; + int status; + + /* + * we need this extra check for annoying interfaces like the + * budget-av + */ + if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && + (ca->pub->poll_slot_status)) { + status = ca->pub->poll_slot_status(ca->pub, slot, 0); + if (!(status & + DVB_CA_EN50221_POLL_CAM_PRESENT)) { + ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; + dvb_ca_en50221_thread_update_delay(ca); + changed = 1; + } + } + return changed; +} + /** * Thread state machine for one CA slot to perform the data transfer. * @@ -1074,7 +1105,6 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, { struct dvb_ca_slot *sl = &ca->slot_info[slot]; int flags; - int status; int pktcount; void *rxbuf; @@ -1124,21 +1154,8 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, case DVB_CA_SLOTSTATE_VALIDATE: if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { - /* - * we need this extra check for annoying interfaces like - * the budget-av - */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) - && (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, - slot, 0); - if (!(status & - DVB_CA_EN50221_POLL_CAM_PRESENT)) { - sl->slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } + if (dvb_ca_en50221_poll_cam_gone(ca, slot)) + break; pr_err("dvb_ca adapter %d: Invalid PC card inserted :(\n", ca->dvbdev->adapter->num); @@ -1187,21 +1204,8 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, case DVB_CA_SLOTSTATE_LINKINIT: if (dvb_ca_en50221_link_init(ca, slot) != 0) { - /* - * we need this extra check for annoying interfaces like - * the budget-av - */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) - && (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, - slot, 0); - if (!(status & - DVB_CA_EN50221_POLL_CAM_PRESENT)) { - sl->slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } + if (dvb_ca_en50221_poll_cam_gone(ca, slot)) + break; pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); -- cgit v1.2.3 From b9af29e15a7cf9d5e26deee0267857d1e0dc78d5 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:04 -0400 Subject: media: dvb_ca_en50221: use usleep_range Fixed all: WARNING: msleep < 20ms can sleep for up to 20ms by using usleep_range. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index bb6aa0f86c07..725fdd0c2071 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -313,7 +313,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, } /* wait for a bit */ - msleep(1); + usleep_range(1000, 1100); } dprintk("%s failed timeout:%lu\n", __func__, jiffies - start); @@ -1489,7 +1489,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, if (status != -EAGAIN) goto exit; - msleep(1); + usleep_range(1000, 1100); } if (!written) { status = -EIO; -- cgit v1.2.3 From a1ca23d10ed088484c9b69596bddf9da6c0a9ec0 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:05 -0400 Subject: media: dvb_ca_en50221: Fixed block comments Fixed all: WARNING: Block comments use * on subsequent lines Added also the missing opening empty comment line. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 725fdd0c2071..28e610220a07 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -342,8 +342,10 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) /* we'll be determining these during this function */ ca->slot_info[slot].da_irq_supported = 0; - /* set the host link buffer size temporarily. it will be overwritten with the - * real negotiated size later. */ + /* + * set the host link buffer size temporarily. it will be overwritten + * with the real negotiated size later. + */ ca->slot_info[slot].link_buf_size = 2; /* read the buffer size from the CAM */ @@ -796,10 +798,12 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) return ca->pub->write_data(ca->pub, slot, buf, bytes_write); - /* it is possible we are dealing with a single buffer implementation, - thus if there is data available for read or if there is even a read - already in progress, we do nothing but awake the kernel thread to - process the data if necessary. */ + /* + * it is possible we are dealing with a single buffer implementation, + * thus if there is data available for read or if there is even a read + * already in progress, we do nothing but awake the kernel thread to + * process the data if necessary. + */ if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) goto exitnowrite; if (status & (STATUSREG_DA | STATUSREG_RE)) { @@ -899,8 +903,10 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) ca->pub->slot_shutdown(ca->pub, slot); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - /* need to wake up all processes to check if they're now - trying to write to a defunct CAM */ + /* + * need to wake up all processes to check if they're now trying to + * write to a defunct CAM + */ wake_up_interruptible(&ca->wait_queue); dprintk("Slot %i shutdown\n", slot); @@ -1686,8 +1692,11 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) { if (ca->slot_info[i].rx_buffer.data != NULL) { - /* it is safe to call this here without locks because - * ca->open == 0. Data is not read in this case */ + /* + * it is safe to call this here without locks + * because ca->open == 0. Data is not read in + * this case + */ dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer); } } -- cgit v1.2.3 From bacba9e540162feef62ed17ed49c313a287a3341 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:06 -0400 Subject: media: dvb_ca_en50221: Avoid assignments in ifs Fixed all: ERROR: do not use assignment in if condition Fixed also "-strict" checks in this patch: - Changed "if (ret != 0)" to "if (ret)". - Camel case variables have been converted to kernel_case. - Comparison to NULL written as "!". - No space is necessary after a cast. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 166 +++++++++++++++++++------------- 1 file changed, 100 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 28e610220a07..d06cdc7a0a2b 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -349,14 +349,18 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) ca->slot_info[slot].link_buf_size = 2; /* read the buffer size from the CAM */ - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0) + ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, + IRQEN | CMDREG_SR); + if (ret) return ret; ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ); - if (ret != 0) + if (ret) return ret; - if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2) + ret = dvb_ca_en50221_read_data(ca, slot, buf, 2); + if (ret != 2) return -EIO; - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0) + ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN); + if (ret) return ret; /* store it, and choose the minimum of our buffer and the CAM's buffer size */ @@ -369,13 +373,18 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) dprintk("Chosen link buffer size of %i\n", buf_size); /* write the buffer size to the CAM */ - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0) + ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, + IRQEN | CMDREG_SW); + if (ret) return ret; - if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0) + ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10); + if (ret) return ret; - if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2) + ret = dvb_ca_en50221_write_data(ca, slot, buf, 2); + if (ret != 2) return -EIO; - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0) + ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN); + if (ret) return ret; /* success */ @@ -395,42 +404,45 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) * @return 0 on success, nonzero on error. */ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, - int *address, int *tupleType, - int *tupleLength, u8 *tuple) + int *address, int *tuple_type, + int *tuple_length, u8 *tuple) { int i; - int _tupleType; - int _tupleLength; + int _tuple_type; + int _tuple_length; int _address = *address; /* grab the next tuple length and type */ - if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0) - return _tupleType; - if (_tupleType == 0xff) { - dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType); + _tuple_type = ca->pub->read_attribute_mem(ca->pub, slot, _address); + if (_tuple_type < 0) + return _tuple_type; + if (_tuple_type == 0xff) { + dprintk("END OF CHAIN TUPLE type:0x%x\n", _tuple_type); *address += 2; - *tupleType = _tupleType; - *tupleLength = 0; + *tuple_type = _tuple_type; + *tuple_length = 0; return 0; } - if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0) - return _tupleLength; + _tuple_length = ca->pub->read_attribute_mem(ca->pub, slot, + _address + 2); + if (_tuple_length < 0) + return _tuple_length; _address += 4; - dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength); + dprintk("TUPLE type:0x%x length:%i\n", _tuple_type, _tuple_length); /* read in the whole tuple */ - for (i = 0; i < _tupleLength; i++) { + for (i = 0; i < _tuple_length; i++) { tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2)); dprintk(" 0x%02x: 0x%02x %c\n", i, tuple[i] & 0xff, ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.'); } - _address += (_tupleLength * 2); + _address += (_tuple_length * 2); // success - *tupleType = _tupleType; - *tupleLength = _tupleLength; + *tuple_type = _tuple_type; + *tuple_length = _tuple_length; *address = _address; return 0; } @@ -448,8 +460,8 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) { int address = 0; - int tupleLength; - int tupleType; + int tuple_length; + int tuple_type; u8 tuple[257]; char *dvb_str; int rasz; @@ -462,39 +474,43 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) // CISTPL_DEVICE_0A - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, + &tuple_length, tuple); + if (status < 0) return status; - if (tupleType != 0x1D) + if (tuple_type != 0x1D) return -EINVAL; // CISTPL_DEVICE_0C - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, + &tuple_length, tuple); + if (status < 0) return status; - if (tupleType != 0x1C) + if (tuple_type != 0x1C) return -EINVAL; // CISTPL_VERS_1 - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, + &tuple_length, tuple); + if (status < 0) return status; - if (tupleType != 0x15) + if (tuple_type != 0x15) return -EINVAL; // CISTPL_MANFID - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, + &tuple_length, tuple); + if (status < 0) return status; - if (tupleType != 0x20) + if (tuple_type != 0x20) return -EINVAL; - if (tupleLength != 4) + if (tuple_length != 4) return -EINVAL; manfid = (tuple[1] << 8) | tuple[0]; devid = (tuple[3] << 8) | tuple[2]; @@ -502,17 +518,18 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) // CISTPL_CONFIG - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, + &tuple_length, tuple); + if (status < 0) return status; - if (tupleType != 0x1A) + if (tuple_type != 0x1A) return -EINVAL; - if (tupleLength < 3) + if (tuple_length < 3) return -EINVAL; /* extract the configbase */ rasz = tuple[0] & 3; - if (tupleLength < (3 + rasz + 14)) + if (tuple_length < (3 + rasz + 14)) return -EINVAL; ca->slot_info[slot].config_base = 0; for (i = 0; i < rasz + 1; i++) { @@ -520,10 +537,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) } /* check it contains the correct DVB string */ - dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8); + dvb_str = findstr((char *)tuple, tuple_length, "DVB_CI_V", 8); if (dvb_str == NULL) return -EINVAL; - if (tupleLength < ((dvb_str - (char *) tuple) + 12)) + if (tuple_length < ((dvb_str - (char *)tuple) + 12)) return -EINVAL; /* is it a version we support? */ @@ -536,12 +553,14 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) /* process the CFTABLE_ENTRY tuples, and any after those */ while ((!end_chain) && (address < 0x1000)) { - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) + status = dvb_ca_en50221_read_tuple(ca, slot, &address, + &tuple_type, &tuple_length, + tuple); + if (status < 0) return status; - switch (tupleType) { + switch (tuple_type) { case 0x1B: // CISTPL_CFTABLE_ENTRY - if (tupleLength < (2 + 11 + 17)) + if (tuple_length < (2 + 11 + 17)) break; /* if we've already parsed one, just use it */ @@ -552,8 +571,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) ca->slot_info[slot].config_option = tuple[0] & 0x3f; /* OK, check it contains the correct strings */ - if ((findstr((char *)tuple, tupleLength, "DVB_HOST", 8) == NULL) || - (findstr((char *)tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL)) + if (!findstr((char *)tuple, tuple_length, + "DVB_HOST", 8) || + !findstr((char *)tuple, tuple_length, + "DVB_CI_MODULE", 13)) break; got_cftableentry = 1; @@ -568,7 +589,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) default: /* Unknown tuple type - just skip this tuple and move to the next one */ dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", - tupleType, tupleLength); + tuple_type, tuple_length); break; } } @@ -804,7 +825,8 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, * already in progress, we do nothing but awake the kernel thread to * process the data if necessary. */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) + status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + if (status < 0) goto exitnowrite; if (status & (STATUSREG_DA | STATUSREG_RE)) { if (status & STATUSREG_DA) @@ -815,12 +837,14 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, } /* OK, set HC bit */ - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, - IRQEN | CMDREG_HC)) != 0) + status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, + IRQEN | CMDREG_HC); + if (status) goto exit; /* check if interface is still free */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) + status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + if (status < 0) goto exit; if (!(status & STATUSREG_FR)) { /* it wasn't free => try again later */ @@ -852,20 +876,26 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, } /* send the amount of data */ - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) + status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, + bytes_write >> 8); + if (status) goto exit; - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW, - bytes_write & 0xff)) != 0) + status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW, + bytes_write & 0xff); + if (status) goto exit; /* send the buffer */ for (i = 0; i < bytes_write; i++) { - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0) + status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, + buf[i]); + if (status) goto exit; } /* check for write error (WE should now be 0) */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) + status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + if (status < 0) goto exit; if (status & STATUSREG_WE) { ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; @@ -1591,7 +1621,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, return -EINVAL; /* wait for some data */ - if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) { + status = dvb_ca_en50221_io_read_condition(ca, &result, &slot); + if (status == 0) { /* if we're in nonblocking mode, exit immediately */ if (file->f_flags & O_NONBLOCK) @@ -1829,7 +1860,8 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, return -EINVAL; /* initialise the system data */ - if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) { + ca = kzalloc(sizeof(*ca), GFP_KERNEL); + if (!ca) { ret = -ENOMEM; goto exit; } @@ -1837,7 +1869,9 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ca->pub = pubca; ca->flags = flags; ca->slot_count = slot_count; - if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) { + ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), + GFP_KERNEL); + if (!ca->slot_info) { ret = -ENOMEM; goto free_ca; } -- cgit v1.2.3 From a75aa90c7c2fd82793efca1d300fd9bad766c02d Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:07 -0400 Subject: media: dvb_ca_en50221: Used a helper variable Used a helper variable "struct dvb_ca_slot *sl" instead of "ca->slot_info[slot]". This reduces the line length and simplifies code reading. Fixed also "-strict" checks in this patch: - Comparison to NULL written as "!". Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 187 ++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index d06cdc7a0a2b..7207ff596b92 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -234,13 +234,14 @@ static char *findstr(char *haystack, int hlen, char *needle, int nlen) */ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int slot_status; int cam_present_now; int cam_changed; /* IRQ mode */ if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) { - return (atomic_read(&ca->slot_info[slot].camchange_count) != 0); + return (atomic_read(&sl->camchange_count) != 0); } /* poll mode */ @@ -249,22 +250,23 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0; cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0; if (!cam_changed) { - int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE); + int cam_present_old = (sl->slot_state != DVB_CA_SLOTSTATE_NONE); + cam_changed = (cam_present_now != cam_present_old); } if (cam_changed) { if (!cam_present_now) { - ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; + sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; } else { - ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED; + sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED; } - atomic_set(&ca->slot_info[slot].camchange_count, 1); + atomic_set(&sl->camchange_count, 1); } else { - if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) && + if ((sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) && (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) { // move to validate state if reset is completed - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE; + sl->slot_state = DVB_CA_SLOTSTATE_VALIDATE; } } @@ -333,6 +335,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, */ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int ret; int buf_size; u8 buf[2]; @@ -340,13 +343,13 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) dprintk("%s\n", __func__); /* we'll be determining these during this function */ - ca->slot_info[slot].da_irq_supported = 0; + sl->da_irq_supported = 0; /* * set the host link buffer size temporarily. it will be overwritten * with the real negotiated size later. */ - ca->slot_info[slot].link_buf_size = 2; + sl->link_buf_size = 2; /* read the buffer size from the CAM */ ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, @@ -367,7 +370,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) buf_size = (buf[0] << 8) | buf[1]; if (buf_size > HOST_LINK_BUF_SIZE) buf_size = HOST_LINK_BUF_SIZE; - ca->slot_info[slot].link_buf_size = buf_size; + sl->link_buf_size = buf_size; buf[0] = buf_size >> 8; buf[1] = buf_size & 0xff; dprintk("Chosen link buffer size of %i\n", buf_size); @@ -459,6 +462,7 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, */ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) { + struct dvb_ca_slot *sl; int address = 0; int tuple_length; int tuple_type; @@ -531,10 +535,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) rasz = tuple[0] & 3; if (tuple_length < (3 + rasz + 14)) return -EINVAL; - ca->slot_info[slot].config_base = 0; - for (i = 0; i < rasz + 1; i++) { - ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i)); - } + sl = &ca->slot_info[slot]; + sl->config_base = 0; + for (i = 0; i < rasz + 1; i++) + sl->config_base |= (tuple[2 + i] << (8 * i)); /* check it contains the correct DVB string */ dvb_str = findstr((char *)tuple, tuple_length, "DVB_CI_V", 8); @@ -568,7 +572,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) break; /* get the config option */ - ca->slot_info[slot].config_option = tuple[0] & 0x3f; + sl->config_option = tuple[0] & 0x3f; /* OK, check it contains the correct strings */ if (!findstr((char *)tuple, tuple_length, @@ -598,8 +602,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) return -EINVAL; dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n", - manfid, devid, ca->slot_info[slot].config_base, - ca->slot_info[slot].config_option); + manfid, devid, sl->config_base, sl->config_option); // success! return 0; @@ -614,19 +617,20 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) */ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int configoption; dprintk("%s\n", __func__); /* set the config option */ - ca->pub->write_attribute_mem(ca->pub, slot, - ca->slot_info[slot].config_base, - ca->slot_info[slot].config_option); + ca->pub->write_attribute_mem(ca->pub, slot, sl->config_base, + sl->config_option); /* check it */ - configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base); + configoption = ca->pub->read_attribute_mem(ca->pub, slot, + sl->config_base); dprintk("Set configoption 0x%x, read configoption 0x%x\n", - ca->slot_info[slot].config_option, configoption & 0x3f); + sl->config_option, configoption & 0x3f); /* fine! */ return 0; @@ -651,6 +655,7 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 *ebuf, int ecount) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int bytes_read; int status; u8 buf[HOST_LINK_BUF_SIZE]; @@ -662,13 +667,13 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, if (ebuf == NULL) { int buf_free; - if (ca->slot_info[slot].rx_buffer.data == NULL) { + if (!sl->rx_buffer.data) { status = -EIO; goto exit; } - buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer); + buf_free = dvb_ringbuffer_free(&sl->rx_buffer); - if (buf_free < (ca->slot_info[slot].link_buf_size + + if (buf_free < (sl->link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) { status = -EAGAIN; goto exit; @@ -676,7 +681,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, } if (ca->pub->read_data && - (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) { + (sl->slot_state != DVB_CA_SLOTSTATE_LINKINIT)) { if (ebuf == NULL) status = ca->pub->read_data(ca->pub, slot, buf, sizeof(buf)); @@ -714,20 +719,18 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, /* check it will fit */ if (ebuf == NULL) { - if (bytes_read > ca->slot_info[slot].link_buf_size) { + if (bytes_read > sl->link_buf_size) { pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n", ca->dvbdev->adapter->num, bytes_read, - ca->slot_info[slot].link_buf_size); - ca->slot_info[slot].slot_state = - DVB_CA_SLOTSTATE_LINKINIT; + sl->link_buf_size); + sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } if (bytes_read < 2) { pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n", ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = - DVB_CA_SLOTSTATE_LINKINIT; + sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } @@ -758,8 +761,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, if (status < 0) goto exit; if (status & STATUSREG_RE) { - ca->slot_info[slot].slot_state = - DVB_CA_SLOTSTATE_LINKINIT; + sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } @@ -767,11 +769,11 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, /* OK, add it to the receive buffer, or copy into external buffer if supplied */ if (ebuf == NULL) { - if (ca->slot_info[slot].rx_buffer.data == NULL) { + if (!sl->rx_buffer.data) { status = -EIO; goto exit; } - dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read); + dvb_ringbuffer_pkt_write(&sl->rx_buffer, buf, bytes_read); } else { memcpy(ebuf, buf, bytes_read); } @@ -805,6 +807,7 @@ exit: static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 *buf, int bytes_write) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int status; int i; @@ -812,11 +815,11 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, /* sanity check */ - if (bytes_write > ca->slot_info[slot].link_buf_size) + if (bytes_write > sl->link_buf_size) return -EINVAL; if (ca->pub->write_data && - (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) + (sl->slot_state != DVB_CA_SLOTSTATE_LINKINIT)) return ca->pub->write_data(ca->pub, slot, buf, bytes_write); /* @@ -898,7 +901,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, if (status < 0) goto exit; if (status & STATUSREG_WE) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; + sl->slot_state = DVB_CA_SLOTSTATE_LINKINIT; status = -EIO; goto exit; } @@ -956,6 +959,7 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) { struct dvb_ca_private *ca = pubca->private; + struct dvb_ca_slot *sl = &ca->slot_info[slot]; dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type); @@ -968,8 +972,8 @@ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int ch return; } - ca->slot_info[slot].camchange_type = change_type; - atomic_inc(&ca->slot_info[slot].camchange_count); + sl->camchange_type = change_type; + atomic_inc(&sl->camchange_count); dvb_ca_en50221_thread_wakeup(ca); } EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); @@ -984,11 +988,12 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) { struct dvb_ca_private *ca = pubca->private; + struct dvb_ca_slot *sl = &ca->slot_info[slot]; dprintk("CAMREADY IRQ slot:%i\n", slot); - if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE; + if (sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) { + sl->slot_state = DVB_CA_SLOTSTATE_VALIDATE; dvb_ca_en50221_thread_wakeup(ca); } } @@ -1004,16 +1009,17 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq); void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) { struct dvb_ca_private *ca = pubca->private; + struct dvb_ca_slot *sl = &ca->slot_info[slot]; int flags; dprintk("FR/DA IRQ slot:%i\n", slot); - switch (ca->slot_info[slot].slot_state) { + switch (sl->slot_state) { case DVB_CA_SLOTSTATE_LINKINIT: flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS); if (flags & STATUSREG_DA) { dprintk("CAM supports DA IRQ\n"); - ca->slot_info[slot].da_irq_supported = 1; + sl->da_irq_supported = 1; } break; @@ -1059,7 +1065,9 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) * call might take several hundred milliseconds until timeout! */ for (slot = 0; slot < ca->slot_count; slot++) { - switch (ca->slot_info[slot].slot_state) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; + + switch (sl->slot_state) { default: case DVB_CA_SLOTSTATE_NONE: delay = HZ * 60; /* 60s */ @@ -1085,7 +1093,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) delay = HZ / 10; /* 100ms */ if (ca->open) { - if ((!ca->slot_info[slot].da_irq_supported) || + if ((!sl->da_irq_supported) || (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) delay = HZ / 10; /* 100ms */ } @@ -1374,15 +1382,17 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file, switch (cmd) { case CA_RESET: for (slot = 0; slot < ca->slot_count; slot++) { - mutex_lock(&ca->slot_info[slot].slot_lock); - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) { + struct dvb_ca_slot *sl = &ca->slot_info[slot]; + + mutex_lock(&sl->slot_lock); + if (sl->slot_state != DVB_CA_SLOTSTATE_NONE) { dvb_ca_en50221_slot_shutdown(ca, slot); if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) dvb_ca_en50221_camchange_irq(ca->pub, slot, DVB_CA_EN50221_CAMCHANGE_INSERTED); } - mutex_unlock(&ca->slot_info[slot].slot_lock); + mutex_unlock(&sl->slot_lock); } ca->next_read_slot = 0; dvb_ca_en50221_thread_wakeup(ca); @@ -1400,21 +1410,23 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file, case CA_GET_SLOT_INFO: { struct ca_slot_info *info = parg; + struct dvb_ca_slot *sl; - if ((info->num > ca->slot_count) || (info->num < 0)) { + slot = info->num; + if ((slot > ca->slot_count) || (slot < 0)) { err = -EINVAL; goto out_unlock; } info->type = CA_CI_LINK; info->flags = 0; - if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE) - && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) { + sl = &ca->slot_info[slot]; + if ((sl->slot_state != DVB_CA_SLOTSTATE_NONE) && + (sl->slot_state != DVB_CA_SLOTSTATE_INVALID)) { info->flags = CA_CI_MODULE_PRESENT; } - if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) { + if (sl->slot_state == DVB_CA_SLOTSTATE_RUNNING) info->flags |= CA_CI_MODULE_READY; - } break; } @@ -1462,6 +1474,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, { struct dvb_device *dvbdev = file->private_data; struct dvb_ca_private *ca = dvbdev->priv; + struct dvb_ca_slot *sl; u8 slot, connection_id; int status; u8 fragbuf[HOST_LINK_BUF_SIZE]; @@ -1483,14 +1496,15 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, return -EFAULT; buf += 2; count -= 2; + sl = &ca->slot_info[slot]; /* check if the slot is actually running */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) + if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING) return -EINVAL; /* fragment the packets & store in the buffer */ while (fragpos < count) { - fraglen = ca->slot_info[slot].link_buf_size - 2; + fraglen = sl->link_buf_size - 2; if (fraglen < 0) break; if (fraglen > HOST_LINK_BUF_SIZE - 2) @@ -1510,14 +1524,14 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, written = 0; while (!time_after(jiffies, timeout)) { /* check the CAM hasn't been removed/reset in the meantime */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) { + if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING) { status = -EIO; goto exit; } - mutex_lock(&ca->slot_info[slot].slot_lock); + mutex_lock(&sl->slot_lock); status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2); - mutex_unlock(&ca->slot_info[slot].slot_lock); + mutex_unlock(&sl->slot_lock); if (status == (fraglen + 2)) { written = 1; break; @@ -1557,16 +1571,17 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, slot = ca->next_read_slot; while ((slot_count < ca->slot_count) && (!found)) { - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) + struct dvb_ca_slot *sl = &ca->slot_info[slot]; + + if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING) goto nextslot; - if (ca->slot_info[slot].rx_buffer.data == NULL) { + if (!sl->rx_buffer.data) return 0; - } - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); + idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, -1, &fraglen); while (idx != -1) { - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); + dvb_ringbuffer_pkt_read(&sl->rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { @@ -1575,7 +1590,8 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, break; } - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen); + idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, idx, + &fraglen); } nextslot: @@ -1603,6 +1619,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, { struct dvb_device *dvbdev = file->private_data; struct dvb_ca_private *ca = dvbdev->priv; + struct dvb_ca_slot *sl; int status; int result = 0; u8 hdr[2]; @@ -1639,7 +1656,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, return status; } - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); + sl = &ca->slot_info[slot]; + idx = dvb_ringbuffer_pkt_next(&sl->rx_buffer, -1, &fraglen); pktlen = 2; do { if (idx == -1) { @@ -1649,7 +1667,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, goto exit; } - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); + dvb_ringbuffer_pkt_read(&sl->rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if (hdr[0] == connection_id) { @@ -1660,10 +1678,14 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, fraglen -= 2; } - if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2, - buf + pktlen, fraglen)) < 0) { + status = + dvb_ringbuffer_pkt_read_user(&sl->rx_buffer, + idx, 2, + buf + pktlen, + fraglen); + if (status < 0) goto exit; - } + pktlen += fraglen; } @@ -1672,9 +1694,9 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, dispose = 1; } - idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen); + idx2 = dvb_ringbuffer_pkt_next(&sl->rx_buffer, idx, &fraglen); if (dispose) - dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx); + dvb_ringbuffer_pkt_dispose(&sl->rx_buffer, idx); idx = idx2; dispose = 0; } while (!last_fragment); @@ -1720,15 +1742,16 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) } for (i = 0; i < ca->slot_count; i++) { + struct dvb_ca_slot *sl = &ca->slot_info[i]; - if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) { - if (ca->slot_info[i].rx_buffer.data != NULL) { + if (sl->slot_state == DVB_CA_SLOTSTATE_RUNNING) { + if (!sl->rx_buffer.data) { /* * it is safe to call this here without locks * because ca->open == 0. Data is not read in * this case */ - dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer); + dvb_ringbuffer_flush(&sl->rx_buffer); } } } @@ -1888,11 +1911,13 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, /* now initialise each slot */ for (i = 0; i < slot_count; i++) { - memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot)); - ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE; - atomic_set(&ca->slot_info[i].camchange_count, 0); - ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; - mutex_init(&ca->slot_info[i].slot_lock); + struct dvb_ca_slot *sl = &ca->slot_info[i]; + + memset(sl, 0, sizeof(struct dvb_ca_slot)); + sl->slot_state = DVB_CA_SLOTSTATE_NONE; + atomic_set(&sl->camchange_count, 0); + sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; + mutex_init(&sl->slot_lock); } mutex_init(&ca->ioctl_mutex); -- cgit v1.2.3 From fbabbddd64236e88e7302cff7c20e066a211d82a Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:08 -0400 Subject: media: dvb_ca_en50221: Added line breaks Fixed all: WARNING: Missing a blank line after declarations Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 7207ff596b92..678bd6a91edc 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -178,7 +178,9 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca) static void dvb_ca_private_release(struct kref *ref) { - struct dvb_ca_private *ca = container_of(ref, struct dvb_ca_private, refcount); + struct dvb_ca_private *ca; + + ca = container_of(ref, struct dvb_ca_private, refcount); dvb_ca_private_free(ca); } @@ -297,8 +299,10 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, start = jiffies; timeout = jiffies + timeout_hz; while (1) { + int res; + /* read the status and check for error */ - int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); + res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); if (res < 0) return -EIO; -- cgit v1.2.3 From 7bd8cc8fff3d487f8806f352d06aebe56d87481f Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:09 -0400 Subject: media: dvb_ca_en50221: Removed useless braces Fixed all: WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 678bd6a91edc..ce22bdbfc765 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -242,9 +242,8 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) int cam_changed; /* IRQ mode */ - if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) { + if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) return (atomic_read(&sl->camchange_count) != 0); - } /* poll mode */ slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open); @@ -258,11 +257,10 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) } if (cam_changed) { - if (!cam_present_now) { + if (!cam_present_now) sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; - } else { + else sl->camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED; - } atomic_set(&sl->camchange_count, 1); } else { if ((sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) && @@ -314,9 +312,8 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, } /* check for timeout */ - if (time_after(jiffies, timeout)) { + if (time_after(jiffies, timeout)) break; - } /* wait for a bit */ usleep_range(1000, 1100); @@ -786,9 +783,9 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, buf[0], (buf[1] & 0x80) == 0, bytes_read); /* wake up readers when a last_fragment is received */ - if ((buf[1] & 0x80) == 0x00) { + if ((buf[1] & 0x80) == 0x00) wake_up_interruptible(&ca->wait_queue); - } + status = bytes_read; exit: @@ -1676,11 +1673,10 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, connection_id = hdr[0]; if (hdr[0] == connection_id) { if (pktlen < count) { - if ((pktlen + fraglen - 2) > count) { + if ((pktlen + fraglen - 2) > count) fraglen = count - pktlen; - } else { + else fraglen -= 2; - } status = dvb_ringbuffer_pkt_read_user(&sl->rx_buffer, @@ -1818,9 +1814,8 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait) dprintk("%s\n", __func__); - if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) { + if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) mask |= POLLIN; - } /* if there is something, return now */ if (mask) @@ -1829,9 +1824,8 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait) /* wait for something to happen */ poll_wait(file, &ca->wait_queue, wait); - if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) { + if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) mask |= POLLIN; - } return mask; } @@ -1973,9 +1967,9 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) /* shutdown the thread if there was one */ kthread_stop(ca->thread); - for (i = 0; i < ca->slot_count; i++) { + for (i = 0; i < ca->slot_count; i++) dvb_ca_en50221_slot_shutdown(ca, i); - } + dvb_remove_device(ca->dvbdev); dvb_ca_private_put(ca); pubca->private = NULL; -- cgit v1.2.3 From 5567d09d2a2d154f4a946304d6d73d4e49080046 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:10 -0400 Subject: media: dvb_ca_en50221: Removed unused symbol - The STATUSREG_TXERR definition is not used and it has style problems, too. Removing it seems to solve both issues. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index ce22bdbfc765..6547f6eb8cf4 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -76,8 +76,6 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages"); #define STATUSREG_WE 2 /* write error */ #define STATUSREG_FR 0x40 /* module free */ #define STATUSREG_DA 0x80 /* data available */ -#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */ - #define DVB_CA_SLOTSTATE_NONE 0 #define DVB_CA_SLOTSTATE_UNINITIALISED 1 -- cgit v1.2.3 From 224457a991c12d27eb9e893f4c4d40bf533466c1 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:11 -0400 Subject: media: dvb_ca_en50221: Fixed C++ comments - Changed all C++ style comments ("// ..") to C style ones ("/* .. */"). Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 6547f6eb8cf4..99cf460b8448 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -263,7 +263,7 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) } else { if ((sl->slot_state == DVB_CA_SLOTSTATE_WAITREADY) && (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) { - // move to validate state if reset is completed + /* move to validate state if reset is completed */ sl->slot_state = DVB_CA_SLOTSTATE_VALIDATE; } } @@ -442,7 +442,7 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, } _address += (_tuple_length * 2); - // success + /* success */ *tuple_type = _tuple_type; *tuple_length = _tuple_length; *address = _address; @@ -476,7 +476,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) u16 devid = 0; - // CISTPL_DEVICE_0A + /* CISTPL_DEVICE_0A */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); if (status < 0) @@ -486,7 +486,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) - // CISTPL_DEVICE_0C + /* CISTPL_DEVICE_0C */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); if (status < 0) @@ -496,7 +496,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) - // CISTPL_VERS_1 + /* CISTPL_VERS_1 */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); if (status < 0) @@ -506,7 +506,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) - // CISTPL_MANFID + /* CISTPL_MANFID */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); if (status < 0) @@ -520,7 +520,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) - // CISTPL_CONFIG + /* CISTPL_CONFIG */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); if (status < 0) @@ -562,7 +562,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) if (status < 0) return status; switch (tuple_type) { - case 0x1B: // CISTPL_CFTABLE_ENTRY + case 0x1B: /* CISTPL_CFTABLE_ENTRY */ if (tuple_length < (2 + 11 + 17)) break; @@ -583,10 +583,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) got_cftableentry = 1; break; - case 0x14: // CISTPL_NO_LINK + case 0x14: /* CISTPL_NO_LINK */ break; - case 0xFF: // CISTPL_END + case 0xFF: /* CISTPL_END */ end_chain = 1; break; @@ -603,7 +603,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n", manfid, devid, sl->config_base, sl->config_option); - // success! + /* success! */ return 0; } -- cgit v1.2.3 From 96375b7a7046f8d06d773d561c978472cf4b4e8c Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:12 -0400 Subject: media: dvb_ca_en50221: Fixed 80 char limit Fixed most of: WARNING: line over 80 characters The remaining lines are printk strings, which should not be split and lines where I thing they should stay as they are. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 57 +++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 99cf460b8448..8c0c730bfdb3 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -155,7 +155,10 @@ struct dvb_ca_private { /* Delay the main thread should use */ unsigned long delay; - /* Slot to start looking for data to read from in the next user-space read operation */ + /* + * Slot to start looking for data to read from in the next user-space + * read operation + */ int next_read_slot; /* mutex serializing ioctls */ @@ -225,7 +228,7 @@ static char *findstr(char *haystack, int hlen, char *needle, int nlen) -/* ******************************************************************************** */ +/* ************************************************************************** */ /* EN50221 physical interface functions */ @@ -365,7 +368,10 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) if (ret) return ret; - /* store it, and choose the minimum of our buffer and the CAM's buffer size */ + /* + * store it, and choose the minimum of our buffer and the CAM's buffer + * size + */ buf_size = (buf[0] << 8) | buf[1]; if (buf_size > HOST_LINK_BUF_SIZE) buf_size = HOST_LINK_BUF_SIZE; @@ -435,7 +441,8 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, /* read in the whole tuple */ for (i = 0; i < _tuple_length; i++) { - tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2)); + tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, + _address + (i * 2)); dprintk(" 0x%02x: 0x%02x %c\n", i, tuple[i] & 0xff, ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.'); @@ -590,7 +597,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) end_chain = 1; break; - default: /* Unknown tuple type - just skip this tuple and move to the next one */ + default: /* Unknown tuple type - just skip this tuple */ dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tuple_type, tuple_length); break; @@ -766,7 +773,10 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, } } - /* OK, add it to the receive buffer, or copy into external buffer if supplied */ + /* + * OK, add it to the receive buffer, or copy into external buffer if + * supplied + */ if (ebuf == NULL) { if (!sl->rx_buffer.data) { status = -EIO; @@ -918,7 +928,7 @@ exitnowrite: -/* ******************************************************************************** */ +/* ************************************************************************** */ /* EN50221 higher level functions */ @@ -955,7 +965,8 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) * @slot: Slot concerned. * @change_type: One of the DVB_CA_CAMCHANGE_* values. */ -void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) +void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, + int change_type) { struct dvb_ca_private *ca = pubca->private; struct dvb_ca_slot *sl = &ca->slot_info[slot]; @@ -1031,7 +1042,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); -/* ******************************************************************************** */ +/* ************************************************************************** */ /* EN50221 thread functions */ /** @@ -1351,7 +1362,7 @@ static int dvb_ca_en50221_thread(void *data) -/* ******************************************************************************** */ +/* ************************************************************************** */ /* EN50221 IO interface functions */ /** @@ -1484,7 +1495,10 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, dprintk("%s\n", __func__); - /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ + /* + * Incoming packet has a 2 byte header. + * hdr[0] = slot_id, hdr[1] = connection_id + */ if (count < 2) return -EINVAL; @@ -1522,14 +1536,18 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, timeout = jiffies + HZ / 2; written = 0; while (!time_after(jiffies, timeout)) { - /* check the CAM hasn't been removed/reset in the meantime */ + /* + * check the CAM hasn't been removed/reset in the + * meantime + */ if (sl->slot_state != DVB_CA_SLOTSTATE_RUNNING) { status = -EIO; goto exit; } mutex_lock(&sl->slot_lock); - status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2); + status = dvb_ca_en50221_write_data(ca, slot, fragbuf, + fraglen + 2); mutex_unlock(&sl->slot_lock); if (status == (fraglen + 2)) { written = 1; @@ -1583,7 +1601,8 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, dvb_ringbuffer_pkt_read(&sl->rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; - if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { + if ((hdr[0] == connection_id) && + ((hdr[1] & 0x80) == 0)) { *_slot = slot; found = 1; break; @@ -1632,7 +1651,10 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, dprintk("%s\n", __func__); - /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ + /* + * Outgoing packet has a 2 byte header. + * hdr[0] = slot_id, hdr[1] = connection_id + */ if (count < 2) return -EINVAL; @@ -1852,7 +1874,7 @@ static const struct dvb_device dvbdev_ca = { .fops = &dvb_ca_fops, }; -/* ******************************************************************************** */ +/* ************************************************************************** */ /* Initialisation/shutdown functions */ @@ -1901,7 +1923,8 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, pubca->private = ca; /* register the DVB device */ - ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0); + ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, + DVB_DEVICE_CA, 0); if (ret) goto free_slot_info; -- cgit v1.2.3 From 4ecb4bfc84f69c27c96289a596d4958adea36573 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:13 -0400 Subject: media: dvb_ca_en50221: Fixed typo - "dont" -> "don't" Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 8c0c730bfdb3..aba80d8be3a7 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1304,7 +1304,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, */ if (dvb_ca_en50221_check_camstatus(ca, slot)) { /* - * we dont want to sleep on the next iteration + * we don't want to sleep on the next iteration * so we can handle the cam change */ ca->wakeup = 1; @@ -1314,7 +1314,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, /* check if we've hit our limit this time */ if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) { /* - * dont sleep; there is likely to be more data + * don't sleep; there is likely to be more data * to read */ ca->wakeup = 1; -- cgit v1.2.3 From 82ec19e4dfdd8258b6c960d052dfde0275641f16 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:14 -0400 Subject: media: dvb_ca_en50221: Fix again wrong EXPORT_SYMBOL order Some EXPORT_SYMBOL() on this file don't match the name of functions that precedes them. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index aba80d8be3a7..26198228a14e 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1849,7 +1849,6 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait) return mask; } -EXPORT_SYMBOL(dvb_ca_en50221_init); static const struct file_operations dvb_ca_fops = { @@ -1968,8 +1967,7 @@ exit: pubca->private = NULL; return ret; } -EXPORT_SYMBOL(dvb_ca_en50221_release); - +EXPORT_SYMBOL(dvb_ca_en50221_init); /** @@ -1995,3 +1993,4 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) dvb_ca_private_put(ca); pubca->private = NULL; } +EXPORT_SYMBOL(dvb_ca_en50221_release); -- cgit v1.2.3 From dc32f3244a6ccfa3aebb848fc1e094f15010009e Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:15 -0400 Subject: media: dvb_ca_en50221: Fixed remaining block comments - Added the missing opening empty comment line. Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 26198228a14e..24e2b0c86ada 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1071,7 +1071,8 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) int curdelay = 100000000; int slot; - /* Beware of too high polling frequency, because one polling + /* + * Beware of too high polling frequency, because one polling * call might take several hundred milliseconds until timeout! */ for (slot = 0; slot < ca->slot_count; slot++) { -- cgit v1.2.3 From 13b516484492c0ee0c7875ed774470c71f77cce0 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:16 -0400 Subject: media: dvb_ca_en50221: Fixed style issues on the whole file - Running "checkpatch.pl -strict -f ..." gave more checks to fix. * Blank lines aren't necessary after an open brace '{' * Comparison to NULL written as "!" * CHECK: Blank lines aren't necessary before a close brace '}' Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 24e2b0c86ada..fa5f5efa657c 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -89,7 +89,6 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages"); /* Information on a CA slot */ struct dvb_ca_slot { - /* current state of the CAM */ int slot_state; @@ -548,7 +547,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) /* check it contains the correct DVB string */ dvb_str = findstr((char *)tuple, tuple_length, "DVB_CI_V", 8); - if (dvb_str == NULL) + if (!dvb_str) return -EINVAL; if (tuple_length < ((dvb_str - (char *)tuple) + 12)) return -EINVAL; @@ -640,7 +639,6 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) /* fine! */ return 0; - } @@ -670,7 +668,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, dprintk("%s\n", __func__); /* check if we have space for a link buf in the rx_buffer */ - if (ebuf == NULL) { + if (!ebuf) { int buf_free; if (!sl->rx_buffer.data) { @@ -688,7 +686,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, if (ca->pub->read_data && (sl->slot_state != DVB_CA_SLOTSTATE_LINKINIT)) { - if (ebuf == NULL) + if (!ebuf) status = ca->pub->read_data(ca->pub, slot, buf, sizeof(buf)); else @@ -699,7 +697,6 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, if (status == 0) goto exit; } else { - /* check if there is data available */ status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); @@ -724,7 +721,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, bytes_read |= status; /* check it will fit */ - if (ebuf == NULL) { + if (!ebuf) { if (bytes_read > sl->link_buf_size) { pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n", ca->dvbdev->adapter->num, bytes_read, @@ -777,7 +774,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, * OK, add it to the receive buffer, or copy into external buffer if * supplied */ - if (ebuf == NULL) { + if (!ebuf) { if (!sl->rx_buffer.data) { status = -EIO; goto exit; @@ -1052,7 +1049,6 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); */ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) { - dprintk("%s\n", __func__); ca->wakeup = 1; @@ -1662,7 +1658,6 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf, /* wait for some data */ status = dvb_ca_en50221_io_read_condition(ca, &result, &slot); if (status == 0) { - /* if we're in nonblocking mode, exit immediately */ if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; -- cgit v1.2.3 From 7011050438be981f12b7d4f73d721ca5d4441cc8 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Sat, 15 Jul 2017 20:43:17 -0400 Subject: media: dvb_ca_en50221: Fixed multiple blank lines - Running "checkpatch.pl -strict -f ..." complained * Please don't use multiple blank lines Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 40 --------------------------------- 1 file changed, 40 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index fa5f5efa657c..95b3723282f4 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -86,7 +86,6 @@ MODULE_PARM_DESC(cam_debug, "enable verbose debug messages"); #define DVB_CA_SLOTSTATE_WAITFR 6 #define DVB_CA_SLOTSTATE_LINKINIT 7 - /* Information on a CA slot */ struct dvb_ca_slot { /* current state of the CAM */ @@ -200,7 +199,6 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 *ebuf, int ecount); - /** * Safely find needle in haystack. * @@ -225,12 +223,9 @@ static char *findstr(char *haystack, int hlen, char *needle, int nlen) return NULL; } - - /* ************************************************************************** */ /* EN50221 physical interface functions */ - /** * dvb_ca_en50221_check_camstatus - Check CAM status. */ @@ -273,7 +268,6 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) return cam_changed; } - /** * dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS * register on a CAM interface, checking for errors and timeout. @@ -325,7 +319,6 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, return -ETIMEDOUT; } - /** * dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM. * @@ -455,7 +448,6 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, return 0; } - /** * dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module, * extracting Config register, and checking it is a DVB CAM module. @@ -481,7 +473,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) u16 manfid = 0; u16 devid = 0; - /* CISTPL_DEVICE_0A */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); @@ -490,8 +481,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) if (tuple_type != 0x1D) return -EINVAL; - - /* CISTPL_DEVICE_0C */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); @@ -500,8 +489,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) if (tuple_type != 0x1C) return -EINVAL; - - /* CISTPL_VERS_1 */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); @@ -510,8 +497,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) if (tuple_type != 0x15) return -EINVAL; - - /* CISTPL_MANFID */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); @@ -524,8 +509,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) manfid = (tuple[1] << 8) | tuple[0]; devid = (tuple[3] << 8) | tuple[2]; - - /* CISTPL_CONFIG */ status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tuple_type, &tuple_length, tuple); @@ -613,7 +596,6 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) return 0; } - /** * dvb_ca_en50221_set_configoption - Set CAM's configoption correctly. * @@ -641,7 +623,6 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) return 0; } - /** * dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control * interface. It reads a buffer of data from the CAM. The data can either @@ -797,7 +778,6 @@ exit: return status; } - /** * dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control * interface. It writes a buffer of data to a CAM. @@ -819,7 +799,6 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, dprintk("%s\n", __func__); - /* sanity check */ if (bytes_write > sl->link_buf_size) return -EINVAL; @@ -923,12 +902,9 @@ exitnowrite: return status; } - - /* ************************************************************************** */ /* EN50221 higher level functions */ - /** * dvb_ca_en50221_slot_shutdown - A CAM has been removed => shut it down. * @@ -954,7 +930,6 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) return 0; } - /** * dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred. * @@ -985,7 +960,6 @@ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, } EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); - /** * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred. * @@ -1006,7 +980,6 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) } EXPORT_SYMBOL(dvb_ca_en50221_camready_irq); - /** * dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred. * @@ -1038,7 +1011,6 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) } EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); - /* ************************************************************************** */ /* EN50221 thread functions */ @@ -1357,8 +1329,6 @@ static int dvb_ca_en50221_thread(void *data) return 0; } - - /* ************************************************************************** */ /* EN50221 IO interface functions */ @@ -1447,7 +1417,6 @@ out_unlock: return err; } - /** * Wrapper for ioctl implementation. * @@ -1464,7 +1433,6 @@ static long dvb_ca_en50221_io_ioctl(struct file *file, return dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl); } - /** * Implementation of write() syscall. * @@ -1568,7 +1536,6 @@ exit: return status; } - /** * Condition for waking up in dvb_ca_en50221_io_read_condition */ @@ -1618,7 +1585,6 @@ nextslot: return found; } - /** * Implementation of read() syscall. * @@ -1730,7 +1696,6 @@ exit: return status; } - /** * Implementation of file open syscall. * @@ -1781,7 +1746,6 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) return 0; } - /** * Implementation of file close syscall. * @@ -1811,7 +1775,6 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) return err; } - /** * Implementation of poll() syscall. * @@ -1846,7 +1809,6 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait) return mask; } - static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_en50221_io_read, @@ -1872,7 +1834,6 @@ static const struct dvb_device dvbdev_ca = { /* ************************************************************************** */ /* Initialisation/shutdown functions */ - /** * Initialise a new DVB CA EN50221 interface device. * @@ -1965,7 +1926,6 @@ exit: } EXPORT_SYMBOL(dvb_ca_en50221_init); - /** * Release a DVB CA EN50221 interface device. * -- cgit v1.2.3 From faafd9e70ec73eca5acec3b633efc69142de57e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jul 2017 15:46:10 -0400 Subject: media: dvb_ca_en50221.h: fix checkpatch strict warnings As we're already touching on dvb_ca_en50221 to cleanup checkpatch issues, do that also for its header file, with: $ ./scripts/checkpatch.pl --strict --fix-inplace -f drivers/media/dvb-core/dvb_ca_en50221.h Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h index 82617bac0875..367687d2b41a 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.h +++ b/drivers/media/dvb-core/dvb_ca_en50221.h @@ -69,9 +69,9 @@ struct dvb_ca_en50221 { int slot, u8 address, u8 value); int (*read_data)(struct dvb_ca_en50221 *ca, - int slot, u8 *ebuf, int ecount); + int slot, u8 *ebuf, int ecount); int (*write_data)(struct dvb_ca_en50221 *ca, - int slot, u8 *ebuf, int ecount); + int slot, u8 *ebuf, int ecount); int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot); int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot); @@ -128,8 +128,8 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *ca, int slot); * * @return 0 on success, nonzero on failure */ -extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, - struct dvb_ca_en50221 *ca, int flags, +int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, + struct dvb_ca_en50221 *ca, int flags, int slot_count); /** @@ -137,6 +137,6 @@ extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, * * @ca: The associated dvb_ca instance. */ -extern void dvb_ca_en50221_release(struct dvb_ca_en50221 *ca); +void dvb_ca_en50221_release(struct dvb_ca_en50221 *ca); #endif -- cgit v1.2.3 From 06e4924644014db548f2241d44cb287c2ae58749 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 17 Jul 2017 04:56:47 -0400 Subject: media: venus: mark PM functions as __maybe_unused Without PM support, gcc warns about two unused functions: platform/qcom/venus/core.c:146:13: error: 'venus_clks_disable' defined but not used [-Werror=unused-function] platform/qcom/venus/core.c:126:12: error: 'venus_clks_enable' defined but not used [-Werror=unused-function] The problem as usual are incorrect #ifdefs, so the easiest fix is to do away with the #ifdef completely and mark the suspend/resume handlers as __maybe_unused, which they are. Fixes: af2c3834c8ca ("[media] media: venus: adding core part and helper functions") Signed-off-by: Arnd Bergmann Reviewed-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index d8cbe8549d97..47f79637938c 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -270,8 +270,7 @@ static int venus_remove(struct platform_device *pdev) return ret; } -#ifdef CONFIG_PM -static int venus_runtime_suspend(struct device *dev) +static __maybe_unused int venus_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); int ret; @@ -283,7 +282,7 @@ static int venus_runtime_suspend(struct device *dev) return ret; } -static int venus_runtime_resume(struct device *dev) +static __maybe_unused int venus_runtime_resume(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); int ret; @@ -302,7 +301,6 @@ err_clks_disable: venus_clks_disable(core); return ret; } -#endif static const struct dev_pm_ops venus_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -- cgit v1.2.3 From 0399b696f7f4ad4c48d59850d0e6adbed43c1d88 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 17 Jul 2017 04:56:49 -0400 Subject: media: venus: fix compile-test build on non-qcom ARM platform If QCOM_MDT_LOADER is enabled, but ARCH_QCOM is not, we run into a build error: ERROR: "qcom_mdt_load" [drivers/media/platform/qcom/venus/venus-core.ko] undefined! ERROR: "qcom_mdt_get_size" [drivers/media/platform/qcom/venus/venus-core.ko] undefined! This changes the 'select' statement again, so we only try to enable those symbols when the drivers will actually get built, and explicitly test for QCOM_MDT_LOADER to be enabled before calling into it. Fixes: 76724b30f222 ("[media] media: venus: enable building with COMPILE_TEST") Signed-off-by: Arnd Bergmann Reviewed-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 4 ++-- drivers/media/platform/qcom/venus/firmware.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 17cffff86454..0c741d12dbc9 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -476,8 +476,8 @@ config VIDEO_QCOM_VENUS tristate "Qualcomm Venus V4L2 encoder/decoder driver" depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST - select QCOM_MDT_LOADER if (ARM || ARM64) - select QCOM_SCM if (ARM || ARM64) + select QCOM_MDT_LOADER if ARCH_QCOM + select QCOM_SCM if ARCH_QCOM select VIDEOBUF2_DMA_SG select V4L2_MEM2MEM_DEV ---help--- diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 1b1a4f355918..1ede92300dd6 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -40,7 +40,7 @@ int venus_boot(struct device *parent, struct device *fw_dev, const char *fwname) void *mem_va; int ret; - if (!qcom_scm_is_available()) + if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) || !qcom_scm_is_available()) return -EPROBE_DEFER; fw_dev->parent = parent; -- cgit v1.2.3 From 9883dc2c4c0531e88fa0555dcc4438c3a1bc0df5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 17 Jul 2017 04:56:50 -0400 Subject: media: venus: hfi: fix error handling in hfi_sys_init_done() Not entirely sure what triggers it, but with venus build as kernel module and in initrd, we hit this crash: Unable to handle kernel paging request at virtual address ffff80003c039000 pgd = ffff00000a14f000 [ffff80003c039000] *pgd=00000000bd9f7003, *pud=00000000bd9f6003, *pmd=00000000bd9f0003, *pte=0000000000000000 Internal error: Oops: 96000007 [#1] SMP Modules linked in: qcom_wcnss_pil(E+) crc32_ce(E) qcom_common(E) venus_core(E+) remoteproc(E) snd_soc_msm8916_digital(E) virtio_ring(E) cdc_ether(E) snd_soc_lpass_apq8016(E) snd_soc_lpass_cpu(E) snd_soc_apq8016_sbc(E) snd_soc_lpass_platform(E) v4l2_mem2mem(E) virtio(E) snd_soc_core(E) ac97_bus(E) snd_pcm_dmaengine(E) snd_seq(E) leds_gpio(E) videobuf2_v4l2(E) videobuf2_core(E) snd_seq_device(E) snd_pcm(E) videodev(E) media(E) nvmem_qfprom(E) msm(E) snd_timer(E) snd(E) soundcore(E) spi_qup(E) mdt_loader(E) qcom_tsens(E) qcom_spmi_temp_alarm(E) nvmem_core(E) msm_rng(E) uas(E) usb_storage(E) dm9601(E) usbnet(E) mii(E) mmc_block(E) adv7511(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) fb_sys_fops(E) qcom_spmi_vadc(E) qcom_vadc_common(PE) industrialio(E) pinctrl_spmi_mpp(E) pinctrl_spmi_gpio(E) rtc_pm8xxx(E) clk_smd_rpm(E) sdhci_msm(E) sdhci_pltfm(E) qcom_smd_regulator(E) drm(E) smd_rpm(E) qcom_spmi_pmic(E) regmap_spmi(E) ci_hdrc_msm(E) ci_hdrc(E) usb3503(E) extcon_usb_gpio(E) phy_msm_usb(E) udc_core(E) qcom_hwspinlock(E) extcon_core(E) ehci_msm(E) i2c_qup(E) sdhci(E) mmc_core(E) spmi_pmic_arb(E) spmi(E) qcom_smd(E) smsm(E) rpmsg_core(E) smp2p(E) smem(E) hwspinlock_core(E) gpio_keys(E) CPU: 2 PID: 551 Comm: irq/150-venus Tainted: P E 4.12.0+ #1625 Hardware name: qualcomm dragonboard410c/dragonboard410c, BIOS 2017.07-rc2-00144-ga97bdbdf72-dirty 07/08/2017 task: ffff800037338000 task.stack: ffff800038e00000 PC is at hfi_sys_init_done+0x64/0x140 [venus_core] LR is at hfi_process_msg_packet+0xcc/0x1e8 [venus_core] pc : [] lr : [] pstate: 20400145 sp : ffff800038e03c60 x29: ffff800038e03c60 x28: 0000000000000000 x27: 00000000000df018 x26: ffff00000118f4d0 x25: 0000000000020003 x24: ffff80003a8d3010 x23: ffff00000118f760 x22: ffff800037b40028 x21: ffff8000382981f0 x20: ffff800037b40028 x19: ffff80003c039000 x18: 0000000000000020 x17: 0000000000000000 x16: ffff800037338000 x15: ffffffffffffffff x14: 0000001000000014 x13: 0000000100001007 x12: 0000000100000020 x11: 0000100e00000000 x10: 0000000000000001 x9 : 0000000200000000 x8 : 0000001400000001 x7 : 0000000000001010 x6 : 0000000000000148 x5 : 0000000000001009 x4 : ffff80003c039000 x3 : 00000000cd770abb x2 : 0000000000000042 x1 : 0000000000000788 x0 : 0000000000000002 Process irq/150-venus (pid: 551, stack limit = 0xffff800038e00000) Call trace: [] hfi_sys_init_done+0x64/0x140 [venus_core] [] hfi_process_msg_packet+0xcc/0x1e8 [venus_core] [] venus_isr_thread+0x1b4/0x208 [venus_core] [] hfi_isr_thread+0x28/0x38 [venus_core] [] irq_thread_fn+0x30/0x70 [] irq_thread+0x14c/0x1c8 [] kthread+0x138/0x140 [] ret_from_fork+0x10/0x40 Code: 52820125 52820207 7a431820 54000249 (b9400263) ---[ end trace c963460f20a984b6 ]--- The problem is that in the error case, we've incremented the data ptr but not decremented rem_bytes, and keep reading (presumably garbage) until eventually we go beyond the end of the buffer. Instead, on first error, we should probably just bail out. Other option is to increment read_bytes by sizeof(u32) before the switch, rather than only accounting for the ptype header in the non-error case. Note that in this case it is HFI_ERR_SYS_INVALID_PARAMETER, ie. an unrecognized/unsupported parameter, so interpreting the next word as a property type would be bogus. The other error cases are due to truncated buffer, so there isn't likely to be anything valid to interpret in the remainder of the buffer. So just bailing seems like a reasonable solution. Signed-off-by: Rob Clark Reviewed-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/hfi_msgs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index f8841713e417..a681ae5381d6 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -239,11 +239,12 @@ static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst, break; } - if (!error) { - rem_bytes -= read_bytes; - data += read_bytes; - num_properties--; - } + if (error) + break; + + rem_bytes -= read_bytes; + data += read_bytes; + num_properties--; } err_no_prop: -- cgit v1.2.3 From a6e2d36bf6b7e2f821ce89dc6e5fb9b4dfe2970c Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Wed, 19 Jul 2017 07:51:37 -0400 Subject: media: venus: don't abuse dma_alloc for non-DMA allocations In venus_boot(), we pass a pointer to a phys_addr_t into dmam_alloc_coherent, which the compiler warns about: platform/qcom/venus/firmware.c: In function 'venus_boot': platform/qcom/venus/firmware.c:63:49: error: passing argument 3 of 'dmam_alloc_coherent' from incompatible pointer type [-Werror=incompatible-pointer-types] To avoid the error refactor venus_boot function by discard dma_alloc_coherent invocation because we don't want to map the memory for the device. Something more, the usage of DMA mapping API is actually wrong and the current implementation relies on several bugs in DMA mapping code. When these bugs are fixed that will break firmware loading, so fix this now to avoid future troubles. The meaning of venus_boot is to copy the content of the firmware buffer into reserved (and memblock removed) block of memory and pass that physical address to the trusted zone for authentication and mapping through iommu form the secure world. After iommu mapping is done the iova is passed as ane entry point to the remote processor. After this change memory-region property is parsed manually and the physical address is memremap to CPU, call mdt_load to load firmware segments into proper places and unmap reserved memory. Fixes: af2c3834c8ca ("[media] media: venus: adding core part and helper functions") Signed-off-by: Stanimir Varbanov Reviewed-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.c | 10 ++-- drivers/media/platform/qcom/venus/core.h | 1 - drivers/media/platform/qcom/venus/firmware.c | 74 ++++++++++++---------------- drivers/media/platform/qcom/venus/firmware.h | 5 +- 4 files changed, 39 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 47f79637938c..41eef376eb2d 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -76,7 +76,7 @@ static void venus_sys_error_handler(struct work_struct *work) hfi_core_deinit(core, true); hfi_destroy(core); mutex_lock(&core->lock); - venus_shutdown(&core->dev_fw); + venus_shutdown(core->dev); pm_runtime_put_sync(core->dev); @@ -84,7 +84,7 @@ static void venus_sys_error_handler(struct work_struct *work) pm_runtime_get_sync(core->dev); - ret |= venus_boot(core->dev, &core->dev_fw, core->res->fwname); + ret |= venus_boot(core->dev, core->res->fwname); ret |= hfi_core_resume(core, true); @@ -207,7 +207,7 @@ static int venus_probe(struct platform_device *pdev) if (ret < 0) goto err_runtime_disable; - ret = venus_boot(dev, &core->dev_fw, core->res->fwname); + ret = venus_boot(dev, core->res->fwname); if (ret) goto err_runtime_disable; @@ -238,7 +238,7 @@ err_dev_unregister: err_core_deinit: hfi_core_deinit(core, false); err_venus_shutdown: - venus_shutdown(&core->dev_fw); + venus_shutdown(dev); err_runtime_disable: pm_runtime_set_suspended(dev); pm_runtime_disable(dev); @@ -259,7 +259,7 @@ static int venus_remove(struct platform_device *pdev) WARN_ON(ret); hfi_destroy(core); - venus_shutdown(&core->dev_fw); + venus_shutdown(dev); of_platform_depopulate(dev); pm_runtime_put_sync(dev); diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index e542700eee32..cba092bcb76d 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -101,7 +101,6 @@ struct venus_core { struct device *dev; struct device *dev_dec; struct device *dev_enc; - struct device dev_fw; struct mutex lock; struct list_head instances; atomic_t insts_count; diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 1ede92300dd6..521d4b36c090 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -12,29 +12,27 @@ * */ -#include +#include #include #include +#include #include -#include -#include +#include #include +#include #include #include "firmware.h" #define VENUS_PAS_ID 9 -#define VENUS_FW_MEM_SIZE SZ_8M +#define VENUS_FW_MEM_SIZE (6 * SZ_1M) -static void device_release_dummy(struct device *dev) -{ - of_reserved_mem_device_release(dev); -} - -int venus_boot(struct device *parent, struct device *fw_dev, const char *fwname) +int venus_boot(struct device *dev, const char *fwname) { const struct firmware *mdt; + struct device_node *node; phys_addr_t mem_phys; + struct resource r; ssize_t fw_size; size_t mem_size; void *mem_va; @@ -43,66 +41,58 @@ int venus_boot(struct device *parent, struct device *fw_dev, const char *fwname) if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) || !qcom_scm_is_available()) return -EPROBE_DEFER; - fw_dev->parent = parent; - fw_dev->release = device_release_dummy; + node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!node) { + dev_err(dev, "no memory-region specified\n"); + return -EINVAL; + } - ret = dev_set_name(fw_dev, "%s:%s", dev_name(parent), "firmware"); + ret = of_address_to_resource(node, 0, &r); if (ret) return ret; - ret = device_register(fw_dev); - if (ret < 0) - return ret; + mem_phys = r.start; + mem_size = resource_size(&r); - ret = of_reserved_mem_device_init_by_idx(fw_dev, parent->of_node, 0); - if (ret) - goto err_unreg_device; + if (mem_size < VENUS_FW_MEM_SIZE) + return -EINVAL; - mem_size = VENUS_FW_MEM_SIZE; - - mem_va = dmam_alloc_coherent(fw_dev, mem_size, &mem_phys, GFP_KERNEL); + mem_va = memremap(r.start, mem_size, MEMREMAP_WC); if (!mem_va) { - ret = -ENOMEM; - goto err_unreg_device; + dev_err(dev, "unable to map memory region: %pa+%zx\n", + &r.start, mem_size); + return -ENOMEM; } - ret = request_firmware(&mdt, fwname, fw_dev); + ret = request_firmware(&mdt, fwname, dev); if (ret < 0) - goto err_unreg_device; + goto err_unmap; fw_size = qcom_mdt_get_size(mdt); if (fw_size < 0) { ret = fw_size; release_firmware(mdt); - goto err_unreg_device; + goto err_unmap; } - ret = qcom_mdt_load(fw_dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys, + ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys, mem_size); release_firmware(mdt); if (ret) - goto err_unreg_device; + goto err_unmap; ret = qcom_scm_pas_auth_and_reset(VENUS_PAS_ID); if (ret) - goto err_unreg_device; - - return 0; + goto err_unmap; -err_unreg_device: - device_unregister(fw_dev); +err_unmap: + memunmap(mem_va); return ret; } -int venus_shutdown(struct device *fw_dev) +int venus_shutdown(struct device *dev) { - int ret; - - ret = qcom_scm_pas_shutdown(VENUS_PAS_ID); - device_unregister(fw_dev); - memset(fw_dev, 0, sizeof(*fw_dev)); - - return ret; + return qcom_scm_pas_shutdown(VENUS_PAS_ID); } diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h index f81a98979798..428efb56d339 100644 --- a/drivers/media/platform/qcom/venus/firmware.h +++ b/drivers/media/platform/qcom/venus/firmware.h @@ -16,8 +16,7 @@ struct device; -int venus_boot(struct device *parent, struct device *fw_dev, - const char *fwname); -int venus_shutdown(struct device *fw_dev); +int venus_boot(struct device *dev, const char *fwname); +int venus_shutdown(struct device *dev); #endif -- cgit v1.2.3 From 6759b019eeacd7de034d4093177f7205abc16d79 Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Thu, 20 Jul 2017 08:02:09 -0400 Subject: media: platform: davinci: return -EINVAL for VPFE_CMD_S_CCDC_RAW_PARAMS ioctl this patch makes sure VPFE_CMD_S_CCDC_RAW_PARAMS ioctl no longer works for vpfe_capture driver with a minimal patch suitable for backporting. - This ioctl was never in public api and was only defined in kernel header. - The function set_params constantly mixes up pointers and phys_addr_t numbers. - This is part of a 'VPFE_CMD_S_CCDC_RAW_PARAMS' ioctl command that is described as an 'experimental ioctl that will change in future kernels'. - The code to allocate the table never gets called after we copy_from_user the user input over the kernel settings, and then compare them for inequality. - We then go on to use an address provided by user space as both the __user pointer for input and pass it through phys_to_virt to come up with a kernel pointer to copy the data to. This looks like a trivially exploitable root hole. Due to these reasons we make sure this ioctl now returns -EINVAL and backport this patch as far as possible. Fixes: 5f15fbb68fd7 ("V4L/DVB (12251): v4l: dm644x ccdc module for vpfe capture driver") Signed-off-by: Lad, Prabhakar Cc: # for v3.7 and up Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index e3fe3e0635aa..1831bf5ccca5 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1719,27 +1719,9 @@ static long vpfe_param_handler(struct file *file, void *priv, switch (cmd) { case VPFE_CMD_S_CCDC_RAW_PARAMS: + ret = -EINVAL; v4l2_warn(&vpfe_dev->v4l2_dev, - "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n"); - if (ccdc_dev->hw_ops.set_params) { - ret = ccdc_dev->hw_ops.set_params(param); - if (ret) { - v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, - "Error setting parameters in CCDC\n"); - goto unlock_out; - } - ret = vpfe_get_ccdc_image_format(vpfe_dev, - &vpfe_dev->fmt); - if (ret < 0) { - v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, - "Invalid image format at CCDC\n"); - goto unlock_out; - } - } else { - ret = -EINVAL; - v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, - "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n"); - } + "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n"); break; default: ret = -ENOTTY; -- cgit v1.2.3 From d75cf0144f150272be806b69b4e62553ba07ea1b Mon Sep 17 00:00:00 2001 From: Prabhakar Lad Date: Thu, 20 Jul 2017 04:56:31 -0400 Subject: media: platform: davinci: drop VPFE_CMD_S_CCDC_RAW_PARAMS drop VPFE_CMD_S_CCDC_RAW_PARAMS ioctl from dm355/dm644x following reasons: - This ioctl was never in public api and was only defined in kernel header. - The function set_params constantly mixes up pointers and phys_addr_t numbers. - This is part of a 'VPFE_CMD_S_CCDC_RAW_PARAMS' ioctl command that is described as an 'experimental ioctl that will change in future kernels'. - The code to allocate the table never gets called after we copy_from_user the user input over the kernel settings, and then compare them for inequality. - We then go on to use an address provided by user space as both the __user pointer for input and pass it through phys_to_virt to come up with a kernel pointer to copy the data to. This looks like a trivially exploitable root hole. Signed-off-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/ccdc_hw_device.h | 10 -- drivers/media/platform/davinci/dm355_ccdc.c | 92 +-------------- drivers/media/platform/davinci/dm644x_ccdc.c | 151 +----------------------- drivers/media/platform/davinci/vpfe_capture.c | 75 ------------ include/media/davinci/dm644x_ccdc.h | 12 -- include/media/davinci/vpfe_capture.h | 10 -- 6 files changed, 4 insertions(+), 346 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h index 8f6688a7a111..f1b521045d64 100644 --- a/drivers/media/platform/davinci/ccdc_hw_device.h +++ b/drivers/media/platform/davinci/ccdc_hw_device.h @@ -42,16 +42,6 @@ struct ccdc_hw_ops { int (*set_hw_if_params) (struct vpfe_hw_if_param *param); /* get interface parameters */ int (*get_hw_if_params) (struct vpfe_hw_if_param *param); - /* - * Pointer to function to set parameters. Used - * for implementing VPFE_S_CCDC_PARAMS - */ - int (*set_params) (void *params); - /* - * Pointer to function to get parameter. Used - * for implementing VPFE_G_CCDC_PARAMS - */ - int (*get_params) (void *params); /* Pointer to function to configure ccdc */ int (*configure) (void); diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 73db166dc338..6d492dc4c3a9 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -17,12 +17,7 @@ * This module is for configuring DM355 CCD controller of VPFE to capture * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules * such as Defect Pixel Correction, Color Space Conversion etc to - * pre-process the Bayer RGB data, before writing it to SDRAM. This - * module also allows application to configure individual - * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL. - * To do so, application include dm355_ccdc.h and vpfe_capture.h header - * files. The setparams() API is called by vpfe_capture driver - * to configure module parameters + * pre-process the Bayer RGB data, before writing it to SDRAM. * * TODO: 1) Raw bayer parameter settings and bayer capture * 2) Split module parameter structure to module specific ioctl structs @@ -260,90 +255,6 @@ static void ccdc_setwin(struct v4l2_rect *image_win, dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin..."); } -static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) -{ - if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT || - ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) { - dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n"); - return -EINVAL; - } - - if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 || - ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) { - dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n"); - return -EINVAL; - } - - if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 || - ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) { - dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n"); - return -EINVAL; - } - - if ((ccdcparam->med_filt_thres < 0) || - (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { - dev_dbg(ccdc_cfg.dev, - "Invalid value of median filter threshold\n"); - return -EINVAL; - } - - if (ccdcparam->data_sz < CCDC_DATA_16BITS || - ccdcparam->data_sz > CCDC_DATA_8BITS) { - dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n"); - return -EINVAL; - } - - if (ccdcparam->alaw.enable) { - if (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_13_4 || - ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) { - dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n"); - return -EINVAL; - } - } - - if (ccdcparam->blk_clamp.b_clamp_enable) { - if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS || - ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) { - dev_dbg(ccdc_cfg.dev, - "Invalid value of sample pixel\n"); - return -EINVAL; - } - if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES || - ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) { - dev_dbg(ccdc_cfg.dev, - "Invalid value of sample lines\n"); - return -EINVAL; - } - } - return 0; -} - -/* Parameter operations */ -static int ccdc_set_params(void __user *params) -{ - struct ccdc_config_params_raw ccdc_raw_params; - int x; - - /* only raw module parameters can be set through the IOCTL */ - if (ccdc_cfg.if_type != VPFE_RAW_BAYER) - return -EINVAL; - - x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); - if (x) { - dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdcparams, %d\n", - x); - return -EFAULT; - } - - if (!validate_ccdc_param(&ccdc_raw_params)) { - memcpy(&ccdc_cfg.bayer.config_params, - &ccdc_raw_params, - sizeof(ccdc_raw_params)); - return 0; - } - return -EINVAL; -} - /* This function will configure CCDC for YCbCr video capture */ static void ccdc_config_ycbcr(void) { @@ -939,7 +850,6 @@ static struct ccdc_hw_device ccdc_hw_dev = { .enable = ccdc_enable, .enable_out_to_sdram = ccdc_enable_output_to_sdram, .set_hw_if_params = ccdc_set_hw_if_params, - .set_params = ccdc_set_params, .configure = ccdc_configure, .set_buftype = ccdc_set_buftype, .get_buftype = ccdc_get_buftype, diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 740fbc7a8c14..3b2d8a9317b8 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -17,13 +17,9 @@ * This module is for configuring CCD controller of DM6446 VPFE to capture * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules * such as Defect Pixel Correction, Color Space Conversion etc to - * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This - * module also allows application to configure individual - * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL. - * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header - * files. The setparams() API is called by vpfe_capture driver - * to configure module parameters. This file is named DM644x so that other - * variants such DM6443 may be supported using the same module. + * pre-process the Raw Bayer RGB data, before writing it to SDRAM. + * This file is named DM644x so that other variants such DM6443 + * may be supported using the same module. * * TODO: Test Raw bayer parameter settings and bayer capture * Split module parameter structure to module specific ioctl structs @@ -216,96 +212,8 @@ static void ccdc_readregs(void) dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val); } -static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) -{ - if (ccdcparam->alaw.enable) { - u8 max_gamma = ccdc_gamma_width_max_bit(ccdcparam->alaw.gamma_wd); - u8 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz); - - if ((ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) || - (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_15_6) || - (max_gamma > max_data)) { - dev_dbg(ccdc_cfg.dev, "\nInvalid data line select"); - return -1; - } - } - return 0; -} - -static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) -{ - struct ccdc_config_params_raw *config_params = - &ccdc_cfg.bayer.config_params; - unsigned int *fpc_virtaddr = NULL; - unsigned int *fpc_physaddr = NULL; - - memcpy(config_params, raw_params, sizeof(*raw_params)); - /* - * allocate memory for fault pixel table and copy the user - * values to the table - */ - if (!config_params->fault_pxl.enable) - return 0; - - fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; - fpc_virtaddr = (unsigned int *)phys_to_virt( - (unsigned long)fpc_physaddr); - /* - * Allocate memory for FPC table if current - * FPC table buffer is not big enough to - * accommodate FPC Number requested - */ - if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) { - if (fpc_physaddr != NULL) { - free_pages((unsigned long)fpc_virtaddr, - get_order - (config_params->fault_pxl.fp_num * - FP_NUM_BYTES)); - } - - /* Allocate memory for FPC table */ - fpc_virtaddr = - (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA, - get_order(raw_params-> - fault_pxl.fp_num * - FP_NUM_BYTES)); - - if (fpc_virtaddr == NULL) { - dev_dbg(ccdc_cfg.dev, - "\nUnable to allocate memory for FPC"); - return -EFAULT; - } - fpc_physaddr = - (unsigned int *)virt_to_phys((void *)fpc_virtaddr); - } - - /* Copy number of fault pixels and FPC table */ - config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num; - if (copy_from_user(fpc_virtaddr, - (void __user *)raw_params->fault_pxl.fpc_table_addr, - config_params->fault_pxl.fp_num * FP_NUM_BYTES)) { - dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed"); - return -EFAULT; - } - config_params->fault_pxl.fpc_table_addr = (unsigned long)fpc_physaddr; - return 0; -} - static int ccdc_close(struct device *dev) { - struct ccdc_config_params_raw *config_params = - &ccdc_cfg.bayer.config_params; - unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL; - - fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; - - if (fpc_physaddr != NULL) { - fpc_virtaddr = (unsigned int *) - phys_to_virt((unsigned long)fpc_physaddr); - free_pages((unsigned long)fpc_virtaddr, - get_order(config_params->fault_pxl.fp_num * - FP_NUM_BYTES)); - } return 0; } @@ -339,29 +247,6 @@ static void ccdc_sbl_reset(void) vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O); } -/* Parameter operations */ -static int ccdc_set_params(void __user *params) -{ - struct ccdc_config_params_raw ccdc_raw_params; - int x; - - if (ccdc_cfg.if_type != VPFE_RAW_BAYER) - return -EINVAL; - - x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); - if (x) { - dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copyingccdc params, %d\n", - x); - return -EFAULT; - } - - if (!validate_ccdc_param(&ccdc_raw_params)) { - if (!ccdc_update_raw_params(&ccdc_raw_params)) - return 0; - } - return -EINVAL; -} - /* * ccdc_config_ycbcr() * This function will configure CCDC for YCbCr video capture @@ -489,32 +374,6 @@ static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp) regw(val, CCDC_BLKCMP); } -static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc) -{ - u32 val; - - /* Initially disable FPC */ - val = CCDC_FPC_DISABLE; - regw(val, CCDC_FPC); - - if (!fpc->enable) - return; - - /* Configure Fault pixel if needed */ - regw(fpc->fpc_table_addr, CCDC_FPC_ADDR); - dev_dbg(ccdc_cfg.dev, "\nWriting 0x%lx to FPC_ADDR...\n", - (fpc->fpc_table_addr)); - /* Write the FPC params with FPC disable */ - val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK; - regw(val, CCDC_FPC); - - dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val); - /* read the FPC register */ - val = regr(CCDC_FPC) | CCDC_FPC_ENABLE; - regw(val, CCDC_FPC); - dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val); -} - /* * ccdc_config_raw() * This function will configure CCDC for Raw capture mode @@ -569,9 +428,6 @@ static void ccdc_config_raw(void) /* Configure Black level compensation */ ccdc_config_black_compense(&config_params->blk_comp); - /* Configure Fault Pixel Correction */ - ccdc_config_fpc(&config_params->fault_pxl); - /* If data size is 8 bit then pack the data */ if ((config_params->data_sz == CCDC_DATA_8BITS) || config_params->alaw.enable) @@ -929,7 +785,6 @@ static struct ccdc_hw_device ccdc_hw_dev = { .reset = ccdc_sbl_reset, .enable = ccdc_enable, .set_hw_if_params = ccdc_set_hw_if_params, - .set_params = ccdc_set_params, .configure = ccdc_configure, .set_buftype = ccdc_set_buftype, .get_buftype = ccdc_get_buftype, diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 1831bf5ccca5..b1bf4a7e8eb7 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -280,45 +280,6 @@ void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) } EXPORT_SYMBOL(vpfe_unregister_ccdc_device); -/* - * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings - */ -static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev, - struct v4l2_format *f) -{ - struct v4l2_rect image_win; - enum ccdc_buftype buf_type; - enum ccdc_frmfmt frm_fmt; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - ccdc_dev->hw_ops.get_image_window(&image_win); - f->fmt.pix.width = image_win.width; - f->fmt.pix.height = image_win.height; - f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length(); - f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * - f->fmt.pix.height; - buf_type = ccdc_dev->hw_ops.get_buftype(); - f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format(); - frm_fmt = ccdc_dev->hw_ops.get_frame_format(); - if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE) - f->fmt.pix.field = V4L2_FIELD_NONE; - else if (frm_fmt == CCDC_FRMFMT_INTERLACED) { - if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) - f->fmt.pix.field = V4L2_FIELD_INTERLACED; - else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED) - f->fmt.pix.field = V4L2_FIELD_SEQ_TB; - else { - v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n"); - return -EINVAL; - } - } else { - v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n"); - return -EINVAL; - } - return 0; -} - /* * vpfe_config_ccdc_image_format() * For a pix format, configure ccdc to setup the capture @@ -1697,41 +1658,6 @@ unlock_out: return ret; } - -static long vpfe_param_handler(struct file *file, void *priv, - bool valid_prio, unsigned int cmd, void *param) -{ - struct vpfe_device *vpfe_dev = video_drvdata(file); - int ret; - - v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n"); - - if (vpfe_dev->started) { - /* only allowed if streaming is not started */ - v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, - "device already started\n"); - return -EBUSY; - } - - ret = mutex_lock_interruptible(&vpfe_dev->lock); - if (ret) - return ret; - - switch (cmd) { - case VPFE_CMD_S_CCDC_RAW_PARAMS: - ret = -EINVAL; - v4l2_warn(&vpfe_dev->v4l2_dev, - "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n"); - break; - default: - ret = -ENOTTY; - } -unlock_out: - mutex_unlock(&vpfe_dev->lock); - return ret; -} - - /* vpfe capture ioctl operations */ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = { .vidioc_querycap = vpfe_querycap, @@ -1754,7 +1680,6 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = { .vidioc_cropcap = vpfe_cropcap, .vidioc_g_selection = vpfe_g_selection, .vidioc_s_selection = vpfe_s_selection, - .vidioc_default = vpfe_param_handler, }; static struct vpfe_device *vpfe_initialize(void) diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h index 7c909da29d43..6ea2ce241851 100644 --- a/include/media/davinci/dm644x_ccdc.h +++ b/include/media/davinci/dm644x_ccdc.h @@ -103,16 +103,6 @@ struct ccdc_black_compensation { char gb; }; -/* structure for fault pixel correction */ -struct ccdc_fault_pixel { - /* Enable or Disable fault pixel correction */ - unsigned char enable; - /* Number of fault pixel */ - unsigned short fp_num; - /* Address of fault pixel table */ - unsigned long fpc_table_addr; -}; - /* Structure for CCDC configuration parameters for raw capture mode passed * by application */ @@ -125,8 +115,6 @@ struct ccdc_config_params_raw { struct ccdc_black_clamp blk_clamp; /* Structure for Black Compensation */ struct ccdc_black_compensation blk_comp; - /* Structure for Fault Pixel Module Configuration */ - struct ccdc_fault_pixel fault_pxl; }; diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h index 8e1a4d88daa0..f003533602d0 100644 --- a/include/media/davinci/vpfe_capture.h +++ b/include/media/davinci/vpfe_capture.h @@ -183,14 +183,4 @@ struct vpfe_config_params { }; #endif /* End of __KERNEL__ */ -/** - * VPFE_CMD_S_CCDC_RAW_PARAMS - EXPERIMENTAL IOCTL to set raw capture params - * This can be used to configure modules such as defect pixel correction, - * color space conversion, culling etc. This is an experimental ioctl that - * will change in future kernels. So use this ioctl with care ! - * TODO: This is to be split into multiple ioctls and also explore the - * possibility of extending the v4l2 api to include this - **/ -#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 1, \ - void *) #endif /* _DAVINCI_VPFE_H */ -- cgit v1.2.3 From dbaed9f095ec6501934a685f9b537cf033e3a33c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 24 Jun 2017 16:40:25 -0400 Subject: media: s3c-camif: use LINUX_VERSION_CODE for driver's version We seldomly increment version numbers on drivers, because... we usually forget ;-) So, instead, just make it identical to the Kernel version, as what we do on all other drivers. Signed-off-by: Mauro Carvalho Chehab Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index ec4001970313..8f0414041e81 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -317,7 +317,7 @@ static int camif_media_dev_init(struct camif_dev *camif) ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X"); strlcpy(md->bus_info, "platform", sizeof(md->bus_info)); md->hw_revision = ip_rev; - md->driver_version = KERNEL_VERSION(1, 0, 0); + md->driver_version = LINUX_VERSION_CODE; md->dev = camif->dev; -- cgit v1.2.3 From 1769e7a400d55aebfa5dacd5af6d80df59f58b2b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 24 Jun 2017 16:40:26 -0400 Subject: media: radio-bcm2048: get rid of BCM2048_DRIVER_VERSION This macro is never used. Get rid of it. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 38f72d069e27..86d7fc20f237 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -48,7 +48,6 @@ /* driver definitions */ #define BCM2048_DRIVER_AUTHOR "Eero Nurkkala " #define BCM2048_DRIVER_NAME BCM2048_NAME -#define BCM2048_DRIVER_VERSION KERNEL_VERSION(0, 0, 1) #define BCM2048_DRIVER_CARD "Broadcom bcm2048 FM Radio Receiver" #define BCM2048_DRIVER_DESC "I2C driver for BCM2048 FM Radio Receiver" -- cgit v1.2.3 From d10447762562ff04b6bc3df9970252bb8d70a846 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 24 Jun 2017 16:40:24 -0400 Subject: media: cx25821: get rid of CX25821_VERSION_CODE This is used just for printing a version number. As this is never incremented, it makes no sense to keep it :-) Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 5 +---- drivers/media/pci/cx25821/cx25821.h | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index fbc0229183bd..04aa4a68a0ae 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -1390,10 +1390,7 @@ static struct pci_driver cx25821_pci_driver = { static int __init cx25821_init(void) { - pr_info("driver version %d.%d.%d loaded\n", - (CX25821_VERSION_CODE >> 16) & 0xff, - (CX25821_VERSION_CODE >> 8) & 0xff, - CX25821_VERSION_CODE & 0xff); + pr_info("driver loaded\n"); return pci_register_driver(&cx25821_pci_driver); } diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 0f20e89b0cde..b3eb2dabb30b 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -41,8 +41,6 @@ #include #include -#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106) - #define UNSET (-1U) #define NO_SYNC_LINE (-1U) -- cgit v1.2.3 From f3b38dcaa4768f13c7009267b7eef1c94298e9a2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 24 Jun 2017 16:40:27 -0400 Subject: media: atomisp: use LINUX_VERSION_CODE for driver version The atomisp subdev driver hardcodes its version to ATOMISP_CSS_VERSION_21. Yet, it has several tests for versions below 21 internally, with sounds really odd. On all other media drivers, we're just keeping version set to LINUX_VERSION_CODE. So, do the same here, simplifying the code a little bit. Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/include/linux/atomisp.h | 6 ---- .../media/atomisp/pci/atomisp2/atomisp_internal.h | 9 ------ .../media/atomisp/pci/atomisp2/atomisp_ioctl.c | 3 -- .../media/atomisp/pci/atomisp2/atomisp_subdev.c | 6 ++-- .../media/atomisp/pci/atomisp2/atomisp_v4l2.c | 33 +++++++++++----------- 5 files changed, 18 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h index 35865462ccf9..d67dd658cff9 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h @@ -28,12 +28,6 @@ #include #include -/* struct media_device_info.driver_version */ -#define ATOMISP_CSS_VERSION_MASK 0x00ffffff -#define ATOMISP_CSS_VERSION_15 KERNEL_VERSION(1, 5, 0) -#define ATOMISP_CSS_VERSION_20 KERNEL_VERSION(2, 0, 0) -#define ATOMISP_CSS_VERSION_21 KERNEL_VERSION(2, 1, 0) - /* struct media_device_info.hw_revision */ #define ATOMISP_HW_REVISION_MASK 0x0000ff00 #define ATOMISP_HW_REVISION_SHIFT 8 diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h index afced4f4eb6a..3c48bfa92c12 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h @@ -75,15 +75,6 @@ #define ATOMISP_PCI_REV_MRFLD_A0_MAX 0 #define ATOMISP_PCI_REV_BYT_A0_MAX 4 -#define ATOMISP_MAJOR 0 -#define ATOMISP_MINOR 5 -#define ATOMISP_PATCHLEVEL 1 - -#define DRIVER_VERSION_STR __stringify(ATOMISP_MAJOR) \ - "." __stringify(ATOMISP_MINOR) "." __stringify(ATOMISP_PATCHLEVEL) -#define DRIVER_VERSION KERNEL_VERSION(ATOMISP_MAJOR, \ - ATOMISP_MINOR, ATOMISP_PATCHLEVEL) - #define ATOM_ISP_STEP_WIDTH 2 #define ATOM_ISP_STEP_HEIGHT 2 diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c index aa0526ebaff1..717647951fb6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c @@ -51,7 +51,6 @@ static const char *DRIVER = "atomisp"; /* max size 15 */ static const char *CARD = "ATOM ISP"; /* max size 31 */ static const char *BUS_INFO = "PCI-3"; /* max size 31 */ -static const u32 VERSION = DRIVER_VERSION; /* * FIXME: ISP should not know beforehand all CIDs supported by sensor. @@ -562,8 +561,6 @@ static int atomisp_querycap(struct file *file, void *fh, strncpy(cap->card, CARD, sizeof(cap->card) - 1); strncpy(cap->bus_info, BUS_INFO, sizeof(cap->card) - 1); - cap->version = VERSION; - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c index 3d6bb166927c..744ab6eb42a0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c @@ -1253,8 +1253,7 @@ int atomisp_create_pads_links(struct atomisp_device *isp) { struct atomisp_sub_device *asd; int i, j, ret = 0; - isp->num_of_streams = isp->media_dev.driver_version >= - ATOMISP_CSS_VERSION_20 ? 2 : 1; + isp->num_of_streams = 2; for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { for (j = 0; j < isp->num_of_streams; j++) { ret = @@ -1414,8 +1413,7 @@ int atomisp_subdev_init(struct atomisp_device *isp) * CSS2.0 running ISP2400 support * multiple streams */ - isp->num_of_streams = isp->media_dev.driver_version >= - ATOMISP_CSS_VERSION_20 ? 2 : 1; + isp->num_of_streams = 2; isp->asd = devm_kzalloc(isp->dev, sizeof(struct atomisp_sub_device) * isp->num_of_streams, GFP_KERNEL); if (!isp->asd) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c index a543def739fc..2f49562377e6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c @@ -1083,22 +1083,20 @@ atomisp_load_firmware(struct atomisp_device *isp) if (skip_fwload) return NULL; - if (isp->media_dev.driver_version == ATOMISP_CSS_VERSION_21) { - if (isp->media_dev.hw_revision == - ((ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT) - | ATOMISP_HW_STEPPING_A0)) - fw_path = "shisp_2401a0_v21.bin"; - - if (isp->media_dev.hw_revision == - ((ATOMISP_HW_REVISION_ISP2401_LEGACY << ATOMISP_HW_REVISION_SHIFT) - | ATOMISP_HW_STEPPING_A0)) - fw_path = "shisp_2401a0_legacy_v21.bin"; - - if (isp->media_dev.hw_revision == - ((ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT) - | ATOMISP_HW_STEPPING_B0)) - fw_path = "shisp_2400b0_v21.bin"; - } + if (isp->media_dev.hw_revision == + ((ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT) + | ATOMISP_HW_STEPPING_A0)) + fw_path = "shisp_2401a0_v21.bin"; + + if (isp->media_dev.hw_revision == + ((ATOMISP_HW_REVISION_ISP2401_LEGACY << ATOMISP_HW_REVISION_SHIFT) + | ATOMISP_HW_STEPPING_A0)) + fw_path = "shisp_2401a0_legacy_v21.bin"; + + if (isp->media_dev.hw_revision == + ((ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT) + | ATOMISP_HW_STEPPING_B0)) + fw_path = "shisp_2400b0_v21.bin"; if (!fw_path) { dev_err(isp->dev, @@ -1251,7 +1249,8 @@ static int atomisp_pci_probe(struct pci_dev *dev, /* This is not a true PCI device on SoC, so the delay is not needed. */ isp->pdev->d3_delay = 0; - isp->media_dev.driver_version = ATOMISP_CSS_VERSION_21; + isp->media_dev.driver_version = LINUX_VERSION_CODE; + switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { case ATOMISP_PCI_DEVICE_SOC_MRFLD: isp->media_dev.hw_revision = -- cgit v1.2.3 From 1ad371deb9b0be142dca205611a56854a37fc48d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 26 Jun 2017 08:33:56 -0400 Subject: media: pvrusb2: fix the retry logic As reported by this warning: drivers/media/usb/pvrusb2/pvrusb2-encoder.c:263 pvr2_encoder_cmd() warn: continue to end of do { ... } while(0); loop There's an issue at the retry logic there: the current logic is: do { if (need_to_retry) continue; some_code(); } while (0); Well, that won't work, as continue will make it test for zero, and abort the loop. So, change the loop to: while (1) { if (need_to_retry) continue; some_code(); break; }; With seems to be what's actually expected there. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-encoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c index ca637074fa1f..43e43404095f 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c @@ -198,7 +198,7 @@ static int pvr2_encoder_cmd(void *ctxt, } - LOCK_TAKE(hdw->ctl_lock); do { + LOCK_TAKE(hdw->ctl_lock); while (1) { if (!hdw->state_encoder_ok) { ret = -EIO; @@ -293,9 +293,9 @@ rdData[0]); wrData[0] = 0x0; ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); - if (ret) break; + break; - } while(0); LOCK_GIVE(hdw->ctl_lock); + }; LOCK_GIVE(hdw->ctl_lock); return ret; } -- cgit v1.2.3 From 4ee236219f6da367093b503b52fcceb609397c6f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 26 Jun 2017 14:07:54 -0400 Subject: media: v4l2-fwnode: suppress a warning at OF parsing logic smatch produce this warning: drivers/media/v4l2-core/v4l2-fwnode.c:76 v4l2_fwnode_endpoint_parse_csi_bus() error: buffer overflow 'array' 5 <= u16max That's because, in thesis, the routine might have called with some value at bus->num_data_lanes. That's not the current case. Yet, better to shut up this warning, and make the code more reliable if some future changes might cause a bug. While here, simplify the code a little bit by reading only once from lanes-properties array. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 32 ++++++++++++++------------------ include/media/v4l2-fwnode.h | 6 ++++-- 2 files changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index ca755a4832fc..d07c54efaa99 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -48,10 +48,9 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); if (rval > 0) { - u32 array[ARRAY_SIZE(bus->data_lanes)]; + u32 array[MAX_DATA_LANES + 1]; - bus->num_data_lanes = - min_t(int, ARRAY_SIZE(bus->data_lanes), rval); + bus->num_data_lanes = min_t(int, MAX_DATA_LANES, rval); fwnode_property_read_u32_array(fwnode, "data-lanes", array, bus->num_data_lanes); @@ -64,24 +63,21 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, bus->data_lanes[i] = array[i]; } - } - rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL, - 0); - if (rval > 0) { - u32 array[ARRAY_SIZE(bus->lane_polarities)]; + rval = fwnode_property_read_u32_array(fwnode, + "lane-polarities", array, + 1 + bus->num_data_lanes); + if (rval > 0) { + if (rval != 1 + bus->num_data_lanes /* clock + data */) { + pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", + 1 + bus->num_data_lanes, rval); + return -EINVAL; + } - if (rval < 1 + bus->num_data_lanes /* clock + data */) { - pr_warn("too few lane-polarities entries (need %u, got %u)\n", - 1 + bus->num_data_lanes, rval); - return -EINVAL; - } - fwnode_property_read_u32_array(fwnode, "lane-polarities", array, - 1 + bus->num_data_lanes); - - for (i = 0; i < 1 + bus->num_data_lanes; i++) - bus->lane_polarities[i] = array[i]; + for (i = 0; i < 1 + bus->num_data_lanes; i++) + bus->lane_polarities[i] = array[i]; + } } if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 29ae22bbbbaf..b373c43f65e8 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -26,6 +26,8 @@ struct fwnode_handle; +#define MAX_DATA_LANES 4 + /** * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure * @flags: media bus (V4L2_MBUS_*) flags @@ -37,10 +39,10 @@ struct fwnode_handle; */ struct v4l2_fwnode_bus_mipi_csi2 { unsigned int flags; - unsigned char data_lanes[4]; + unsigned char data_lanes[MAX_DATA_LANES]; unsigned char clock_lane; unsigned short num_data_lanes; - bool lane_polarities[5]; + bool lane_polarities[MAX_DATA_LANES + 1]; }; /** -- cgit v1.2.3 From abc5b2cbc20abf9524106105a73a3315caae446d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jul 2017 16:27:27 -0400 Subject: media: v4l2-fwnode: make v4l2_fwnode_endpoint_parse_csi1_bus static This function is used only internally. So, make it static. Shuts up this warning: drivers/media/v4l2-core/v4l2-fwnode.c:153:6: warning: no previous prototype for 'v4l2_fwnode_endpoint_parse_csi1_bus' [-Wmissing-prototypes] void v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index d07c54efaa99..a4f80ff713c6 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -150,9 +150,10 @@ static void v4l2_fwnode_endpoint_parse_parallel_bus( } -void v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, - struct v4l2_fwnode_endpoint *vep, - u32 bus_type) +static void +v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, + struct v4l2_fwnode_endpoint *vep, + u32 bus_type) { struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1; u32 v; -- cgit v1.2.3 From 488e27ad81f76a2664fb33c06b6da846605adad2 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 26 Jun 2017 19:50:16 -0400 Subject: media: dvb-frontends: mb86a16: remove useless variables in signal_det() Remove useless variables wait_t and wait_sym and code related. Also, fix some coding style issues. Addresses-Coverity-ID: 1226947 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mb86a16.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c index 9bb122c39c1b..dfe322eccaa1 100644 --- a/drivers/media/dvb-frontends/mb86a16.c +++ b/drivers/media/dvb-frontends/mb86a16.c @@ -415,27 +415,21 @@ static int signal_det(struct mb86a16_state *state, int smrt, unsigned char *SIG) { - - int ret ; - int smrtd ; - int wait_sym ; - - u32 wait_t; - unsigned char S[3] ; - int i ; + int ret; + int smrtd; + unsigned char S[3]; + int i; if (*SIG > 45) { if (CNTM_set(state, 2, 1, 2) < 0) { dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); return -1; } - wait_sym = 40000; } else { if (CNTM_set(state, 3, 1, 2) < 0) { dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error"); return -1; } - wait_sym = 80000; } for (i = 0; i < 3; i++) { if (i == 0) @@ -447,22 +441,17 @@ static int signal_det(struct mb86a16_state *state, smrt_info_get(state, smrtd); smrt_set(state, smrtd); srst(state); - wait_t = (wait_sym + 99 * smrtd / 100) / smrtd; - if (wait_t == 0) - wait_t = 1; msleep_interruptible(10); if (mb86a16_read(state, 0x37, &(S[i])) != 2) { dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error"); return -EREMOTEIO; } } - if ((S[1] > S[0] * 112 / 100) && - (S[1] > S[2] * 112 / 100)) { - + if ((S[1] > S[0] * 112 / 100) && (S[1] > S[2] * 112 / 100)) ret = 1; - } else { + else ret = 0; - } + *SIG = S[1]; if (CNTM_set(state, 0, 1, 2) < 0) { -- cgit v1.2.3 From ff05c9849a52d53da6254f80f53c14d9ad2399a4 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 29 Jun 2017 02:55:23 -0400 Subject: media: : usb: add const to v4l2_file_operations structures Declare v4l2_file_operations structures as const as they are only stored in the fops field of video_device structures. This field is of type const, so declare v4l2_file_operations structures with similar properties as const. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-video.c | 2 +- drivers/media/usb/cx231xx/cx231xx-417.c | 2 +- drivers/media/usb/go7007/go7007-v4l2.c | 2 +- drivers/media/usb/gspca/gspca.c | 2 +- drivers/media/usb/stk1160/stk1160-v4l.c | 2 +- drivers/media/usb/stkwebcam/stk-webcam.c | 2 +- drivers/media/usb/tm6000/tm6000-video.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 2a255bd32bb3..9342402b92f7 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1740,7 +1740,7 @@ void au0828_v4l2_resume(struct au0828_dev *dev) } } -static struct v4l2_file_operations au0828_v4l_fops = { +static const struct v4l2_file_operations au0828_v4l_fops = { .owner = THIS_MODULE, .open = au0828_v4l2_open, .release = au0828_v4l2_close, diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 509d9711d590..8d5eb99deacb 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1843,7 +1843,7 @@ static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) return videobuf_mmap_mapper(&fh->vidq, vma); } -static struct v4l2_file_operations mpeg_fops = { +static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, .open = mpeg_open, .release = mpeg_release, diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index ed5ec9773969..445f17b850c5 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -857,7 +857,7 @@ static int go7007_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static struct v4l2_file_operations go7007_fops = { +static const struct v4l2_file_operations go7007_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 16bc1dde2c8c..0f141762abf1 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1964,7 +1964,7 @@ out: return ret; } -static struct v4l2_file_operations dev_fops = { +static const struct v4l2_file_operations dev_fops = { .owner = THIS_MODULE, .open = dev_open, .release = dev_close, diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index a005d262392a..a132faa590df 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -326,7 +326,7 @@ static int stk1160_stop_streaming(struct stk1160 *dev) return 0; } -static struct v4l2_file_operations stk1160_fops = { +static const struct v4l2_file_operations stk1160_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = vb2_fop_release, diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 90d4a08cda31..93330be8cc54 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1202,7 +1202,7 @@ static const struct v4l2_ctrl_ops stk_ctrl_ops = { .s_ctrl = stk_s_ctrl, }; -static struct v4l2_file_operations v4l_stk_fops = { +static const struct v4l2_file_operations v4l_stk_fops = { .owner = THIS_MODULE, .open = v4l_stk_open, .release = v4l_stk_release, diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 7e960d0a5b92..cec1321289df 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -1532,7 +1532,7 @@ static int tm6000_mmap(struct file *file, struct vm_area_struct * vma) return res; } -static struct v4l2_file_operations tm6000_fops = { +static const struct v4l2_file_operations tm6000_fops = { .owner = THIS_MODULE, .open = tm6000_open, .release = tm6000_release, -- cgit v1.2.3 From b5e0733ffca70c1b9169791be1166513d89db2d9 Mon Sep 17 00:00:00 2001 From: Nuno Henriques Date: Thu, 29 Jun 2017 13:55:54 -0400 Subject: media: Added support for the TerraTec T1 DVB-T USB tuner [IT9135 chipset] Signed-off-by: Nuno Henriques Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb-usb-ids.h | 1 + drivers/media/usb/dvb-usb-v2/af9035.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index e200aa6f2d2f..5b6041d462bc 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h @@ -279,6 +279,7 @@ #define USB_PID_TERRATEC_H7 0x10b4 #define USB_PID_TERRATEC_H7_2 0x10a3 #define USB_PID_TERRATEC_H7_3 0x10a5 +#define USB_PID_TERRATEC_T1 0x10ae #define USB_PID_TERRATEC_T3 0x10a0 #define USB_PID_TERRATEC_T5 0x10a1 #define USB_PID_NOXON_DAB_STICK 0x00b3 diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 4df9486e19b9..ccf4a5c68877 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -2108,6 +2108,8 @@ static const struct usb_device_id af9035_id_table[] = { { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2, &af9035_props, "Digital Dual TV Receiver CTVDIGDUAL_V2", RC_MAP_IT913X_V1) }, + { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T1, + &af9035_props, "TerraTec T1", RC_MAP_IT913X_V1) }, /* XXX: that same ID [0ccd:0099] is used by af9015 driver too */ { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099, &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", -- cgit v1.2.3 From 6538b02d210f52ef2a2e67d59fcb58be98451fbd Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Mon, 3 Jul 2017 08:08:11 -0400 Subject: media: Make parameter of media_entity_remote_pad() const The local pad parameter in media_entity_remote_pad() is not modified. Make that explicit by adding a const modifier. Signed-off-by: Todor Tomov Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 2 +- include/media/media-entity.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index dd0f0ead9516..2ace0410d277 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -917,7 +917,7 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink) } EXPORT_SYMBOL_GPL(media_entity_find_link); -struct media_pad *media_entity_remote_pad(struct media_pad *pad) +struct media_pad *media_entity_remote_pad(const struct media_pad *pad) { struct media_link *link; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 754182d29668..222d379960b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -805,7 +805,7 @@ struct media_link *media_entity_find_link(struct media_pad *source, * Return: returns a pointer to the pad at the remote end of the first found * enabled link, or %NULL if no enabled link has been found. */ -struct media_pad *media_entity_remote_pad(struct media_pad *pad); +struct media_pad *media_entity_remote_pad(const struct media_pad *pad); /** * media_entity_get - Get a reference to the parent module -- cgit v1.2.3 From 0e50e84a11f4854e9a7e3b7f4443ffb99e6be292 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 16 Jul 2017 04:07:59 -0400 Subject: media: dvb-core/demux.h: fix kernel-doc warning Fix this kernel-doc warning: WARNING: kernel-doc 'media-git/scripts/kernel-doc -rst -enable-lineno media-git/drivers/media/dvb-core/demux.h' processing failed with: 'ascii' codec can't decode byte 0xe2 in position 6368: ordinal not in range(128) Caused by using fancy quotes instead of regular quotes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/demux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/demux.h b/drivers/media/dvb-core/demux.h index f854309ba8a5..c4df6cee48e6 100644 --- a/drivers/media/dvb-core/demux.h +++ b/drivers/media/dvb-core/demux.h @@ -210,7 +210,7 @@ struct dmx_section_feed { * the start of the first undelivered TS packet within a circular buffer. * The @buffer2 buffer parameter is normally NULL, except when the received * TS packets have crossed the last address of the circular buffer and - * ”wrapped” to the beginning of the buffer. In the latter case the @buffer1 + * "wrapped" to the beginning of the buffer. In the latter case the @buffer1 * parameter would contain an address within the circular buffer, while the * @buffer2 parameter would contain the first address of the circular buffer. * The number of bytes delivered with this function (i.e. @buffer1_length + -- cgit v1.2.3 From 5ea3bf28ed4a261e281642d140652b00fd64338c Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Fri, 30 Jun 2017 10:15:40 -0400 Subject: media: s5p-jpeg: Call jpeg_bound_align_image after qbuf When queuing an OUTPUT buffer for decoder, s5p_jpeg_parse_hdr() function parses the input jpeg file and takes the width and height parameters from its header. These new width/height values will be used for the calculation of stride. HX_JPEG Hardware needs the width and height values aligned on a 16 bits boundary. This width/height alignment is handled in the s5p_jpeg_s_fmt_vid_cap() function during the S_FMT ioctl call. But if user space calls the QBUF of OUTPUT buffer after the S_FMT of CAPTURE buffer, these aligned values will be replaced by the values in jpeg header. If the width/height values of jpeg are not aligned, the decoder output will be corrupted. So in this patch we call jpeg_bound_align_image() to align the width/height values of Capture buffer in s5p_jpeg_buf_queue(). Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index d1e3ebb22577..97e5518520b3 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2523,6 +2523,25 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) q_data = &ctx->cap_q; q_data->w = tmp.w; q_data->h = tmp.h; + + /* + * This call to jpeg_bound_align_image() takes care of width and + * height values alignment when user space calls the QBUF of + * OUTPUT buffer after the S_FMT of CAPTURE buffer. + * Please note that on Exynos4x12 SoCs, resigning from executing + * S_FMT on capture buffer for each JPEG image can result in a + * hardware hangup if subsampling is lower than the one of input + * JPEG. + */ + jpeg_bound_align_image(ctx, + &q_data->w, + S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH, + q_data->fmt->h_align, + &q_data->h, + S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT, + q_data->fmt->v_align); + + q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; } v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); -- cgit v1.2.3 From fa3cb90bdfc64122f50ce9c1a6090cb720361463 Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Fri, 30 Jun 2017 10:15:41 -0400 Subject: media: s5p-jpeg: Correct WARN_ON statement for checking subsampling Correct the WARN_ON statement for subsampling based on the JPEG hardware version. Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 97e5518520b3..4c672a0f1418 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -614,24 +614,26 @@ static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh) static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) { - WARN_ON(ctx->subsampling > 3); - switch (ctx->jpeg->variant->version) { case SJPEG_S5P: + WARN_ON(ctx->subsampling > 3); if (ctx->subsampling > 2) return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; return ctx->subsampling; case SJPEG_EXYNOS3250: case SJPEG_EXYNOS5420: + WARN_ON(ctx->subsampling > 6); if (ctx->subsampling > 3) return V4L2_JPEG_CHROMA_SUBSAMPLING_411; return exynos3250_decoded_subsampling[ctx->subsampling]; case SJPEG_EXYNOS4: case SJPEG_EXYNOS5433: + WARN_ON(ctx->subsampling > 3); if (ctx->subsampling > 2) return V4L2_JPEG_CHROMA_SUBSAMPLING_420; return exynos4x12_decoded_subsampling[ctx->subsampling]; default: + WARN_ON(ctx->subsampling > 3); return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; } } -- cgit v1.2.3 From fe8a57b618fe128481b8603169a694712a73fbc9 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 30 Jun 2017 10:15:42 -0400 Subject: media: s5p-jpeg: Handle parsing error in s5p_jpeg_parse_hdr() This patch modifies the s5p_jpeg_parse_hdr() function so it only modifies the passed s5p_jpeg_q_data structure if the jpeg header parsing is successful. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 38 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 4c672a0f1418..955cc6e6a2cf 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1206,22 +1206,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, break; } } - result->w = width; - result->h = height; - result->sos = sos; - result->dht.n = n_dht; - while (n_dht--) { - result->dht.marker[n_dht] = dht[n_dht]; - result->dht.len[n_dht] = dht_len[n_dht]; - } - result->dqt.n = n_dqt; - while (n_dqt--) { - result->dqt.marker[n_dqt] = dqt[n_dqt]; - result->dqt.len[n_dqt] = dqt_len[n_dqt]; - } - result->sof = sof; - result->sof_len = sof_len; - result->size = result->components = components; + + if (notfound || !sos) + return false; switch (subsampling) { case 0x11: @@ -1240,7 +1227,24 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, return false; } - return !notfound && sos; + result->w = width; + result->h = height; + result->sos = sos; + result->dht.n = n_dht; + while (n_dht--) { + result->dht.marker[n_dht] = dht[n_dht]; + result->dht.len[n_dht] = dht_len[n_dht]; + } + result->dqt.n = n_dqt; + while (n_dqt--) { + result->dqt.marker[n_dqt] = dqt[n_dqt]; + result->dqt.len[n_dqt] = dqt_len[n_dqt]; + } + result->sof = sof; + result->sof_len = sof_len; + result->size = result->components = components; + + return true; } static int s5p_jpeg_querycap(struct file *file, void *priv, -- cgit v1.2.3 From 14a2de14dc0619bf926c56cd12e29e0245d12abc Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 30 Jun 2017 10:15:43 -0400 Subject: media: s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue If s5p_jpeg_parse_hdr() fails to parse the JPEG header, the passed s5p_jpeg_q_data structure is not modified so there is no need to use a temporary structure and the field-by-field copy can be avoided. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 955cc6e6a2cf..e9ff9773ad32 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2500,9 +2500,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) if (ctx->mode == S5P_JPEG_DECODE && vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - struct s5p_jpeg_q_data tmp, *q_data; + struct s5p_jpeg_q_data *q_data; - ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp, + ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q, (unsigned long)vb2_plane_vaddr(vb, 0), min((unsigned long)ctx->out_q.size, vb2_get_plane_payload(vb, 0)), ctx); @@ -2511,24 +2511,9 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) return; } - q_data = &ctx->out_q; - q_data->w = tmp.w; - q_data->h = tmp.h; - q_data->sos = tmp.sos; - memcpy(q_data->dht.marker, tmp.dht.marker, - sizeof(tmp.dht.marker)); - memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len)); - q_data->dht.n = tmp.dht.n; - memcpy(q_data->dqt.marker, tmp.dqt.marker, - sizeof(tmp.dqt.marker)); - memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len)); - q_data->dqt.n = tmp.dqt.n; - q_data->sof = tmp.sof; - q_data->sof_len = tmp.sof_len; - q_data = &ctx->cap_q; - q_data->w = tmp.w; - q_data->h = tmp.h; + q_data->w = ctx->out_q.w; + q_data->h = ctx->out_q.h; /* * This call to jpeg_bound_align_image() takes care of width and -- cgit v1.2.3 From c8d36a80352efd00088ec0e693636c5ac8ca94e8 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 30 Jun 2017 10:15:44 -0400 Subject: media: s5p-jpeg: Split s5p_jpeg_parse_hdr() This patch moves the subsampling value decoding read from the JPEG header into its own function. This new function is called s5p_jpeg_subsampling_decode() and returns true if it successfully decodes the subsampling value, false otherwise. Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 42 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index e9ff9773ad32..21ba3b4f397c 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1096,6 +1096,29 @@ static void skip(struct s5p_jpeg_buffer *buf, long len) get_byte(buf); } +static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, + unsigned int subsampling) +{ + switch (subsampling) { + case 0x11: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; + break; + case 0x21: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422; + break; + case 0x22: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420; + break; + case 0x33: + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; + break; + default: + return false; + } + + return true; +} + static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, unsigned long buffer, unsigned long size, struct s5p_jpeg_ctx *ctx) @@ -1207,26 +1230,9 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, } } - if (notfound || !sos) + if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling)) return false; - switch (subsampling) { - case 0x11: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; - break; - case 0x21: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422; - break; - case 0x22: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420; - break; - case 0x33: - ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; - break; - default: - return false; - } - result->w = width; result->h = height; result->sos = sos; -- cgit v1.2.3 From accf9b2c1f8326d916576f4eef4ceaad3bab9bf4 Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Fri, 30 Jun 2017 10:15:45 -0400 Subject: media: s5p-jpeg: Decode 4:1:1 chroma subsampling format This patch adds support for decoding 4:1:1 chroma subsampling in the JPEG header parsing function. Signed-off-by: Tony K Nadackal Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 21ba3b4f397c..46d92037bf20 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1099,6 +1099,8 @@ static void skip(struct s5p_jpeg_buffer *buf, long len) static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, unsigned int subsampling) { + unsigned int version; + switch (subsampling) { case 0x11: ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444; @@ -1112,6 +1114,19 @@ static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx, case 0x33: ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; break; + case 0x41: + /* + * 4:1:1 subsampling only supported by 3250, 5420, and 5433 + * variants + */ + version = ctx->jpeg->variant->version; + if (version != SJPEG_EXYNOS3250 && + version != SJPEG_EXYNOS5420 && + version != SJPEG_EXYNOS5433) + return false; + + ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411; + break; default: return false; } -- cgit v1.2.3 From 1c84e7f9d5dc596bef22204131e561c4b3addf0a Mon Sep 17 00:00:00 2001 From: henryhsu Date: Fri, 30 Jun 2017 10:15:46 -0400 Subject: media: s5p-jpeg: Add support for resolution change event This patch adds support for resolution change event to notify clients so they can prepare correct output buffer. When resolution change happened, G_FMT for CAPTURE should return old resolution and format before CAPTURE queues streamoff. This event is used in the Chromium browser project by the V4L2 JPEG Decode Accelerator (V4L2JDA) to allocate output buffer. Signed-off-by: Henry-Ruey Hsu Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 106 +++++++++++++++++++++------- drivers/media/platform/s5p-jpeg/jpeg-core.h | 7 ++ 2 files changed, 89 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 46d92037bf20..96f38f49b260 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1633,8 +1634,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE; q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); - q_data->w = pix->width; - q_data->h = pix->height; if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { /* * During encoding Exynos4x12 SoCs access wider memory area @@ -1642,6 +1641,8 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu * page fault calculate proper buffer size in such a case. */ + q_data->w = pix->width; + q_data->h = pix->height; if (ct->jpeg->variant->hw_ex4_compat && f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE) q_data->size = exynos4_jpeg_get_output_buffer_size(ct, @@ -1717,6 +1718,15 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); } +static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + if (sub->type == V4L2_EVENT_SOURCE_CHANGE) + return v4l2_src_change_event_subscribe(fh, sub); + + return -EINVAL; +} + static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, struct v4l2_rect *r) { @@ -2042,6 +2052,9 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = { .vidioc_g_selection = s5p_jpeg_g_selection, .vidioc_s_selection = s5p_jpeg_s_selection, + + .vidioc_subscribe_event = s5p_jpeg_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; /* @@ -2434,8 +2447,17 @@ static int s5p_jpeg_job_ready(void *priv) { struct s5p_jpeg_ctx *ctx = priv; - if (ctx->mode == S5P_JPEG_DECODE) + if (ctx->mode == S5P_JPEG_DECODE) { + /* + * We have only one input buffer and one output buffer. If there + * is a resolution change event, no need to continue decoding. + */ + if (ctx->state == JPEGCTX_RESOLUTION_CHANGE) + return 0; + return ctx->hdr_parsed; + } + return 1; } @@ -2514,6 +2536,30 @@ static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb) return 0; } +static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx) +{ + struct s5p_jpeg_q_data *q_data = &ctx->cap_q; + + q_data->w = ctx->out_q.w; + q_data->h = ctx->out_q.h; + + /* + * This call to jpeg_bound_align_image() takes care of width and + * height values alignment when user space calls the QBUF of + * OUTPUT buffer after the S_FMT of CAPTURE buffer. + * Please note that on Exynos4x12 SoCs, resigning from executing + * S_FMT on capture buffer for each JPEG image can result in a + * hardware hangup if subsampling is lower than the one of input + * JPEG. + */ + jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH, + S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align, + &q_data->h, S5P_JPEG_MIN_HEIGHT, + S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align); + + q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; +} + static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); @@ -2521,7 +2567,18 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) if (ctx->mode == S5P_JPEG_DECODE && vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - struct s5p_jpeg_q_data *q_data; + static const struct v4l2_event ev_src_ch = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, + }; + struct vb2_queue *dst_vq; + u32 ori_w; + u32 ori_h; + + dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, + V4L2_BUF_TYPE_VIDEO_CAPTURE); + ori_w = ctx->out_q.w; + ori_h = ctx->out_q.h; ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q, (unsigned long)vb2_plane_vaddr(vb, 0), @@ -2532,28 +2589,18 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) return; } - q_data = &ctx->cap_q; - q_data->w = ctx->out_q.w; - q_data->h = ctx->out_q.h; - /* - * This call to jpeg_bound_align_image() takes care of width and - * height values alignment when user space calls the QBUF of - * OUTPUT buffer after the S_FMT of CAPTURE buffer. - * Please note that on Exynos4x12 SoCs, resigning from executing - * S_FMT on capture buffer for each JPEG image can result in a - * hardware hangup if subsampling is lower than the one of input - * JPEG. + * If there is a resolution change event, only update capture + * queue when it is not streaming. Otherwise, update it in + * STREAMOFF. See s5p_jpeg_stop_streaming for detail. */ - jpeg_bound_align_image(ctx, - &q_data->w, - S5P_JPEG_MIN_WIDTH, S5P_JPEG_MAX_WIDTH, - q_data->fmt->h_align, - &q_data->h, - S5P_JPEG_MIN_HEIGHT, S5P_JPEG_MAX_HEIGHT, - q_data->fmt->v_align); - - q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; + if (ctx->out_q.w != ori_w || ctx->out_q.h != ori_h) { + v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); + if (vb2_is_streaming(dst_vq)) + ctx->state = JPEGCTX_RESOLUTION_CHANGE; + else + s5p_jpeg_set_capture_queue_data(ctx); + } } v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); @@ -2573,6 +2620,17 @@ static void s5p_jpeg_stop_streaming(struct vb2_queue *q) { struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); + /* + * STREAMOFF is an acknowledgment for resolution change event. + * Before STREAMOFF, we still have to return the old resolution and + * subsampling. Update capture queue when the stream is off. + */ + if (ctx->state == JPEGCTX_RESOLUTION_CHANGE && + q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + s5p_jpeg_set_capture_queue_data(ctx); + ctx->state = JPEGCTX_RUNNING; + } + pm_runtime_put(ctx->jpeg->dev); } diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 4492a3535df5..9aa26bd1d46d 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h @@ -98,6 +98,11 @@ enum exynos4_jpeg_img_quality_level { QUALITY_LEVEL_4, /* low */ }; +enum s5p_jpeg_ctx_state { + JPEGCTX_RUNNING = 0, + JPEGCTX_RESOLUTION_CHANGE, +}; + /** * struct s5p_jpeg - JPEG IP abstraction * @lock: the mutex protecting this structure @@ -220,6 +225,7 @@ struct s5p_jpeg_q_data { * @hdr_parsed: set if header has been parsed during decompression * @crop_altered: set if crop rectangle has been altered by the user space * @ctrl_handler: controls handler + * @state: state of the context */ struct s5p_jpeg_ctx { struct s5p_jpeg *jpeg; @@ -235,6 +241,7 @@ struct s5p_jpeg_ctx { bool hdr_parsed; bool crop_altered; struct v4l2_ctrl_handler ctrl_handler; + enum s5p_jpeg_ctx_state state; }; /** -- cgit v1.2.3 From 80cdacaa5cad7e0550789a47bcd108f32a7fc9f1 Mon Sep 17 00:00:00 2001 From: henryhsu Date: Fri, 30 Jun 2017 10:15:47 -0400 Subject: media: s5p-jpeg: Add stream error handling for Exynos5420 On Exynos5420, the STREAM_STAT bit raised on the JPGINTST register means there is a syntax error or an unrecoverable error on compressed file when ERR_INT_EN is set to 1. Fix this case and report BUF_STATE_ERROR to videobuf2. Signed-off-by: Henry-Ruey Hsu Signed-off-by: Thierry Escande Acked-by: Andrzej Pietrasiewicz Acked-by: Jacek Anaszewski Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 96f38f49b260..4cef4b8c6584 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2813,6 +2813,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) unsigned long payload_size = 0; enum vb2_buffer_state state = VB2_BUF_STATE_DONE; bool interrupt_timeout = false; + bool stream_error = false; u32 irq_status; spin_lock(&jpeg->slock); @@ -2829,6 +2830,12 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) jpeg->irq_status |= irq_status; + if (jpeg->variant->version == SJPEG_EXYNOS5420 && + irq_status & EXYNOS3250_STREAM_STAT) { + stream_error = true; + dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n"); + } + curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); if (!curr_ctx) @@ -2845,7 +2852,7 @@ static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) EXYNOS3250_RDMA_DONE | EXYNOS3250_RESULT_STAT)) payload_size = exynos3250_jpeg_compressed_size(jpeg->regs); - else if (interrupt_timeout) + else if (interrupt_timeout || stream_error) state = VB2_BUF_STATE_ERROR; else goto exit_unlock; -- cgit v1.2.3 From 281643a2ad7a82ee6588f5f95b6153bb38e6640c Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 5 Jul 2017 14:07:29 -0400 Subject: media: s5k5baf: remove unnecessary static in s5k5baf_get_selection() Remove unnecessary static on local variable rtype. Such variable is initialized before being used, on every execution path throughout the function. The static has no benefit and, removing it reduces the code size. This issue was detected using Coccinelle and the following semantic patch: @bad exists@ position p; identifier x; type T; @@ static T x@p; ... x = <+...x...+> @@ identifier x; expression e; type T; position p != bad.p; @@ -static T x@p; ... when != x when strict ?x = e; In the following log you can see the difference in the code size. Also, there is a significant difference in the bss segment. This log is the output of the size command, before and after the code change: before: text data bss dec hex filename 27765 5656 320 33741 83cd drivers/media/i2c/s5k5baf.o after: text data bss dec hex filename 27733 5600 256 33589 8335 drivers/media/i2c/s5k5baf.o Signed-off-by: Gustavo A. R. Silva Reviewed-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5k5baf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 962051b9939d..f01722dc04d0 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1374,7 +1374,7 @@ static int s5k5baf_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { - static enum selection_rect rtype; + enum selection_rect rtype; struct s5k5baf *state = to_s5k5baf(sd); rtype = s5k5baf_get_sel_rect(sel->pad, sel->target); -- cgit v1.2.3 From 26d051e301f67cdd2ea3404abb43902f13214efa Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 29 Jun 2017 04:21:35 -0400 Subject: media: exynos4-is: fimc-is-i2c: constify dev_pm_ops structures dev_pm_ops are not supposed to change at runtime. All functions working with dev_pm_ops provided by work with const dev_pm_ops. So mark the non-const structs as const. File size before: text data bss dec hex filename 1195 376 0 1571 623 fimc-is-i2c.o File size After adding 'const': text data bss dec hex filename 1403 176 0 1579 62b fimc-is-i2c.o Signed-off-by: Arvind Yadav Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-is-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c index 2f559663e51e..70dd4852b2b9 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c +++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c @@ -130,7 +130,7 @@ static int fimc_is_i2c_resume(struct device *dev) } #endif -static struct dev_pm_ops fimc_is_i2c_pm_ops = { +static const struct dev_pm_ops fimc_is_i2c_pm_ops = { SET_RUNTIME_PM_OPS(fimc_is_i2c_runtime_suspend, fimc_is_i2c_runtime_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(fimc_is_i2c_suspend, fimc_is_i2c_resume) -- cgit v1.2.3 From 06f8152027765e55da3afc23d87c5fdaf9e7a686 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 20 Jun 2017 09:14:43 -0400 Subject: media: v4l2-fwnode: link_frequency is an optional property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v4l2_fwnode_endpoint_alloc_parse() is intended as a replacement for v4l2_fwnode_endpoint_parse(). It parses the "link-frequency" property and if the property isn't found, it returns an error. However, "link-frequency" is an optional property and if it does not exist is not an error. Instead, the number of link frequencies is simply zero in that case. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index a4f80ff713c6..5cd2687310fe 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -291,23 +291,23 @@ struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( rval = fwnode_property_read_u64_array(fwnode, "link-frequencies", NULL, 0); - if (rval < 0) - goto out_err; - - vep->link_frequencies = - kmalloc_array(rval, sizeof(*vep->link_frequencies), GFP_KERNEL); - if (!vep->link_frequencies) { - rval = -ENOMEM; - goto out_err; - } + if (rval > 0) { + vep->link_frequencies = + kmalloc_array(rval, sizeof(*vep->link_frequencies), + GFP_KERNEL); + if (!vep->link_frequencies) { + rval = -ENOMEM; + goto out_err; + } - vep->nr_of_link_frequencies = rval; + vep->nr_of_link_frequencies = rval; - rval = fwnode_property_read_u64_array(fwnode, "link-frequencies", - vep->link_frequencies, - vep->nr_of_link_frequencies); - if (rval < 0) - goto out_err; + rval = fwnode_property_read_u64_array( + fwnode, "link-frequencies", vep->link_frequencies, + vep->nr_of_link_frequencies); + if (rval < 0) + goto out_err; + } return vep; -- cgit v1.2.3 From 85f7ff9702bcc5e899bd0bf6b6e383ecb2ac436a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 2 Jun 2017 05:30:02 -0400 Subject: media: v4l2-flash: Use led_classdev instead of led_classdev_flash for indicator The V4L2 flash class initialisation expects struct led_classdev_flash that describes an indicator but only uses struct led_classdev which is a field iled_cdev in the struct. Use struct iled_cdev only. Signed-off-by: Sakari Ailus Reviewed-by: Jacek Anaszewski Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-flash-led-class.c | 19 +++++++------------ drivers/staging/greybus/light.c | 4 ++-- include/media/v4l2-flash-led-class.h | 6 +++--- 3 files changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 7b8288108e8a..6d69119ff097 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -110,7 +110,7 @@ static void v4l2_flash_set_led_brightness(struct v4l2_flash *v4l2_flash, led_set_brightness_sync(&v4l2_flash->fled_cdev->led_cdev, brightness); } else { - led_set_brightness_sync(&v4l2_flash->iled_cdev->led_cdev, + led_set_brightness_sync(v4l2_flash->iled_cdev, brightness); } } @@ -133,7 +133,7 @@ static int v4l2_flash_update_led_brightness(struct v4l2_flash *v4l2_flash, return 0; led_cdev = &v4l2_flash->fled_cdev->led_cdev; } else { - led_cdev = &v4l2_flash->iled_cdev->led_cdev; + led_cdev = v4l2_flash->iled_cdev; } ret = led_update_brightness(led_cdev); @@ -529,8 +529,7 @@ static int v4l2_flash_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct v4l2_flash *v4l2_flash = v4l2_subdev_to_v4l2_flash(sd); struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; struct led_classdev *led_cdev = &fled_cdev->led_cdev; - struct led_classdev_flash *iled_cdev = v4l2_flash->iled_cdev; - struct led_classdev *led_cdev_ind = NULL; + struct led_classdev *led_cdev_ind = v4l2_flash->iled_cdev; int ret = 0; if (!v4l2_fh_is_singular(&fh->vfh)) @@ -543,9 +542,7 @@ static int v4l2_flash_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_unlock(&led_cdev->led_access); - if (iled_cdev) { - led_cdev_ind = &iled_cdev->led_cdev; - + if (led_cdev_ind) { mutex_lock(&led_cdev_ind->led_access); led_sysfs_disable(led_cdev_ind); @@ -578,7 +575,7 @@ static int v4l2_flash_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct v4l2_flash *v4l2_flash = v4l2_subdev_to_v4l2_flash(sd); struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; struct led_classdev *led_cdev = &fled_cdev->led_cdev; - struct led_classdev_flash *iled_cdev = v4l2_flash->iled_cdev; + struct led_classdev *led_cdev_ind = v4l2_flash->iled_cdev; int ret = 0; if (!v4l2_fh_is_singular(&fh->vfh)) @@ -593,9 +590,7 @@ static int v4l2_flash_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_unlock(&led_cdev->led_access); - if (iled_cdev) { - struct led_classdev *led_cdev_ind = &iled_cdev->led_cdev; - + if (led_cdev_ind) { mutex_lock(&led_cdev_ind->led_access); led_sysfs_enable(led_cdev_ind); mutex_unlock(&led_cdev_ind->led_access); @@ -614,7 +609,7 @@ static const struct v4l2_subdev_ops v4l2_flash_subdev_ops; struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev_flash *iled_cdev, + struct led_classdev *iled_cdev, const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config) { diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index 861a249e6ef1..129ceed39829 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -536,7 +536,7 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) struct device *dev = &connection->bundle->dev; struct v4l2_flash_config *sd_cfg; struct led_classdev_flash *fled; - struct led_classdev_flash *iled = NULL; + struct led_classdev *iled = NULL; struct gb_channel *channel_torch, *channel_ind, *channel_flash; int ret = 0; @@ -553,7 +553,7 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) if (channel_ind) { __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA, &sd_cfg->indicator_intensity); - iled = &channel_ind->fled; + iled = &channel_ind->fled.led_cdev; } channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH); diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h index f9dcd54c1745..54e31a805a88 100644 --- a/include/media/v4l2-flash-led-class.h +++ b/include/media/v4l2-flash-led-class.h @@ -85,7 +85,7 @@ struct v4l2_flash_config { */ struct v4l2_flash { struct led_classdev_flash *fled_cdev; - struct led_classdev_flash *iled_cdev; + struct led_classdev *iled_cdev; const struct v4l2_flash_ops *ops; struct v4l2_subdev sd; @@ -124,7 +124,7 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c) struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev_flash *iled_cdev, + struct led_classdev *iled_cdev, const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config); @@ -140,7 +140,7 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash); static inline struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev_flash *iled_cdev, + struct led_classdev *iled_cdev, const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config) { -- cgit v1.2.3 From 52740975f3751c02ece88b2ee2e183aff7503cdf Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 8 Jun 2017 07:19:49 -0400 Subject: media: v4l2-flash: Flash ops aren't mandatory None of the flash operations are mandatory and therefore there should be no need for the flash ops structure either. Accept NULL. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Reviewed-by: Jacek Anaszewski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-flash-led-class.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 6d69119ff097..aabc85dbb8b5 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -18,7 +18,7 @@ #include #define has_flash_op(v4l2_flash, op) \ - (v4l2_flash && v4l2_flash->ops->op) + (v4l2_flash && v4l2_flash->ops && v4l2_flash->ops->op) #define call_flash_op(v4l2_flash, op, arg) \ (has_flash_op(v4l2_flash, op) ? \ @@ -299,7 +299,6 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, struct v4l2_flash_ctrl_data *ctrl_init_data) { struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; - const struct led_flash_ops *fled_cdev_ops = fled_cdev->ops; struct led_classdev *led_cdev = &fled_cdev->led_cdev; struct v4l2_ctrl_config *ctrl_cfg; u32 mask; @@ -376,7 +375,7 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, } /* Init STROBE_STATUS ctrl data */ - if (fled_cdev_ops->strobe_get) { + if (has_flash_op(fled_cdev, strobe_get)) { ctrl_init_data[STROBE_STATUS].cid = V4L2_CID_FLASH_STROBE_STATUS; ctrl_cfg = &ctrl_init_data[STROBE_STATUS].config; @@ -386,7 +385,7 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, } /* Init FLASH_TIMEOUT ctrl data */ - if (fled_cdev_ops->timeout_set) { + if (has_flash_op(fled_cdev, timeout_set)) { ctrl_init_data[FLASH_TIMEOUT].cid = V4L2_CID_FLASH_TIMEOUT; ctrl_cfg = &ctrl_init_data[FLASH_TIMEOUT].config; __lfs_to_v4l2_ctrl_config(&fled_cdev->timeout, ctrl_cfg); @@ -394,7 +393,7 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, } /* Init FLASH_INTENSITY ctrl data */ - if (fled_cdev_ops->flash_brightness_set) { + if (has_flash_op(fled_cdev, flash_brightness_set)) { ctrl_init_data[FLASH_INTENSITY].cid = V4L2_CID_FLASH_INTENSITY; ctrl_cfg = &ctrl_init_data[FLASH_INTENSITY].config; __lfs_to_v4l2_ctrl_config(&fled_cdev->brightness, ctrl_cfg); @@ -618,7 +617,7 @@ struct v4l2_flash *v4l2_flash_init( struct v4l2_subdev *sd; int ret; - if (!fled_cdev || !ops || !config) + if (!fled_cdev || !config) return ERR_PTR(-EINVAL); led_cdev = &fled_cdev->led_cdev; -- cgit v1.2.3 From c8dbe3181b80dbb1f3e6c9f27da9bb3c1459c656 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 18 Jul 2017 11:51:35 -0400 Subject: media: v4l: omap3isp: Get the parallel bus type from DT The OMAP3 ISP supports both external and embedded BT.656 synchronization for parallel buses. It currently gets the bus type information from the source subdev through the .g_mbus_config() operation, but should instead get it from DT as that's the authoritative source of bus configuration information. Signed-off-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 1 + drivers/media/platform/omap3isp/ispccdc.c | 8 +------- drivers/media/platform/omap3isp/omap3isp.h | 2 ++ 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 2de7a27bb0e5..79aff6b989a1 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2042,6 +2042,7 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); buscfg->bus.parallel.data_pol = !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); + buscfg->bus.parallel.bt656 = vep.bus_type == V4L2_MBUS_BT656; break; case ISP_OF_PHY_CSIPHY1: diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 7207558d722c..4947876cfadf 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1139,15 +1139,9 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); if (ccdc->input == CCDC_INPUT_PARALLEL) { - struct v4l2_mbus_config cfg; - int ret; - - ret = v4l2_subdev_call(sensor, video, g_mbus_config, &cfg); - if (!ret) - ccdc->bt656 = cfg.type == V4L2_MBUS_BT656; - parcfg = &((struct isp_bus_cfg *)sensor->host_priv) ->bus.parallel; + ccdc->bt656 = parcfg->bt656; } /* CCDC_PAD_SINK */ diff --git a/drivers/media/platform/omap3isp/omap3isp.h b/drivers/media/platform/omap3isp/omap3isp.h index 3c26f9a3f508..dfd3cbe26ccd 100644 --- a/drivers/media/platform/omap3isp/omap3isp.h +++ b/drivers/media/platform/omap3isp/omap3isp.h @@ -46,6 +46,7 @@ enum isp_interface_type { * 0 - Positive, 1 - Negative * @data_pol: Data polarity * 0 - Normal, 1 - One's complement + * @bt656: Data contain BT.656 embedded synchronization */ struct isp_parallel_cfg { unsigned int data_lane_shift:3; @@ -54,6 +55,7 @@ struct isp_parallel_cfg { unsigned int vs_pol:1; unsigned int fld_pol:1; unsigned int data_pol:1; + unsigned int bt656:1; }; enum { -- cgit v1.2.3 From d9ba7bd98a1a95675cc97ef87e911376d4bff6a8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 19 Jul 2017 22:41:20 -0400 Subject: media: ov5640: Remove unneeded gpiod NULL check The gpiod API checks for NULL descriptors, so there is no need to duplicate the check in the driver. Signed-off-by: Fabio Estevam Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5640.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 1f5b483cf334..39a2269c0bee 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -1524,8 +1524,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor) static void ov5640_power(struct ov5640_dev *sensor, bool enable) { - if (sensor->pwdn_gpio) - gpiod_set_value(sensor->pwdn_gpio, enable ? 0 : 1); + gpiod_set_value(sensor->pwdn_gpio, enable ? 0 : 1); } static void ov5640_reset(struct ov5640_dev *sensor) -- cgit v1.2.3 From 87a420c8f6ffa85edc1e95f7e84a75932f3bec52 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 06:06:12 -0400 Subject: media: coda: disable BWB only while decoding on CODA 960 Disabling the BWB works around hangups observed while decoding. Since no issues have been observed while encoding, and disabling BWB also reduces encoding performance, reenable it for encoding. Fixes: 89ed025d5c53 ("[media] coda: disable BWB for all codecs on CODA 960") Reported-by: Ian Arkver Signed-off-by: Philipp Zabel Tested-by: Ian Arkver Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 3992ef2bda42..dcb3419d5126 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -73,7 +73,7 @@ MODULE_PARM_DESC(disable_vdoa, "Disable Video Data Order Adapter tiled to raster static int enable_bwb = 0; module_param(enable_bwb, int, 0644); -MODULE_PARM_DESC(enable_bwb, "Enable BWB unit, may crash on certain streams"); +MODULE_PARM_DESC(enable_bwb, "Enable BWB unit for decoding, may crash on certain streams"); void coda_write(struct coda_dev *dev, u32 data, u32 reg) { @@ -1988,7 +1988,13 @@ static int coda_open(struct file *file) ctx->idx = idx; switch (dev->devtype->product) { case CODA_960: - if (enable_bwb) + /* + * Enabling the BWB when decoding can hang the firmware with + * certain streams. The issue was tracked as ENGR00293425 by + * Freescale. As a workaround, disable BWB for all decoders. + * The enable_bwb module parameter allows to override this. + */ + if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; /* fallthrough */ case CODA_7541: @@ -2192,7 +2198,8 @@ static int coda_hw_init(struct coda_dev *dev) CODA_REG_BIT_STREAM_CTRL); } if (dev->devtype->product == CODA_960) - coda_write(dev, 1 << 12, CODA_REG_BIT_FRAME_MEM_CTRL); + coda_write(dev, CODA9_FRAME_ENABLE_BWB, + CODA_REG_BIT_FRAME_MEM_CTRL); else coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL); -- cgit v1.2.3 From 9e6b1dae37810bec45c80d478636b254db377eaa Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 11:25:38 -0400 Subject: media: coda: explicitly request exclusive reset control Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Signed-off-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index dcb3419d5126..40f31038249d 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2527,7 +2527,8 @@ static int coda_probe(struct platform_device *pdev) return ret; } - dev->rstc = devm_reset_control_get_optional(&pdev->dev, NULL); + dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, + NULL); if (IS_ERR(dev->rstc)) { ret = PTR_ERR(dev->rstc); dev_err(&pdev->dev, "failed get reset control: %d\n", ret); -- cgit v1.2.3 From 14330d7f08bab92029f0c95c70fe200e8d76b31e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 12:34:20 -0400 Subject: media: imx: csi: enable double write reduction For 4:2:0 subsampled YUV formats, avoid chroma overdraw by only writing chroma for even lines. Reduces necessary write memory bandwidth by 25%. Signed-off-by: Philipp Zabel Acked-by: Steve Longerbeam Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-media-csi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index a2d26693912e..f2d64d1eeff8 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -357,6 +357,8 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 && sensor_ep->bus.parallel.bus_width >= 16); passthrough_bits = 16; + /* Skip writing U and V components to odd rows */ + ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch); break; case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: -- cgit v1.2.3 From 4c7089ee66026f38275d43e26d9da6e2945af6f9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Jul 2017 06:48:33 -0400 Subject: media: media-device: set driver_version directly Don't use driver_version from struct media_device, just return LINUX_VERSION_CODE as the other media subsystems do. The driver_version field in struct media_device will be removed in the following patches. Signed-off-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 2 +- include/media/media-device.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index fce91b543c14..7ff8e2d5bb07 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -71,7 +71,7 @@ static int media_device_get_info(struct media_device *dev, info->media_version = MEDIA_API_VERSION; info->hw_revision = dev->hw_revision; - info->driver_version = dev->driver_version; + info->driver_version = LINUX_VERSION_CODE; return 0; } diff --git a/include/media/media-device.h b/include/media/media-device.h index 6896266031b9..7ae200d89a9f 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -249,11 +249,6 @@ void media_device_cleanup(struct media_device *mdev); * driver-specific format. When possible the revision should be formatted * with the KERNEL_VERSION() macro. * - * - &media_entity.driver_version is formatted with the KERNEL_VERSION() - * macro. The version minor must be incremented when new features are added - * to the userspace API without breaking binary compatibility. The version - * major must be incremented when binary compatibility is broken. - * * .. note:: * * #) Upon successful registration a character device named media[0-9]+ is created. The device major and minor numbers are dynamic. The model name is exported as a sysfs attribute. -- cgit v1.2.3 From 4b3b11048d88b52d859c20f8ed5aaab87d199513 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Jul 2017 04:53:30 -0400 Subject: media: s3c-camif: don't set driver_version This field will be removed as it is not needed anymore. Signed-off-by: Hans Verkuil Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 8f0414041e81..c4ab63986c8f 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -317,7 +317,6 @@ static int camif_media_dev_init(struct camif_dev *camif) ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X"); strlcpy(md->bus_info, "platform", sizeof(md->bus_info)); md->hw_revision = ip_rev; - md->driver_version = LINUX_VERSION_CODE; md->dev = camif->dev; -- cgit v1.2.3 From 71269bf607bcb6e51970c90428e8a912857ea728 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Jul 2017 04:54:12 -0400 Subject: media: uvc: don't set driver_version This field will be removed as it is not needed anymore. Signed-off-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 70842c5af05b..4f463bf2b877 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2096,7 +2096,6 @@ static int uvc_probe(struct usb_interface *intf, sizeof(dev->mdev.serial)); strcpy(dev->mdev.bus_info, udev->devpath); dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); - dev->mdev.driver_version = LINUX_VERSION_CODE; media_device_init(&dev->mdev); dev->vdev.mdev = &dev->mdev; -- cgit v1.2.3 From be2d2dcdbec272fa5a9125842ae3f7977ea73a76 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Jul 2017 04:54:40 -0400 Subject: media: atomisp2: don't set driver_version This field will be removed as it is not needed anymore. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c index 2f49562377e6..663aa916e3ca 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c @@ -1099,9 +1099,7 @@ atomisp_load_firmware(struct atomisp_device *isp) fw_path = "shisp_2400b0_v21.bin"; if (!fw_path) { - dev_err(isp->dev, - "Unsupported driver_version 0x%x, hw_revision 0x%x\n", - isp->media_dev.driver_version, + dev_err(isp->dev, "Unsupported hw_revision 0x%x\n", isp->media_dev.hw_revision); return NULL; } @@ -1249,8 +1247,6 @@ static int atomisp_pci_probe(struct pci_dev *dev, /* This is not a true PCI device on SoC, so the delay is not needed. */ isp->pdev->d3_delay = 0; - isp->media_dev.driver_version = LINUX_VERSION_CODE; - switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { case ATOMISP_PCI_DEVICE_SOC_MRFLD: isp->media_dev.hw_revision = -- cgit v1.2.3 From 2bd8682375f3a79e463d8840794d2872b02d755b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 Jul 2017 04:49:44 -0400 Subject: media: media-device: remove driver_version Since the driver_version field in struct media_device is no longer used, just remove it. Signed-off-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 3 --- include/media/media-device.h | 2 -- 2 files changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7ff8e2d5bb07..979e4307d248 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -833,8 +833,6 @@ void media_device_pci_init(struct media_device *mdev, mdev->hw_revision = (pci_dev->subsystem_vendor << 16) | pci_dev->subsystem_device; - mdev->driver_version = LINUX_VERSION_CODE; - media_device_init(mdev); } EXPORT_SYMBOL_GPL(media_device_pci_init); @@ -862,7 +860,6 @@ void __media_device_usb_init(struct media_device *mdev, strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); usb_make_path(udev, mdev->bus_info, sizeof(mdev->bus_info)); mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); - mdev->driver_version = LINUX_VERSION_CODE; media_device_init(mdev); } diff --git a/include/media/media-device.h b/include/media/media-device.h index 7ae200d89a9f..bcc6ec434f1f 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -68,7 +68,6 @@ struct media_device_ops { * @serial: Device serial number (optional) * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision - * @driver_version: Device driver version * @topology_version: Monotonic counter for storing the version of the graph * topology. Should be incremented each time the topology changes. * @id: Unique ID used on the last registered graph object @@ -134,7 +133,6 @@ struct media_device { char serial[40]; char bus_info[32]; u32 hw_revision; - u32 driver_version; u64 topology_version; -- cgit v1.2.3 From 6c2c188f35c61c8eee71ec6d07524ce122c06539 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 28 Jul 2017 03:25:06 -0400 Subject: media: drop use of MEDIA_API_VERSION Set media_version to LINUX_VERSION_CODE, just as we did for driver_version. Nobody ever rememebers to update the version number, but LINUX_VERSION_CODE will always be updated. Move the MEDIA_API_VERSION define to the ifndef __KERNEL__ section of the media.h header. That way kernelspace can't accidentally start to use it again. Signed-off-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-device.c | 4 ++-- include/uapi/linux/media.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 979e4307d248..e79f72b8b858 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -69,9 +69,9 @@ static int media_device_get_info(struct media_device *dev, strlcpy(info->serial, dev->serial, sizeof(info->serial)); strlcpy(info->bus_info, dev->bus_info, sizeof(info->bus_info)); - info->media_version = MEDIA_API_VERSION; + info->media_version = LINUX_VERSION_CODE; + info->driver_version = info->media_version; info->hw_revision = dev->hw_revision; - info->driver_version = LINUX_VERSION_CODE; return 0; } diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index fac96c64fe51..4865f1e71339 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -30,8 +30,6 @@ #include #include -#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) - struct media_device_info { char driver[16]; char model[32]; @@ -187,6 +185,9 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER + +/* Obsolete symbol for media_version, no longer used in the kernel */ +#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) #endif /* Entity flags */ -- cgit v1.2.3 From eada47597b97abe956570ea47120df8833f64574 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 27 Jul 2017 11:39:14 -0400 Subject: media: v4l2-tpg-core.c: fix typo in bt2020_full matrix My eye fell on this wrong coefficient in the bt2020_full matrix. The bt2020 matrix (limited range) is OK. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 3dd22da7e17d..a772976cfe26 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -615,7 +615,7 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, static const int bt2020_full[3][3] = { { COEFF(0.2627, 255), COEFF(0.6780, 255), COEFF(0.0593, 255) }, { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255) }, - { COEFF(0.5, 255), COEFF(-0.4698, 255), COEFF(-0.0402, 255) }, + { COEFF(0.5, 255), COEFF(-0.4598, 255), COEFF(-0.0402, 255) }, }; static const int bt2020c[4] = { COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224), -- cgit v1.2.3 From 011dfab80543019d01f66665734f50f5a4b26e6d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 18 Jul 2017 23:34:18 -0400 Subject: media: ov7670: Return the real error code When devm_clk_get() fails the real error code should be propagated, instead of always returning -EPROBE_DEFER. Signed-off-by: Fabio Estevam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7670.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 7270c68ed18a..552a881e24da 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1614,7 +1614,7 @@ static int ov7670_probe(struct i2c_client *client, info->clk = devm_clk_get(&client->dev, "xclk"); if (IS_ERR(info->clk)) - return -EPROBE_DEFER; + return PTR_ERR(info->clk); clk_prepare_enable(info->clk); ret = ov7670_init_gpio(client, info); -- cgit v1.2.3 From 1fc86ad052fc051639df1f60faeb619dbe567e07 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 18 Jul 2017 23:34:19 -0400 Subject: media: ov7670: Check the return value from clk_prepare_enable() clk_prepare_enable() may fail, so we should better check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7670.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 552a881e24da..e88549f0e704 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -1615,7 +1615,9 @@ static int ov7670_probe(struct i2c_client *client, info->clk = devm_clk_get(&client->dev, "xclk"); if (IS_ERR(info->clk)) return PTR_ERR(info->clk); - clk_prepare_enable(info->clk); + ret = clk_prepare_enable(info->clk); + if (ret) + return ret; ret = ov7670_init_gpio(client, info); if (ret) -- cgit v1.2.3 From e706b9ed6905b9276c3770c2c0683b7fd3c63860 Mon Sep 17 00:00:00 2001 From: Tiffany Lin Date: Wed, 19 Jul 2017 05:22:52 -0400 Subject: media: mtk-vcodec: fix vp9 decode error Fix The camera has a blurry screen phenomenon when we video chat with apprtc using vp9 codec Signed-off-by: Tiffany Lin Reviewed-by: Wu-Cheng Li Tested-by: Wu-Cheng Li Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/mtk-vcodec/vdec/vdec_vp9_if.c | 37 ++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c index 1daee1207469..bc8349bc2e80 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c @@ -31,6 +31,7 @@ #define MAX_NUM_REF_FRAMES 8 #define VP9_MAX_FRM_BUF_NUM 9 #define VP9_MAX_FRM_BUF_NODE_NUM (VP9_MAX_FRM_BUF_NUM * 2) +#define VP9_SEG_ID_SZ 0x12000 /** * struct vp9_dram_buf - contains buffer info for vpu @@ -132,6 +133,7 @@ struct vp9_sf_ref_fb { * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W) * @mv_buf : motion vector working buffer (AP-W, VPU-R) * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W) + * @seg_id_buf : segmentation map working buffer (AP-W, VPU-R) */ struct vdec_vp9_vsi { unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ]; @@ -167,11 +169,14 @@ struct vdec_vp9_vsi { struct vp9_dram_buf mv_buf; struct vp9_ref_buf frm_refs[REFS_PER_FRAME]; + struct vp9_dram_buf seg_id_buf; + }; /* * struct vdec_vp9_inst - vp9 decode instance * @mv_buf : working buffer for mv + * @seg_id_buf : working buffer for segmentation map * @dec_fb : vdec_fb node to link fb to different fb_xxx_list * @available_fb_node_list : current available vdec_fb node * @fb_use_list : current used or referenced vdec_fb @@ -187,6 +192,7 @@ struct vdec_vp9_vsi { */ struct vdec_vp9_inst { struct mtk_vcodec_mem mv_buf; + struct mtk_vcodec_mem seg_id_buf; struct vdec_fb_node dec_fb[VP9_MAX_FRM_BUF_NODE_NUM]; struct list_head available_fb_node_list; @@ -388,13 +394,11 @@ static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) vsi->buf_h); mem = &inst->mv_buf; - if (mem->va) mtk_vcodec_mem_free(inst->ctx, mem); mem->size = ((vsi->buf_w / 64) * (vsi->buf_h / 64) + 2) * 36 * 16; - result = mtk_vcodec_mem_alloc(inst->ctx, mem); if (result) { mem->size = 0; @@ -406,6 +410,24 @@ static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst) vsi->mv_buf.pa = (unsigned long)mem->dma_addr; vsi->mv_buf.sz = (unsigned int)mem->size; + + mem = &inst->seg_id_buf; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + + mem->size = VP9_SEG_ID_SZ; + result = mtk_vcodec_mem_alloc(inst->ctx, mem); + if (result) { + mem->size = 0; + mtk_vcodec_err(inst, "Cannot allocate seg_id_buf"); + return false; + } + /* Set the va again */ + vsi->seg_id_buf.va = (unsigned long)mem->va; + vsi->seg_id_buf.pa = (unsigned long)mem->dma_addr; + vsi->seg_id_buf.sz = (unsigned int)mem->size; + + vp9_free_all_sf_ref_fb(inst); vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst); @@ -653,6 +675,12 @@ static void vp9_reset(struct vdec_vp9_inst *inst) inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va; inst->vsi->mv_buf.pa = (unsigned long)inst->mv_buf.dma_addr; inst->vsi->mv_buf.sz = (unsigned long)inst->mv_buf.size; + + /* Set the va again, since vpu_dec_reset will clear seg_id_buf in vpu */ + inst->vsi->seg_id_buf.va = (unsigned long)inst->seg_id_buf.va; + inst->vsi->seg_id_buf.pa = (unsigned long)inst->seg_id_buf.dma_addr; + inst->vsi->seg_id_buf.sz = (unsigned long)inst->seg_id_buf.size; + } static void init_all_fb_lists(struct vdec_vp9_inst *inst) @@ -752,6 +780,10 @@ static void vdec_vp9_deinit(unsigned long h_vdec) if (mem->va) mtk_vcodec_mem_free(inst->ctx, mem); + mem = &inst->seg_id_buf; + if (mem->va) + mtk_vcodec_mem_free(inst->ctx, mem); + vp9_free_all_sf_ref_fb(inst); vp9_free_inst(inst); } @@ -848,6 +880,7 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, vsi->sf_frm_sz[idx]); } } + memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size); ret = vpu_dec_start(&inst->vpu, data, 3); if (ret) { mtk_vcodec_err(inst, "vpu_dec_start failed"); -- cgit v1.2.3 From 1a48e102826ee852c4600872c37cbc01cec47237 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 11:25:40 -0400 Subject: media: stm32-dcmi: explicitly request exclusive reset control Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Cc: Maxime Coquelin Cc: Alexandre Torgue Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 24ef88809d7c..c2168b5c7810 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -1209,7 +1209,7 @@ static int dcmi_probe(struct platform_device *pdev) if (!dcmi) return -ENOMEM; - dcmi->rstc = devm_reset_control_get(&pdev->dev, NULL); + dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(dcmi->rstc)) { dev_err(&pdev->dev, "Could not get reset control\n"); return -ENODEV; -- cgit v1.2.3 From 0a7a13452b72d7b54a627cc7c66257ad135ff46e Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Fri, 21 Jul 2017 11:49:40 -0400 Subject: media: ov9650: fix coding style Fix a bunch of coding style issues detected by checkpatch --strict. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov9650.c | 59 ++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 2de2fbb13b85..e8dea28c33b3 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -484,6 +484,7 @@ static int ov965x_set_default_gamma_curve(struct ov965x *ov965x) for (i = 0; i < ARRAY_SIZE(gamma_curve); i++) { int ret = ov965x_write(ov965x->client, addr, gamma_curve[i]); + if (ret < 0) return ret; addr++; @@ -503,6 +504,7 @@ static int ov965x_set_color_matrix(struct ov965x *ov965x) for (i = 0; i < ARRAY_SIZE(mtx); i++) { int ret = ov965x_write(ov965x->client, addr, mtx[i]); + if (ret < 0) return ret; addr++; @@ -611,7 +613,7 @@ static int ov965x_set_banding_filter(struct ov965x *ov965x, int value) } if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED) return 0; - if (WARN_ON(ov965x->fiv == NULL)) + if (WARN_ON(!ov965x->fiv)) return -EINVAL; /* Set minimal exposure time for 50/60 HZ lighting */ if (value == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) @@ -999,44 +1001,47 @@ static int ov965x_initialize_controls(struct ov965x *ov965x) /* Auto/manual white balance */ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, - V4L2_CID_AUTO_WHITE_BALANCE, - 0, 1, 1, 1); + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 1); ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, 0x80); ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, - 0, 0xff, 1, 0x80); + 0, 0xff, 1, 0x80); /* Auto/manual exposure */ - ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, - V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO); + ctrls->auto_exp = + v4l2_ctrl_new_std_menu(hdl, ops, + V4L2_CID_EXPOSURE_AUTO, + V4L2_EXPOSURE_MANUAL, 0, + V4L2_EXPOSURE_AUTO); /* Exposure time, in 100 us units. min/max is updated dynamically. */ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, - V4L2_CID_EXPOSURE_ABSOLUTE, - 2, 1500, 1, 500); + V4L2_CID_EXPOSURE_ABSOLUTE, + 2, 1500, 1, 500); /* Auto/manual gain */ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, - 0, 1, 1, 1); + 0, 1, 1, 1); ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, - 16, 64 * (16 + 15), 1, 64 * 16); + 16, 64 * (16 + 15), 1, 64 * 16); ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, - -2, 2, 1, 0); + -2, 2, 1, 0); ctrls->brightness = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, - -3, 3, 1, 0); + -3, 3, 1, 0); ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, - 0, 32, 1, 6); + 0, 32, 1, 6); ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0); ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - ctrls->light_freq = v4l2_ctrl_new_std_menu(hdl, ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, ~0x7, - V4L2_CID_POWER_LINE_FREQUENCY_50HZ); + ctrls->light_freq = + v4l2_ctrl_new_std_menu(hdl, ops, + V4L2_CID_POWER_LINE_FREQUENCY, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ, ~0x7, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ); v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, - test_pattern_menu); + ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, + test_pattern_menu); if (hdl->error) { ret = hdl->error; v4l2_ctrl_handler_free(hdl); @@ -1121,7 +1126,6 @@ static int __ov965x_set_frame_interval(struct ov965x *ov965x, u64 req_int, err, min_err = ~0ULL; unsigned int i; - if (fi->interval.denominator == 0) return -EINVAL; @@ -1165,7 +1169,8 @@ static int ov965x_s_frame_interval(struct v4l2_subdev *sd, return ret; } -static int ov965x_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ov965x_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct ov965x *ov965x = to_ov965x(sd); @@ -1209,7 +1214,8 @@ static void __ov965x_try_frame_size(struct v4l2_mbus_framefmt *mf, *size = match; } -static int ov965x_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ov965x_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { unsigned int index = ARRAY_SIZE(ov965x_formats); @@ -1231,7 +1237,7 @@ static int ov965x_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config mutex_lock(&ov965x->lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg != NULL) { + if (cfg) { mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); *mf = fmt->format; } @@ -1362,7 +1368,8 @@ static int ov965x_s_stream(struct v4l2_subdev *sd, int on) */ static int ov965x_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *mf = + v4l2_subdev_get_try_format(sd, fh->pad, 0); ov965x_get_default_format(mf); return 0; @@ -1470,7 +1477,7 @@ static int ov965x_probe(struct i2c_client *client, struct ov965x *ov965x; int ret; - if (pdata == NULL) { + if (!pdata) { dev_err(&client->dev, "platform data not specified\n"); return -EINVAL; } -- cgit v1.2.3 From 457a1a7ac0f7b6a9c3b968a72c85116f17f24f86 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Fri, 21 Jul 2017 11:49:41 -0400 Subject: media: ov9655: fix missing mutex_destroy() Fix missing mutex_destroy() when probe fails and when driver is removed. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov9650.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index e8dea28c33b3..6ffb460e8589 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1505,13 +1505,13 @@ static int ov965x_probe(struct i2c_client *client, ret = ov965x_configure_gpios(ov965x, pdata); if (ret < 0) - return ret; + goto err_mutex; ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) - return ret; + goto err_mutex; ret = ov965x_initialize_controls(ov965x); if (ret < 0) @@ -1537,16 +1537,20 @@ err_ctrls: v4l2_ctrl_handler_free(sd->ctrl_handler); err_me: media_entity_cleanup(&sd->entity); +err_mutex: + mutex_destroy(&ov965x->lock); return ret; } static int ov965x_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov965x *ov965x = to_ov965x(sd); v4l2_async_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); media_entity_cleanup(&sd->entity); + mutex_destroy(&ov965x->lock); return 0; } -- cgit v1.2.3 From d74ce54885714f1427966d9ad7f6c60358358dba Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 21 Jul 2017 12:20:23 -0400 Subject: media: v4l: omap_vout: vrfb: include linux/slab.h Without this header, we get a build error in some configurations: drivers/media/platform/omap/omap_vout_vrfb.c: In function 'omap_vout_setup_vrfb_bufs': drivers/media/platform/omap/omap_vout_vrfb.c:143:26: error: implicit declaration of function 'kzalloc'; did you mean 'vzalloc'? [-Werror=implicit-function-declaration] Fixes: 6a1560ecaa8c ("media: v4l: omap_vout: vrfb: Convert to dmaengine") Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/omap_vout_vrfb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index 45a553d4f5b2..040eacc45168 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 4560cb4a0c9969260356b0ac9473c45bb1c1101d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 21 Jul 2017 12:21:25 -0400 Subject: media: imx: add VIDEO_V4L2_SUBDEV_API dependency Without this, I get a build error: drivers/staging/media/imx/imx-media-vdic.c: In function '__vdic_get_fmt': drivers/staging/media/imx/imx-media-vdic.c:554:10: error: implicit declaration of function 'v4l2_subdev_get_try_format'; did you mean 'v4l2_subdev_notify_event'? [-Werror=implicit-function-declaration] Fixes: e130291212df ("[media] media: Add i.MX media core driver") Signed-off-by: Arnd Bergmann Acked-by: Steve Longerbeam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index 7eff50bcea39..719508fcb0e9 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig @@ -1,6 +1,7 @@ config VIDEO_IMX_MEDIA tristate "i.MX5/6 V4L2 media core driver" depends on MEDIA_CONTROLLER && VIDEO_V4L2 && ARCH_MXC && IMX_IPUV3_CORE + depends on VIDEO_V4L2_SUBDEV_API select V4L2_FWNODE ---help--- Say yes here to enable support for video4linux media controller -- cgit v1.2.3 From b54a5c2dc83a96d6a9e1b114fd47c5b5dc8e8be5 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sat, 22 Jul 2017 17:21:41 -0400 Subject: media: imx: prpencvf: enable double write reduction For the write channels with 4:2:0 subsampled YUV formats, avoid chroma overdraw by only writing chroma for even lines. Reduces necessary write memory bandwidth by at least 25% (more with rotation enabled). Signed-off-by: Steve Longerbeam Acked-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-ic-prpencvf.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index ed363fe3b3d0..42c5045e397e 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -374,6 +374,17 @@ static int prp_setup_channel(struct prp_priv *priv, image.phys0 = addr0; image.phys1 = addr1; + if (channel == priv->out_ch || channel == priv->rot_out_ch) { + switch (image.pix.pixelformat) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: + /* Skip writing U and V components to odd rows */ + ipu_cpmem_skip_odd_chroma_rows(channel); + break; + } + } + ret = ipu_cpmem_set_image(channel, &image); if (ret) return ret; -- cgit v1.2.3 From 2f05db96c69bce376c2330f6fa7197a8a2abc8b2 Mon Sep 17 00:00:00 2001 From: JB Van Puyvelde Date: Sun, 23 Jul 2017 11:35:55 -0400 Subject: media: staging: imx: fix non-static declarations Add static keywords to fix this kind of sparse warnings: warning: symbol 'imx_t_vcm_timing' was not declared. Should it be static? Signed-off-by: JB Van Puyvelde Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/imx/imx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.c b/drivers/staging/media/atomisp/i2c/imx/imx.c index 408a7b945153..fb32cb2f2dd1 100644 --- a/drivers/staging/media/atomisp/i2c/imx/imx.c +++ b/drivers/staging/media/atomisp/i2c/imx/imx.c @@ -1084,7 +1084,7 @@ static int imx_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val) return 0; } -int imx_vcm_power_up(struct v4l2_subdev *sd) +static int imx_vcm_power_up(struct v4l2_subdev *sd) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->power_up) @@ -1092,7 +1092,7 @@ int imx_vcm_power_up(struct v4l2_subdev *sd) return 0; } -int imx_vcm_power_down(struct v4l2_subdev *sd) +static int imx_vcm_power_down(struct v4l2_subdev *sd) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->power_down) @@ -1100,7 +1100,7 @@ int imx_vcm_power_down(struct v4l2_subdev *sd) return 0; } -int imx_vcm_init(struct v4l2_subdev *sd) +static int imx_vcm_init(struct v4l2_subdev *sd) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->init) @@ -1108,7 +1108,7 @@ int imx_vcm_init(struct v4l2_subdev *sd) return 0; } -int imx_t_focus_vcm(struct v4l2_subdev *sd, u16 val) +static int imx_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->t_focus_vcm) @@ -1116,14 +1116,15 @@ int imx_t_focus_vcm(struct v4l2_subdev *sd, u16 val) return 0; } -int imx_t_focus_abs(struct v4l2_subdev *sd, s32 value) +static int imx_t_focus_abs(struct v4l2_subdev *sd, s32 value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->t_focus_abs) return dev->vcm_driver->t_focus_abs(sd, value); return 0; } -int imx_t_focus_rel(struct v4l2_subdev *sd, s32 value) + +static int imx_t_focus_rel(struct v4l2_subdev *sd, s32 value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->t_focus_rel) @@ -1131,7 +1132,7 @@ int imx_t_focus_rel(struct v4l2_subdev *sd, s32 value) return 0; } -int imx_q_focus_status(struct v4l2_subdev *sd, s32 *value) +static int imx_q_focus_status(struct v4l2_subdev *sd, s32 *value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->q_focus_status) @@ -1139,7 +1140,7 @@ int imx_q_focus_status(struct v4l2_subdev *sd, s32 *value) return 0; } -int imx_q_focus_abs(struct v4l2_subdev *sd, s32 *value) +static int imx_q_focus_abs(struct v4l2_subdev *sd, s32 *value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->q_focus_abs) @@ -1147,7 +1148,7 @@ int imx_q_focus_abs(struct v4l2_subdev *sd, s32 *value) return 0; } -int imx_t_vcm_slew(struct v4l2_subdev *sd, s32 value) +static int imx_t_vcm_slew(struct v4l2_subdev *sd, s32 value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->t_vcm_slew) @@ -1155,7 +1156,7 @@ int imx_t_vcm_slew(struct v4l2_subdev *sd, s32 value) return 0; } -int imx_t_vcm_timing(struct v4l2_subdev *sd, s32 value) +static int imx_t_vcm_timing(struct v4l2_subdev *sd, s32 value) { struct imx_device *dev = to_imx_sensor(sd); if (dev->vcm_driver && dev->vcm_driver->t_vcm_timing) @@ -2105,8 +2106,7 @@ imx_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param) return 0; } -int -imx_g_frame_interval(struct v4l2_subdev *sd, +static int imx_g_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval) { struct imx_device *dev = to_imx_sensor(sd); -- cgit v1.2.3 From f3c8e4b5a71a170a8bcd555a5933b9a070b6819a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 23 Jul 2017 21:36:54 -0400 Subject: media: ti-vpe: cal: use of_graph_get_remote_endpoint() Now, we can use of_graph_get_remote_endpoint(). Let's use it. Signed-off-by: Kuninori Morimoto Reviewed-by: Sylwester Nawrocki Acked-by: Benoit Parrot Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/cal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 177faa36bc16..0c7ddf894a69 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1702,7 +1702,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) asd->match_type = V4L2_ASYNC_MATCH_FWNODE; asd->match.fwnode.fwnode = of_fwnode_handle(sensor_node); - remote_ep = of_parse_phandle(ep_node, "remote-endpoint", 0); + remote_ep = of_graph_get_remote_endpoint(ep_node); if (!remote_ep) { ctx_dbg(3, ctx, "can't get remote-endpoint\n"); goto cleanup_exit; -- cgit v1.2.3 From fa31c1175f0ef7c9b2820d122c77ee1ed50f20c8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jul 2017 11:36:45 -0400 Subject: media: i2c: add KConfig dependencies The new ov5670 driver fails to build when VIDEO_V4L2_SUBDEV_API or MEDIA_CONTROLLER are disabled: drivers/media/i2c/ov5670.c: In function 'ov5670_open': drivers/media/i2c/ov5670.c:1917:5: error: implicit declaration of function 'v4l2_subdev_get_try_format'; did you mean 'v4l2_subdev_notify_event'? [-Werror=implicit-function-declaration] v4l2_subdev_get_try_format(sd, fh->pad, 0); ^~~~~~~~~~~~~~~~~~~~~~~~~~ v4l2_subdev_notify_event drivers/media/i2c/ov5670.c:1917:38: error: 'struct v4l2_subdev_fh' has no member named 'pad' v4l2_subdev_get_try_format(sd, fh->pad, 0); ^~ drivers/media/i2c/ov5670.c: In function 'ov5670_do_get_pad_format': drivers/media/i2c/ov5670.c:2198:17: error: invalid type argument of unary '*' (have 'int') fmt->format = *v4l2_subdev_get_try_format(&ov5670->sd, cfg, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fmt->pad); ~~~~~~~~~ drivers/media/i2c/ov5670.c: At top level: drivers/media/i2c/ov5670.c:2444:19: error: 'v4l2_subdev_link_validate' undeclared here (not in a function); did you mean 'v4l2_subdev_init'? .link_validate = v4l2_subdev_link_validate, ^~~~~~~~~~~~~~~~~~~~~~~~~ v4l2_subdev_init drivers/media/i2c/ov5670.c: In function 'ov5670_probe': drivers/media/i2c/ov5670.c:2492:12: error: 'struct v4l2_subdev' has no member named 'entity' This adds both to the Kconfig entry. Fixes: 5de35c9b8dcd ("media: i2c: Add Omnivision OV5670 5M sensor support") Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index a05e40ecba7c..94153895fcd4 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -618,8 +618,9 @@ config VIDEO_OV6650 config VIDEO_OV5670 tristate "OmniVision OV5670 sensor support" - depends on I2C && VIDEO_V4L2 + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on MEDIA_CAMERA_SUPPORT + depends on MEDIA_CONTROLLER select V4L2_FWNODE ---help--- This is a Video4Linux2 sensor-level driver for the OmniVision -- cgit v1.2.3 From f57cdbd34cb435ed3b7d38be6276f7f389e8d0e9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jul 2017 11:39:14 -0400 Subject: media: v4l: use WARN_ON(1) instead of __WARN() __WARN() cannot be used in portable code, since it is only available on some architectures and configurations: drivers/media/platform/pxa_camera.c: In function 'pxa_mbus_config_compatible': drivers/media/platform/pxa_camera.c:642:3: error: implicit declaration of function '__WARN'; did you mean '__WALL'? [-Werror=implicit-function-declaration] The common way to express an unconditional warning is WARN_ON(1), so let's use that here. Fixes: 97bbdf02d905 ("media: v4l: Add support for CSI-1 and CCP2 busses") Signed-off-by: Arnd Bergmann Acked-by: Sakari Ailus Acked-by: Pavel Machek Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/pxa_camera.c | 2 +- drivers/media/platform/soc_camera/soc_mediabus.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 3898a5cd8664..0d4af6d91ffc 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -639,7 +639,7 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; default: - __WARN(); + WARN_ON(1); return -EINVAL; } return 0; diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c index 43192d80beef..0ad4b28266e4 100644 --- a/drivers/media/platform/soc_camera/soc_mediabus.c +++ b/drivers/media/platform/soc_camera/soc_mediabus.c @@ -509,7 +509,7 @@ unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg, V4L2_MBUS_CSI2_CONTINUOUS_CLOCK); return (!mipi_lanes || !mipi_clock) ? 0 : common_flags; default: - __WARN(); + WARN_ON(1); return -EINVAL; } return 0; -- cgit v1.2.3 From 0f59b2d0138b936d8d65ecbe193d512196199806 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 26 Jul 2017 11:23:07 -0400 Subject: media: v4l: omap_vout: vrfb: initialize DMA flags Passing uninitialized flags into device_prep_interleaved_dma is clearly a bad idea, and we get a compiler warning for it: drivers/media/platform/omap/omap_vout_vrfb.c: In function 'omap_vout_prepare_vrfb': drivers/media/platform/omap/omap_vout_vrfb.c:273:5: error: 'flags' may be used uninitialized in this function [-Werror=maybe-uninitialized] It seems that the OMAP dmaengine ignores the flags, but we should pick the right ones anyway. This sets the flags I guessed based on what other drivers used, and Peter confirmed that they are the right ones. Fixes: 6a1560ecaa8c ("media: v4l: omap_vout: vrfb: Convert to dmaengine") Acked-by: Peter Ujfalusi Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap/omap_vout_vrfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index 040eacc45168..123c2b26a933 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c @@ -234,7 +234,7 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, struct videobuf_buffer *vb) { struct dma_async_tx_descriptor *tx; - enum dma_ctrl_flags flags; + enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; struct dma_chan *chan = vout->vrfb_dma_tx.chan; struct dma_device *dmadev = chan->device; struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; -- cgit v1.2.3 From 07ca2d4c0f44086eb38bbe0b3f86a379a701e2dc Mon Sep 17 00:00:00 2001 From: Hirokazu Honda Date: Tue, 30 May 2017 05:49:01 -0400 Subject: media: vb2: core: Lower the log level of debug outputs Some debug output whose log level is set 1 flooded the log. Their log level is lowered to find the important log easily. Signed-off-by: Hirokazu Honda Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 14f83cecfa92..0924594989b4 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1139,7 +1139,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) continue; } - dprintk(1, "buffer for plane %d changed\n", plane); + dprintk(3, "buffer for plane %d changed\n", plane); if (!reacquired) { reacquired = true; @@ -1298,7 +1298,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) /* Fill buffer information for the userspace */ call_void_bufop(q, fill_user_buffer, vb, pb); - dprintk(1, "prepare of buffer %d succeeded\n", vb->index); + dprintk(2, "prepare of buffer %d succeeded\n", vb->index); return ret; } @@ -1428,7 +1428,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) return ret; } - dprintk(1, "qbuf of buffer %d succeeded\n", vb->index); + dprintk(2, "qbuf of buffer %d succeeded\n", vb->index); return 0; } EXPORT_SYMBOL_GPL(vb2_core_qbuf); @@ -1476,7 +1476,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) } if (nonblocking) { - dprintk(1, "nonblocking and no buffers to dequeue, will not wait\n"); + dprintk(3, "nonblocking and no buffers to dequeue, will not wait\n"); return -EAGAIN; } @@ -1623,7 +1623,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, /* go back to dequeued state */ __vb2_dqbuf(vb); - dprintk(1, "dqbuf of buffer %d, with state %d\n", + dprintk(2, "dqbuf of buffer %d, with state %d\n", vb->index, vb->state); return 0; -- cgit v1.2.3 From 05ad2b6dbbb03031a7761e6607a152deafbc39e9 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Wed, 14 Jun 2017 09:47:15 -0400 Subject: media: i2c: fix semicolon.cocci warnings drivers/media/i2c/ov5670.c:2033:2-3: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci CC: Chiranjeevi Rapolu Signed-off-by: Fengguang Wu Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5670.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 7de80645dd6f..8d8e16c5c49f 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -2030,7 +2030,7 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl) dev_info(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); break; - }; + } pm_runtime_put(&client->dev); -- cgit v1.2.3 From 0b2e9e7947e7bfd08c512e15ae02645cf9cd38c5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 11 Jul 2017 09:18:35 -0400 Subject: media: staging/imx: remove confusing IS_ERR_OR_NULL usage While looking at a compiler warning, I noticed the use of IS_ERR_OR_NULL, which is generally a sign of a bad API design and should be avoided. In this driver, this is fairly easy, we can simply stop storing error pointers in persistent structures, and change the two functions that might return either a NULL pointer or an error code to consistently return error pointers when failing. of_parse_subdev() now separates the error code and the pointer it looks up, to clarify the interface. There are two cases where this function originally returns 'NULL', and I have changed that to '0' for success to keep the current behavior, though returning an error would also make sense there. Fixes: e130291212df ("[media] media: Add i.MX media core driver") Signed-off-by: Arnd Bergmann Reviewed-by: Philipp Zabel Tested-by: Philipp Zabel Reviewed-by: Steve Longerbeam Tested-by: Steve Longerbeam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-ic-prpencvf.c | 41 ++++++++++++----------- drivers/staging/media/imx/imx-media-csi.c | 30 ++++++++++------- drivers/staging/media/imx/imx-media-dev.c | 4 +-- drivers/staging/media/imx/imx-media-of.c | 50 ++++++++++++++++------------- drivers/staging/media/imx/imx-media-vdic.c | 37 +++++++++++---------- 5 files changed, 90 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 42c5045e397e..fa2c120168b6 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -134,19 +134,19 @@ static inline struct prp_priv *sd_to_priv(struct v4l2_subdev *sd) static void prp_put_ipu_resources(struct prp_priv *priv) { - if (!IS_ERR_OR_NULL(priv->ic)) + if (priv->ic) ipu_ic_put(priv->ic); priv->ic = NULL; - if (!IS_ERR_OR_NULL(priv->out_ch)) + if (priv->out_ch) ipu_idmac_put(priv->out_ch); priv->out_ch = NULL; - if (!IS_ERR_OR_NULL(priv->rot_in_ch)) + if (priv->rot_in_ch) ipu_idmac_put(priv->rot_in_ch); priv->rot_in_ch = NULL; - if (!IS_ERR_OR_NULL(priv->rot_out_ch)) + if (priv->rot_out_ch) ipu_idmac_put(priv->rot_out_ch); priv->rot_out_ch = NULL; } @@ -154,43 +154,46 @@ static void prp_put_ipu_resources(struct prp_priv *priv) static int prp_get_ipu_resources(struct prp_priv *priv) { struct imx_ic_priv *ic_priv = priv->ic_priv; + struct ipu_ic *ic; + struct ipuv3_channel *out_ch, *rot_in_ch, *rot_out_ch; int ret, task = ic_priv->task_id; priv->ipu = priv->md->ipu[ic_priv->ipu_id]; - priv->ic = ipu_ic_get(priv->ipu, task); - if (IS_ERR(priv->ic)) { + ic = ipu_ic_get(priv->ipu, task); + if (IS_ERR(ic)) { v4l2_err(&ic_priv->sd, "failed to get IC\n"); - ret = PTR_ERR(priv->ic); + ret = PTR_ERR(ic); goto out; } + priv->ic = ic; - priv->out_ch = ipu_idmac_get(priv->ipu, - prp_channel[task].out_ch); - if (IS_ERR(priv->out_ch)) { + out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].out_ch); + if (IS_ERR(out_ch)) { v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", prp_channel[task].out_ch); - ret = PTR_ERR(priv->out_ch); + ret = PTR_ERR(out_ch); goto out; } + priv->out_ch = out_ch; - priv->rot_in_ch = ipu_idmac_get(priv->ipu, - prp_channel[task].rot_in_ch); - if (IS_ERR(priv->rot_in_ch)) { + rot_in_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_in_ch); + if (IS_ERR(rot_in_ch)) { v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", prp_channel[task].rot_in_ch); - ret = PTR_ERR(priv->rot_in_ch); + ret = PTR_ERR(rot_in_ch); goto out; } + priv->rot_in_ch = rot_in_ch; - priv->rot_out_ch = ipu_idmac_get(priv->ipu, - prp_channel[task].rot_out_ch); - if (IS_ERR(priv->rot_out_ch)) { + rot_out_ch = ipu_idmac_get(priv->ipu, prp_channel[task].rot_out_ch); + if (IS_ERR(rot_out_ch)) { v4l2_err(&ic_priv->sd, "could not get IDMAC channel %u\n", prp_channel[task].rot_out_ch); - ret = PTR_ERR(priv->rot_out_ch); + ret = PTR_ERR(rot_out_ch); goto out; } + priv->rot_out_ch = rot_out_ch; return 0; out: diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index f2d64d1eeff8..552a030f3232 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -122,11 +122,11 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev) static void csi_idmac_put_ipu_resources(struct csi_priv *priv) { - if (!IS_ERR_OR_NULL(priv->idmac_ch)) + if (priv->idmac_ch) ipu_idmac_put(priv->idmac_ch); priv->idmac_ch = NULL; - if (!IS_ERR_OR_NULL(priv->smfc)) + if (priv->smfc) ipu_smfc_put(priv->smfc); priv->smfc = NULL; } @@ -134,23 +134,27 @@ static void csi_idmac_put_ipu_resources(struct csi_priv *priv) static int csi_idmac_get_ipu_resources(struct csi_priv *priv) { int ch_num, ret; + struct ipu_smfc *smfc; + struct ipuv3_channel *idmac_ch; ch_num = IPUV3_CHANNEL_CSI0 + priv->smfc_id; - priv->smfc = ipu_smfc_get(priv->ipu, ch_num); - if (IS_ERR(priv->smfc)) { + smfc = ipu_smfc_get(priv->ipu, ch_num); + if (IS_ERR(smfc)) { v4l2_err(&priv->sd, "failed to get SMFC\n"); - ret = PTR_ERR(priv->smfc); + ret = PTR_ERR(smfc); goto out; } + priv->smfc = smfc; - priv->idmac_ch = ipu_idmac_get(priv->ipu, ch_num); - if (IS_ERR(priv->idmac_ch)) { + idmac_ch = ipu_idmac_get(priv->ipu, ch_num); + if (IS_ERR(idmac_ch)) { v4l2_err(&priv->sd, "could not get IDMAC channel %u\n", ch_num); - ret = PTR_ERR(priv->idmac_ch); + ret = PTR_ERR(idmac_ch); goto out; } + priv->idmac_ch = idmac_ch; return 0; out: @@ -1585,6 +1589,7 @@ static int csi_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, static int csi_registered(struct v4l2_subdev *sd) { struct csi_priv *priv = v4l2_get_subdevdata(sd); + struct ipu_csi *csi; int i, ret; u32 code; @@ -1592,11 +1597,12 @@ static int csi_registered(struct v4l2_subdev *sd) priv->md = dev_get_drvdata(sd->v4l2_dev->dev); /* get handle to IPU CSI */ - priv->csi = ipu_csi_get(priv->ipu, priv->csi_id); - if (IS_ERR(priv->csi)) { + csi = ipu_csi_get(priv->ipu, priv->csi_id); + if (IS_ERR(csi)) { v4l2_err(&priv->sd, "failed to get CSI%d\n", priv->csi_id); - return PTR_ERR(priv->csi); + return PTR_ERR(csi); } + priv->csi = csi; for (i = 0; i < CSI_NUM_PADS; i++) { priv->pad[i].flags = (i == CSI_SINK_PAD) ? @@ -1665,7 +1671,7 @@ static void csi_unregistered(struct v4l2_subdev *sd) if (priv->fim) imx_media_fim_free(priv->fim); - if (!IS_ERR_OR_NULL(priv->csi)) + if (priv->csi) ipu_csi_put(priv->csi); } diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index 48cbc7716758..d96f4512224f 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -87,11 +87,11 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd, if (pdev) devname = dev_name(&pdev->dev); - /* return NULL if this subdev already added */ + /* return -EEXIST if this subdev already added */ if (imx_media_find_async_subdev(imxmd, np, devname)) { dev_dbg(imxmd->md.dev, "%s: already added %s\n", __func__, np ? np->name : devname); - imxsd = NULL; + imxsd = ERR_PTR(-EEXIST); goto out; } diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c index b026fe66467c..12df09f52490 100644 --- a/drivers/staging/media/imx/imx-media-of.c +++ b/drivers/staging/media/imx/imx-media-of.c @@ -100,9 +100,9 @@ static void of_get_remote_pad(struct device_node *epnode, } } -static struct imx_media_subdev * +static int of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, - bool is_csi_port) + bool is_csi_port, struct imx_media_subdev **subdev) { struct imx_media_subdev *imxsd; int i, num_pads, ret; @@ -110,13 +110,25 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, if (!of_device_is_available(sd_np)) { dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__, sd_np->name); - return NULL; + *subdev = NULL; + /* unavailable is not an error */ + return 0; } /* register this subdev with async notifier */ imxsd = imx_media_add_async_subdev(imxmd, sd_np, NULL); - if (IS_ERR_OR_NULL(imxsd)) - return imxsd; + ret = PTR_ERR_OR_ZERO(imxsd); + if (ret) { + if (ret == -EEXIST) { + /* already added, everything is fine */ + *subdev = NULL; + return 0; + } + + /* other error, can't continue */ + return ret; + } + *subdev = imxsd; if (is_csi_port) { /* @@ -137,10 +149,11 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, } else { num_pads = of_get_port_count(sd_np); if (num_pads != 1) { + /* confused, but no reason to give up here */ dev_warn(imxmd->md.dev, "%s: unknown device %s with %d ports\n", __func__, sd_np->name, num_pads); - return NULL; + return 0; } /* @@ -151,7 +164,7 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, } if (imxsd->num_sink_pads >= num_pads) - return ERR_PTR(-EINVAL); + return -EINVAL; imxsd->num_src_pads = num_pads - imxsd->num_sink_pads; @@ -191,20 +204,15 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, ret = of_add_pad_link(imxmd, pad, sd_np, remote_np, i, remote_pad); - if (ret) { - imxsd = ERR_PTR(ret); + if (ret) break; - } if (i < imxsd->num_sink_pads) { /* follow sink endpoints upstream */ - remote_imxsd = of_parse_subdev(imxmd, - remote_np, - false); - if (IS_ERR(remote_imxsd)) { - imxsd = remote_imxsd; + ret = of_parse_subdev(imxmd, remote_np, + false, &remote_imxsd); + if (ret) break; - } } of_node_put(remote_np); @@ -212,14 +220,14 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np, if (port != sd_np) of_node_put(port); - if (IS_ERR(imxsd)) { + if (ret) { of_node_put(remote_np); of_node_put(epnode); break; } } - return imxsd; + return ret; } int imx_media_of_parse(struct imx_media_dev *imxmd, @@ -236,11 +244,9 @@ int imx_media_of_parse(struct imx_media_dev *imxmd, if (!csi_np) break; - lcsi = of_parse_subdev(imxmd, csi_np, true); - if (IS_ERR(lcsi)) { - ret = PTR_ERR(lcsi); + ret = of_parse_subdev(imxmd, csi_np, true, &lcsi); + if (ret) goto err_put; - } ret = of_property_read_u32(csi_np, "reg", &csi_id); if (ret) { diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 7eabdc4aa79f..433474d58e3e 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -126,15 +126,15 @@ struct vdic_priv { static void vdic_put_ipu_resources(struct vdic_priv *priv) { - if (!IS_ERR_OR_NULL(priv->vdi_in_ch_p)) + if (priv->vdi_in_ch_p) ipu_idmac_put(priv->vdi_in_ch_p); priv->vdi_in_ch_p = NULL; - if (!IS_ERR_OR_NULL(priv->vdi_in_ch)) + if (priv->vdi_in_ch) ipu_idmac_put(priv->vdi_in_ch); priv->vdi_in_ch = NULL; - if (!IS_ERR_OR_NULL(priv->vdi_in_ch_n)) + if (priv->vdi_in_ch_n) ipu_idmac_put(priv->vdi_in_ch_n); priv->vdi_in_ch_n = NULL; @@ -146,40 +146,43 @@ static void vdic_put_ipu_resources(struct vdic_priv *priv) static int vdic_get_ipu_resources(struct vdic_priv *priv) { int ret, err_chan; + struct ipuv3_channel *ch; + struct ipu_vdi *vdi; priv->ipu = priv->md->ipu[priv->ipu_id]; - priv->vdi = ipu_vdi_get(priv->ipu); - if (IS_ERR(priv->vdi)) { + vdi = ipu_vdi_get(priv->ipu); + if (IS_ERR(vdi)) { v4l2_err(&priv->sd, "failed to get VDIC\n"); - ret = PTR_ERR(priv->vdi); + ret = PTR_ERR(vdi); goto out; } + priv->vdi = vdi; if (!priv->csi_direct) { - priv->vdi_in_ch_p = ipu_idmac_get(priv->ipu, - IPUV3_CHANNEL_MEM_VDI_PREV); - if (IS_ERR(priv->vdi_in_ch_p)) { + ch = ipu_idmac_get(priv->ipu, IPUV3_CHANNEL_MEM_VDI_PREV); + if (IS_ERR(ch)) { err_chan = IPUV3_CHANNEL_MEM_VDI_PREV; - ret = PTR_ERR(priv->vdi_in_ch_p); + ret = PTR_ERR(ch); goto out_err_chan; } + priv->vdi_in_ch_p = ch; - priv->vdi_in_ch = ipu_idmac_get(priv->ipu, - IPUV3_CHANNEL_MEM_VDI_CUR); - if (IS_ERR(priv->vdi_in_ch)) { + ch = ipu_idmac_get(priv->ipu, IPUV3_CHANNEL_MEM_VDI_CUR); + if (IS_ERR(ch)) { err_chan = IPUV3_CHANNEL_MEM_VDI_CUR; - ret = PTR_ERR(priv->vdi_in_ch); + ret = PTR_ERR(ch); goto out_err_chan; } + priv->vdi_in_ch = ch; - priv->vdi_in_ch_n = ipu_idmac_get(priv->ipu, - IPUV3_CHANNEL_MEM_VDI_NEXT); + ch = ipu_idmac_get(priv->ipu, IPUV3_CHANNEL_MEM_VDI_NEXT); if (IS_ERR(priv->vdi_in_ch_n)) { err_chan = IPUV3_CHANNEL_MEM_VDI_NEXT; - ret = PTR_ERR(priv->vdi_in_ch_n); + ret = PTR_ERR(ch); goto out_err_chan; } + priv->vdi_in_ch_n = ch; } return 0; -- cgit v1.2.3 From 45340c14e55aef16b5b535e9b7c1ebfea050a314 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 28 Jul 2017 09:26:25 -0400 Subject: media: coda: fix decoder sequence init escape flag coda_command_sync calls coda_command_async, which writes the bit_stream_param context variable into the BIT_STREAM_PARAM register, overwriting the previously set value during coda_start_decoding. Instead of writing to the register, set bit_stream_param to ensure that the decoder sequence init command is executed with the escape flag set. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-bit.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 95e4b74d5dd0..291c40933935 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -1639,9 +1639,6 @@ static int __coda_start_decoding(struct coda_ctx *ctx) ctx->frm_dis_flg = 0; coda_write(dev, 0, CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx)); - coda_write(dev, CODA_BIT_DEC_SEQ_INIT_ESCAPE, - CODA_REG_BIT_BIT_STREAM_PARAM); - coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START); coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE); val = 0; @@ -1676,18 +1673,18 @@ static int __coda_start_decoding(struct coda_ctx *ctx) if (dev->devtype->product != CODA_960) coda_write(dev, 0, CODA_CMD_DEC_SEQ_SRC_SIZE); - if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) { + ctx->bit_stream_param = CODA_BIT_DEC_SEQ_INIT_ESCAPE; + ret = coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT); + ctx->bit_stream_param = 0; + if (ret) { v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n"); - coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); - return -ETIMEDOUT; + return ret; } ctx->initialized = 1; /* Update kfifo out pointer from coda bitstream read pointer */ coda_kfifo_sync_from_device(ctx); - coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); - if (coda_read(dev, CODA_RET_DEC_SEQ_SUCCESS) == 0) { v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_SEQ_INIT failed, error code = %d\n", -- cgit v1.2.3 From e047c5e0dad14c7b6d1470dc2e237a7a55252233 Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Fri, 28 Jul 2017 09:26:47 -0400 Subject: media: coda: reduce iram size to leave space for suspend to ram The on-chip SRAM of i.MX6S is only 128 KiB. 4 KiB of that are allocated for suspend to RAM since commit df595746fa69 ("ARM: imx: add suspend in ocram support for i.mx6q"). Reduce the requested IRAM size to 124 KiB to avoid an allocation failure that causes the coda driver to not use the SRAM at all. Signed-off-by: Jan Luebbe Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 40f31038249d..27c613752fbf 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2443,7 +2443,7 @@ static const struct coda_devtype coda_devdata[] = { .num_vdevs = ARRAY_SIZE(coda9_video_devices), .workbuf_size = 80 * 1024, .tempbuf_size = 204 * 1024, - .iram_size = 0x20000, + .iram_size = 0x1f000, /* leave 4k for suspend code */ }, }; -- cgit v1.2.3 From 079c6eaf80d9fb6d9cea7ad71e590c8425c1b0fe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 8 Aug 2017 06:56:29 -0400 Subject: media: v4l2-tpg: fix the SMPTE-2084 transfer function The SMPTE-2084 transfer functions maps to the luminance range of 0-10000 cd/m^2. Other transfer functions use the traditional range of 0-100 cd/m^2. I didn't take this into account so the luminance was off by a factor of 100. Since qv4l2 made the same mistake in reverse I never noticed this until I tested with actual SMPTE-2084 video. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c | 150 ++++++++++++------------ 1 file changed, 78 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c index 9bcbd318489b..5b5f95c38fe1 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c @@ -646,14 +646,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][5] = { 3248, 944, 1094 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][6] = { 1017, 967, 3168 }, [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3802, 3805, 2602 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 3806, 3797 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][3] = { 1780, 3812, 2592 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3820, 2215, 3796 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3824, 2409, 2574 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2491, 2435, 3795 }, - [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][1] = { 1815, 1818, 910 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 1819, 1811 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][3] = { 472, 1825, 904 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][4] = { 1832, 686, 1810 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][5] = { 1835, 794, 893 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][6] = { 843, 809, 1810 }, + [V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 }, @@ -702,14 +702,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][5] = { 3248, 944, 1094 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][6] = { 1017, 967, 3168 }, [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3802, 3805, 2602 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 3806, 3797 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][3] = { 1780, 3812, 2592 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3820, 2215, 3796 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3824, 2409, 2574 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2491, 2435, 3795 }, - [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][1] = { 1815, 1818, 910 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][2] = { 0, 1819, 1811 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][3] = { 472, 1825, 904 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][4] = { 1832, 686, 1810 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][5] = { 1835, 794, 893 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][6] = { 843, 809, 1810 }, + [V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 }, @@ -758,14 +758,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][5] = { 3175, 1084, 1084 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3175 }, [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2563 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][2] = { 2563, 3798, 3798 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][3] = { 2563, 3798, 2563 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][4] = { 3798, 2563, 3798 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][5] = { 3798, 2563, 2563 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3798 }, - [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 886 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][2] = { 886, 1812, 1812 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][3] = { 886, 1812, 886 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][4] = { 1812, 886, 1812 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 }, + [V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][1] = { 2892, 3034, 910 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_709][2] = { 1715, 2916, 2914 }, @@ -814,14 +814,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][5] = { 2765, 1182, 1190 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][6] = { 1270, 0, 3094 }, [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][1] = { 3784, 3825, 2879 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][2] = { 3351, 3791, 3790 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][3] = { 3311, 3819, 2815 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][4] = { 3659, 1900, 3777 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][5] = { 3640, 2662, 2669 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][6] = { 2743, 0, 3769 }, - [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][1] = { 1800, 1836, 1090 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][2] = { 1436, 1806, 1805 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][3] = { 1405, 1830, 1047 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][4] = { 1691, 527, 1793 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][5] = { 1674, 947, 952 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][6] = { 1000, 0, 1786 }, + [V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 464 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_709][2] = { 786, 2939, 2939 }, @@ -870,14 +870,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][5] = { 3126, 1084, 1084 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3188 }, [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2476 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][2] = { 2782, 3798, 3798 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][3] = { 2782, 3798, 2476 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][4] = { 3780, 2563, 3803 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][5] = { 3780, 2563, 2563 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3803 }, - [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 833 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][2] = { 1025, 1812, 1812 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][3] = { 1025, 1812, 833 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][4] = { 1796, 886, 1816 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][5] = { 1796, 886, 886 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1816 }, + [V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 547 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_709][2] = { 547, 2939, 2939 }, @@ -926,14 +926,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 3175, 1084, 1084 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3175 }, [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2563 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 2563, 3798, 3798 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 2563, 3798, 2563 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 3798, 2563, 3798 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 3798, 2563, 2563 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3798 }, - [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 886 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 886, 1812, 1812 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 886, 1812, 886 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1812, 886, 1812 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 }, + [V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 }, [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 }, @@ -982,14 +982,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 }, [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 }, [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 3798, 3798, 2778 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 3306, 3798, 3798 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 3306, 3798, 2778 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 3661, 2563, 3781 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 3661, 2563, 2563 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 2563, 2563, 3781 }, - [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 }, + [V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 }, @@ -1038,14 +1038,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][5] = { 2690, 1431, 1182 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][6] = { 1318, 1153, 3051 }, [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][1] = { 3780, 3793, 2984 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][2] = { 3406, 3768, 3791 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][3] = { 3359, 3763, 2939 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][4] = { 3636, 2916, 3760 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][5] = { 3609, 2880, 2661 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][6] = { 2786, 2633, 3753 }, - [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][1] = { 1796, 1808, 1163 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][2] = { 1480, 1786, 1806 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][3] = { 1443, 1781, 1131 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][4] = { 1670, 1116, 1778 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][5] = { 1648, 1091, 947 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][6] = { 1028, 929, 1772 }, + [V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][1] = { 2936, 2934, 992 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_709][2] = { 1159, 2890, 2916 }, @@ -1094,14 +1094,14 @@ const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_S [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][5] = { 3018, 1276, 1184 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][6] = { 1100, 1107, 3071 }, [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][0] = { 3798, 3798, 3798 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][1] = { 3797, 3796, 2938 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][2] = { 3049, 3783, 3791 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][3] = { 3044, 3782, 2887 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][4] = { 3741, 2765, 3768 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][5] = { 3740, 2749, 2663 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][6] = { 2580, 2587, 3760 }, - [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][7] = { 2563, 2563, 2563 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][1] = { 1811, 1810, 1131 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][2] = { 1210, 1799, 1806 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][3] = { 1206, 1798, 1096 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][4] = { 1762, 1014, 1785 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][5] = { 1761, 1004, 948 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][6] = { 896, 901, 1778 }, + [V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 }, }; #else @@ -1225,6 +1225,12 @@ static double transfer_rgb_to_smpte2084(double v) const double c2 = 32.0 * 2413.0 / 4096.0; const double c3 = 32.0 * 2392.0 / 4096.0; + /* + * The RGB input maps to the luminance range 0-100 cd/m^2, while + * SMPTE-2084 maps values to the luminance range of 0-10000 cd/m^2. + * Hence the factor 100. + */ + v /= 100.0; v = pow(v, m1); return pow((c1 + c2 * v) / (1 + c3 * v), m2); } -- cgit v1.2.3 From 57b796365500fe7acdea383ef6682a4a9479e2d7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Aug 2017 06:41:52 -0400 Subject: media: adv*/vivid/pulse8/rainshadow: cec: use CEC_CAP_DEFAULTS Use the new CEC_CAP_DEFAULTS define in the adv, vivid, pulse8 and rainshadow CEC drivers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7511.c | 3 +-- drivers/media/i2c/adv7604.c | 3 +-- drivers/media/i2c/adv7842.c | 3 +-- drivers/media/platform/vivid/vivid-cec.c | 3 +-- drivers/media/usb/pulse8-cec/pulse8-cec.c | 3 +-- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index ccc478605643..aef02c994df9 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1927,8 +1927,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * #if IS_ENABLED(CONFIG_VIDEO_ADV7511_CEC) state->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, - state, dev_name(&client->dev), CEC_CAP_TRANSMIT | - CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | CEC_CAP_RC, + state, dev_name(&client->dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) { diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 660bacb8f7d9..324d39bd68d0 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3515,8 +3515,7 @@ static int adv76xx_probe(struct i2c_client *client, #if IS_ENABLED(CONFIG_VIDEO_ADV7604_CEC) state->cec_adap = cec_allocate_adapter(&adv76xx_cec_adap_ops, state, dev_name(&client->dev), - CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV76XX_MAX_ADDRS); + CEC_CAP_DEFAULTS, ADV76XX_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) goto err_entity; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 303effda1a2e..1bf6129fab62 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3568,8 +3568,7 @@ static int adv7842_probe(struct i2c_client *client, #if IS_ENABLED(CONFIG_VIDEO_ADV7842_CEC) state->cec_adap = cec_allocate_adapter(&adv7842_cec_adap_ops, state, dev_name(&client->dev), - CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV7842_MAX_ADDRS); + CEC_CAP_DEFAULTS, ADV7842_MAX_ADDRS); err = PTR_ERR_OR_ZERO(state->cec_adap); if (err) goto err_entity; diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index e15705758969..43992fa92a88 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -219,8 +219,7 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, bool is_source) { char name[sizeof(dev->vid_out_dev.name) + 2]; - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL; snprintf(name, sizeof(name), "%s%d", is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index 993117c04935..95f616f94004 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -642,8 +642,7 @@ static const struct cec_adap_ops pulse8_cec_adap_ops = { static int pulse8_connect(struct serio *serio, struct serio_driver *drv) { - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; struct pulse8 *pulse8; int err = -ENOMEM; struct cec_log_addrs log_addrs = {}; diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index 30bff4c48f92..6f9681c995a4 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -309,8 +309,7 @@ static const struct cec_adap_ops rain_cec_adap_ops = { static int rain_connect(struct serio *serio, struct serio_driver *drv) { - u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; struct rain *rain; int err = -ENOMEM; struct cec_log_addrs log_addrs = {}; -- cgit v1.2.3 From c33da628de92dc64c11009b885871f963278469a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 6 Aug 2017 07:04:05 -0400 Subject: media: cec-api: log the reason for the -EINVAL in cec_s_mode If cec_debug >= 1 then log why the requested mode returned -EINVAL. It can be hard to debug this since -EINVAL can be returned for many reasons. So this should help. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-api.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 8dd16e263452..00d43d74020f 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -357,34 +357,47 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (copy_from_user(&mode, parg, sizeof(mode))) return -EFAULT; - if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) + if (mode & ~(CEC_MODE_INITIATOR_MSK | CEC_MODE_FOLLOWER_MSK)) { + dprintk(1, "%s: invalid mode bits set\n", __func__); return -EINVAL; + } mode_initiator = mode & CEC_MODE_INITIATOR_MSK; mode_follower = mode & CEC_MODE_FOLLOWER_MSK; if (mode_initiator > CEC_MODE_EXCL_INITIATOR || - mode_follower > CEC_MODE_MONITOR_ALL) + mode_follower > CEC_MODE_MONITOR_ALL) { + dprintk(1, "%s: unknown mode\n", __func__); return -EINVAL; + } if (mode_follower == CEC_MODE_MONITOR_ALL && - !(adap->capabilities & CEC_CAP_MONITOR_ALL)) + !(adap->capabilities & CEC_CAP_MONITOR_ALL)) { + dprintk(1, "%s: MONITOR_ALL not supported\n", __func__); return -EINVAL; + } if (mode_follower == CEC_MODE_MONITOR_PIN && - !(adap->capabilities & CEC_CAP_MONITOR_PIN)) + !(adap->capabilities & CEC_CAP_MONITOR_PIN)) { + dprintk(1, "%s: MONITOR_PIN not supported\n", __func__); return -EINVAL; + } /* Follower modes should always be able to send CEC messages */ if ((mode_initiator == CEC_MODE_NO_INITIATOR || !(adap->capabilities & CEC_CAP_TRANSMIT)) && mode_follower >= CEC_MODE_FOLLOWER && - mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) + mode_follower <= CEC_MODE_EXCL_FOLLOWER_PASSTHRU) { + dprintk(1, "%s: cannot transmit\n", __func__); return -EINVAL; + } /* Monitor modes require CEC_MODE_NO_INITIATOR */ - if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) + if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN) { + dprintk(1, "%s: monitor modes require NO_INITIATOR\n", + __func__); return -EINVAL; + } /* Monitor modes require CAP_NET_ADMIN */ if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN)) -- cgit v1.2.3 From 8c8808e01a2237a50aa7bb9ac7b509c017f45a85 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:17 -0400 Subject: media: marvell-ccic: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/cafe-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index 063fd43f8539..57d2c483ad09 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -612,7 +612,7 @@ static int cafe_pci_resume(struct pci_dev *pdev) #endif /* CONFIG_PM */ -static struct pci_device_id cafe_ids[] = { +static const struct pci_device_id cafe_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) }, { 0, } -- cgit v1.2.3 From af38e42b0441974423e05a5f809ce286e27ac2da Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:18 -0400 Subject: media: netup_unidvb: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index 5c0a4e614413..60e6cd5b3a03 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -1014,7 +1014,7 @@ static void netup_unidvb_finidev(struct pci_dev *pci_dev) } -static struct pci_device_id netup_unidvb_pci_tbl[] = { +static const struct pci_device_id netup_unidvb_pci_tbl[] = { { PCI_DEVICE(0x1b55, 0x18f6) }, /* hw rev. 1.3 */ { PCI_DEVICE(0x1b55, 0x18f7) }, /* hw rev. 1.4 */ { 0, } -- cgit v1.2.3 From 0fcefb39c82febfbb7919c59a581def6281a2f63 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:19 -0400 Subject: media: cx23885: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 02b5ec549369..8f63df1cb418 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2056,7 +2056,7 @@ static void cx23885_finidev(struct pci_dev *pci_dev) kfree(dev); } -static struct pci_device_id cx23885_pci_tbl[] = { +static const struct pci_device_id cx23885_pci_tbl[] = { { /* CX23885 */ .vendor = 0x14f1, -- cgit v1.2.3 From 5a764ed09b0608ec87fd4f1707edd62096405c66 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:20 -0400 Subject: media: meye: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/meye/meye.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 9c4a024745de..0fe76bea2393 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1801,7 +1801,7 @@ static void meye_remove(struct pci_dev *pcidev) printk(KERN_INFO "meye: removed\n"); } -static struct pci_device_id meye_pci_tbl[] = { +static const struct pci_device_id meye_pci_tbl[] = { { PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 }, { } }; -- cgit v1.2.3 From d060296cc0300ae8ed08004ebd3994bf325fa257 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:21 -0400 Subject: media: pluto2: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pluto2/pluto2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c index 74838109afe5..39dcba2b620c 100644 --- a/drivers/media/pci/pluto2/pluto2.c +++ b/drivers/media/pci/pluto2/pluto2.c @@ -770,7 +770,7 @@ static void pluto2_remove(struct pci_dev *pdev) #define PCI_DEVICE_ID_PLUTO2 0x0001 #endif -static struct pci_device_id pluto2_id_table[] = { +static const struct pci_device_id pluto2_id_table[] = { { .vendor = PCI_VENDOR_ID_SCM, .device = PCI_DEVICE_ID_PLUTO2, -- cgit v1.2.3 From 82c055cdc21edf31f8721503ac2c94c571cadf1f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:22 -0400 Subject: media: dm1105: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/dm1105/dm1105.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 36e94f81aba5..190ca9c17237 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -1208,7 +1208,7 @@ static void dm1105_remove(struct pci_dev *pdev) kfree(dev); } -static struct pci_device_id dm1105_id_table[] = { +static const struct pci_device_id dm1105_id_table[] = { { .vendor = PCI_VENDOR_ID_TRIGEM, .device = PCI_DEVICE_ID_DM1105, -- cgit v1.2.3 From f758b2c373eb69e0b6908132129f4f2177ce7331 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:23 -0400 Subject: media: zoran: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/zoran/zoran_card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c index 4680f001653a..a6b9ebd20263 100644 --- a/drivers/media/pci/zoran/zoran_card.c +++ b/drivers/media/pci/zoran/zoran_card.c @@ -130,7 +130,7 @@ MODULE_VERSION(ZORAN_VERSION); .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \ .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) } -static struct pci_device_id zr36067_pci_tbl[] = { +static const struct pci_device_id zr36067_pci_tbl[] = { ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus), ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus), ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10), -- cgit v1.2.3 From a88e7e7a888859e59411b003ea8f2527d787bd51 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:24 -0400 Subject: media: bt8xx: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bt878.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 8aa726651630..a5f52137d306 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -383,7 +383,7 @@ EXPORT_SYMBOL(bt878_device_control); .driver_data = (unsigned long) name \ } -static struct pci_device_id bt878_pci_tbl[] = { +static const struct pci_device_id bt878_pci_tbl[] = { BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"), BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"), BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"), -- cgit v1.2.3 From 70665b3e150d21218f62359db74690f4dc0268f8 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:25 -0400 Subject: media: bt8xx: bttv: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index ed319f18ba48..40110be4e986 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -4388,7 +4388,7 @@ static int bttv_resume(struct pci_dev *pci_dev) } #endif -static struct pci_device_id bttv_pci_tbl[] = { +static const struct pci_device_id bttv_pci_tbl[] = { {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, -- cgit v1.2.3 From a166faadef76dc3437e31e6ff551eefe8308fa6f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:26 -0400 Subject: media: ivtv: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index e8fa99b6c7b4..54dcac4b2229 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -73,7 +73,7 @@ int (*ivtv_ext_init)(struct ivtv *); EXPORT_SYMBOL(ivtv_ext_init); /* add your revision and whatnot here */ -static struct pci_device_id ivtv_pci_tbl[] = { +static const struct pci_device_id ivtv_pci_tbl[] = { {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16, -- cgit v1.2.3 From aaf4882d3dbebe842e394111eeb6f61e28101385 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:27 -0400 Subject: media: cobalt: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index f8e173f3e9e2..98b6cb9505d1 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -36,7 +36,7 @@ #include "cobalt-omnitek.h" /* add your revision and whatnot here */ -static struct pci_device_id cobalt_pci_tbl[] = { +static const struct pci_device_id cobalt_pci_tbl[] = { {PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_COBALT, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} -- cgit v1.2.3 From 78899349b138b608269db78303bce0b2e06ab84d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:28 -0400 Subject: media: b2c2: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/b2c2/flexcop-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c index 6e60decb2198..cc6527e35537 100644 --- a/drivers/media/pci/b2c2/flexcop-pci.c +++ b/drivers/media/pci/b2c2/flexcop-pci.c @@ -415,7 +415,7 @@ static void flexcop_pci_remove(struct pci_dev *pdev) flexcop_device_kfree(fc_pci->fc_dev); } -static struct pci_device_id flexcop_pci_tbl[] = { +static const struct pci_device_id flexcop_pci_tbl[] = { { PCI_DEVICE(0x13d0, 0x2103) }, { }, }; -- cgit v1.2.3 From 52b025b1578f3b2248a59cb6f3f5386da6854d9d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:29 -0400 Subject: media: saa7164: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7164/saa7164-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 75eed4cc4823..fca36a4910c2 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1490,7 +1490,7 @@ static void saa7164_finidev(struct pci_dev *pci_dev) kfree(dev); } -static struct pci_device_id saa7164_pci_tbl[] = { +static const struct pci_device_id saa7164_pci_tbl[] = { { /* SAA7164 */ .vendor = 0x1131, -- cgit v1.2.3 From d2c43ff160e144348e5a820febb6b3c13759924d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:30 -0400 Subject: media: pt1: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/pt1/pt1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index 3219d2f3271e..b6b1a8d20d86 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -1202,7 +1202,7 @@ err: } -static struct pci_device_id pt1_id_table[] = { +static const struct pci_device_id pt1_id_table[] = { { PCI_DEVICE(0x10ee, 0x211a) }, { PCI_DEVICE(0x10ee, 0x222a) }, { }, -- cgit v1.2.3 From a7c8f87d626c7100087d4576f0545537aeb9b7f6 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:31 -0400 Subject: media: mantis: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/mantis_cards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index cdefffc16d9e..adc980d33711 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -281,7 +281,7 @@ static void mantis_pci_remove(struct pci_dev *pdev) return; } -static struct pci_device_id mantis_pci_table[] = { +static const struct pci_device_id mantis_pci_table[] = { MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config, RC_MAP_TECHNISAT_TS35), MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config, -- cgit v1.2.3 From 2b9e300fcbf952ebcd1d2732b2cc1d4414853e16 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:32 -0400 Subject: media: mantis: hopper_cards: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/mantis/hopper_cards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index 68b5800030b7..11e987860b23 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -255,7 +255,7 @@ static void hopper_pci_remove(struct pci_dev *pdev) } -static struct pci_device_id hopper_pci_table[] = { +static const struct pci_device_id hopper_pci_table[] = { MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config, NULL), { } -- cgit v1.2.3 From 1482ccdaae6a335f448cc91043695cb1a07af981 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:33 -0400 Subject: media: cx18: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 8bce49cdad46..8654710464cc 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -48,7 +48,7 @@ int (*cx18_ext_init)(struct cx18 *); EXPORT_SYMBOL(cx18_ext_init); /* add your revision and whatnot here */ -static struct pci_device_id cx18_pci_tbl[] = { +static const struct pci_device_id cx18_pci_tbl[] = { {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} -- cgit v1.2.3 From c181efd25ca4aa5af64081f4824d5fd3f6ecf03d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 1 Aug 2017 13:56:34 -0400 Subject: media: radio: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-maxiradio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 8253f79d5d75..3aa5ad391581 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -186,7 +186,7 @@ static void maxiradio_remove(struct pci_dev *pdev) kfree(dev); } -static struct pci_device_id maxiradio_pci_tbl[] = { +static const struct pci_device_id maxiradio_pci_tbl[] = { { PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO, PCI_ANY_ID, PCI_ANY_ID, }, { 0 } -- cgit v1.2.3 From 63dcbcff0ef851c725b4f0199dc1ae3a03d90c42 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:50 -0400 Subject: media: ttpci: budget: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/budget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index 81fe35cedd10..f59eadb7a5eb 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -845,7 +845,7 @@ MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1 MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT); MAKE_BUDGET_INFO(sylt, "Philips Semi Sylt PCI", BUDGET_TT_HW_DISEQC); -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), -- cgit v1.2.3 From 60bd1e1cb6ba460de740ba4586f820ff2fe0dac0 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:51 -0400 Subject: media: ttpci: budget-patch: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/budget-patch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/media/pci/ttpci/budget-patch.c index 442992372008..a738018cdca8 100644 --- a/drivers/media/pci/ttpci/budget-patch.c +++ b/drivers/media/pci/ttpci/budget-patch.c @@ -45,7 +45,7 @@ static struct saa7146_extension budget_extension; MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH); //MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC); -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000), // MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), { -- cgit v1.2.3 From 110cb3c043b6efb14af953dbc8ed5184f54de655 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:52 -0400 Subject: media: ttpci: budget-ci: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/budget-ci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 11b9227307bf..5b8aab4c7b81 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -1538,7 +1538,7 @@ MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT); -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), -- cgit v1.2.3 From 1d71a4c60d9e1f6265a360ab0fd2e01bea26252d Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:53 -0400 Subject: media: ttpci: budget-av: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/budget-av.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index dc7be8fac9a3..ac83fff9fe0b 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -1567,7 +1567,7 @@ MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), -- cgit v1.2.3 From cd142f431a3119eee0e06d8fa578f7d31120ac2a Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:54 -0400 Subject: media: ttpci: av7110: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/av7110.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index f2905bd80366..f46947d8adf8 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -2872,7 +2872,7 @@ MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3"); -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000), MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), -- cgit v1.2.3 From 34e7b45a01ef914cf6d5d49e0968ad013e221376 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:55 -0400 Subject: media: saa7146: mxb: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7146/mxb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 504d78807639..930218cc2de1 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -819,7 +819,7 @@ static struct saa7146_pci_extension_data mxb = { .ext = &extension, }; -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7146, -- cgit v1.2.3 From 7ad584c0dfd36dce0d49e4e5ab30a7237888ce1e Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:56 -0400 Subject: media: saa7146: hexium_orion: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7146/hexium_orion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index c306a92e8909..01f01580c7ca 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -427,7 +427,7 @@ static struct saa7146_pci_extension_data hexium_orion_4bnc = { .ext = &extension, }; -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7146, -- cgit v1.2.3 From c6e3bdb8e6a1f0007c6ea1502a46552b789c79f3 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 13:14:57 -0400 Subject: media: saa7146: hexium_gemini: constify pci_device_id pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by and work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7146/hexium_gemini.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index c889ec9f8a5a..f708cab01fef 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -363,7 +363,7 @@ static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = { .ext = &hexium_extension, }; -static struct pci_device_id pci_tbl[] = { +static const struct pci_device_id pci_tbl[] = { { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7146, -- cgit v1.2.3 From 54b1b41f8be7017950d7cdfe8834ed6361d0e33a Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 31 Jul 2017 09:38:50 -0400 Subject: media: cx231xx: fail probe if i2c_add_adapter fails While at it, change the type of the previously always-zero i2c_rc member to int, matching the returned type from i2c_add_adapter. Signed-off-by: Peter Rosin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 2 +- drivers/media/usb/cx231xx/cx231xx.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 8d95b1154e12..3a0c45ffd40f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -538,7 +538,7 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) bus->i2c_adap.algo_data = bus; i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); - i2c_add_adapter(&bus->i2c_adap); + bus->i2c_rc = i2c_add_adapter(&bus->i2c_adap); if (0 != bus->i2c_rc) dev_warn(dev->dev, diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 986c64ba5b56..27ee035f9f84 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -476,7 +476,7 @@ struct cx231xx_i2c { /* i2c i/o */ struct i2c_adapter i2c_adap; - u32 i2c_rc; + int i2c_rc; /* different settings for each bus */ u8 i2c_period; -- cgit v1.2.3 From 2246902264956f099bca967b2b5b5817ca9e35b6 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 31 Jul 2017 09:38:51 -0400 Subject: media: cx231xx: drop return value of cx231xx_i2c_unregister No one cares anyway. Signed-off-by: Peter Rosin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-i2c.c | 3 +-- drivers/media/usb/cx231xx/cx231xx.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 3a0c45ffd40f..3e49517cb5e0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -551,10 +551,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) * cx231xx_i2c_unregister() * unregister i2c_bus */ -int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) +void cx231xx_i2c_unregister(struct cx231xx_i2c *bus) { i2c_del_adapter(&bus->i2c_adap); - return 0; } /* diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 27ee035f9f84..72d5937a087e 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -762,7 +762,7 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev); /* Provided by cx231xx-i2c.c */ void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); -int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +void cx231xx_i2c_unregister(struct cx231xx_i2c *bus); int cx231xx_i2c_mux_create(struct cx231xx *dev); int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no); void cx231xx_i2c_mux_unregister(struct cx231xx *dev); -- cgit v1.2.3 From d3202d1981dc5a5f03f9afc96480619b48b60124 Mon Sep 17 00:00:00 2001 From: Anton Sviridenko Date: Wed, 2 Aug 2017 10:17:02 -0400 Subject: media: solo6x10: export hardware GPIO pins 8:31 to gpiolib interface 24 GPIO pins from 32 available on solo6x10 chips are exported to gpiolib. First 8 GPIOs are reserved for internal use on capture card boards, GPIOs in range 8:15 are configured as outputs to control relays, remaining 16:31 are configured as inputs to read sensor states. Now with this patch userspace DVR software can switch relays and read sensor states when GPIO extension cards are attached to Softlogic solo6x10 based video capture cards. Signed-off-by: Anton Sviridenko Signed-off-by: Ismael Luceno Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-gpio.c | 97 ++++++++++++++++++++++++++++++ drivers/media/pci/solo6x10/solo6x10.h | 5 ++ 2 files changed, 102 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/solo6x10/solo6x10-gpio.c b/drivers/media/pci/solo6x10/solo6x10-gpio.c index 6d3b4a36bc11..3d0d1aa2f6a8 100644 --- a/drivers/media/pci/solo6x10/solo6x10-gpio.c +++ b/drivers/media/pci/solo6x10/solo6x10-gpio.c @@ -57,6 +57,9 @@ static void solo_gpio_mode(struct solo_dev *solo_dev, ret |= 1 << port; } + /* Enable GPIO[31:16] */ + ret |= 0xffff0000; + solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret); } @@ -90,16 +93,110 @@ static void solo_gpio_config(struct solo_dev *solo_dev) /* Initially set relay status to 0 */ solo_gpio_clear(solo_dev, 0xff00); + + /* Set input pins direction */ + solo_gpio_mode(solo_dev, 0xffff0000, 0); +} + +#ifdef CONFIG_GPIOLIB +/* Pins 0-7 are not exported, because it seems from code above they are + * used for internal purposes. So offset 0 corresponds to pin 8, therefore + * offsets 0-7 are relay GPIOs, 8-23 - input GPIOs. + */ +static int solo_gpiochip_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + int ret, mode; + struct solo_dev *solo_dev = gpiochip_get_data(chip); + + if (offset < 8) { + ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0); + mode = 3 & (ret >> ((offset + 8) * 2)); + } else { + ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1); + mode = 1 & (ret >> (offset - 8)); + } + + if (!mode) + return 1; + else if (mode == 1) + return 0; + + return -1; } +static int solo_gpiochip_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + return -1; +} + +static int solo_gpiochip_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + return -1; +} + +static int solo_gpiochip_get(struct gpio_chip *chip, + unsigned int offset) +{ + int ret; + struct solo_dev *solo_dev = gpiochip_get_data(chip); + + ret = solo_reg_read(solo_dev, SOLO_GPIO_DATA_IN); + + return 1 & (ret >> (offset + 8)); +} + +static void solo_gpiochip_set(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct solo_dev *solo_dev = gpiochip_get_data(chip); + + if (value) + solo_gpio_set(solo_dev, 1 << (offset + 8)); + else + solo_gpio_clear(solo_dev, 1 << (offset + 8)); +} +#endif + int solo_gpio_init(struct solo_dev *solo_dev) { + int ret; + solo_gpio_config(solo_dev); +#ifdef CONFIG_GPIOLIB + solo_dev->gpio_dev.label = SOLO6X10_NAME"_gpio"; + solo_dev->gpio_dev.parent = &solo_dev->pdev->dev; + solo_dev->gpio_dev.owner = THIS_MODULE; + solo_dev->gpio_dev.base = -1; + solo_dev->gpio_dev.ngpio = 24; + solo_dev->gpio_dev.can_sleep = 0; + + solo_dev->gpio_dev.get_direction = solo_gpiochip_get_direction; + solo_dev->gpio_dev.direction_input = solo_gpiochip_direction_input; + solo_dev->gpio_dev.direction_output = solo_gpiochip_direction_output; + solo_dev->gpio_dev.get = solo_gpiochip_get; + solo_dev->gpio_dev.set = solo_gpiochip_set; + + ret = gpiochip_add_data(&solo_dev->gpio_dev, solo_dev); + + if (ret) { + solo_dev->gpio_dev.label = NULL; + return -1; + } +#endif return 0; } void solo_gpio_exit(struct solo_dev *solo_dev) { +#ifdef CONFIG_GPIOLIB + if (solo_dev->gpio_dev.label) { + gpiochip_remove(&solo_dev->gpio_dev); + solo_dev->gpio_dev.label = NULL; + } +#endif solo_gpio_clear(solo_dev, 0x30); solo_gpio_config(solo_dev); } diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h index 3f8da5e8c430..3a1893ae2dad 100644 --- a/drivers/media/pci/solo6x10/solo6x10.h +++ b/drivers/media/pci/solo6x10/solo6x10.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -199,6 +200,10 @@ struct solo_dev { u32 irq_mask; u32 motion_mask; struct v4l2_device v4l2_dev; +#ifdef CONFIG_GPIOLIB + /* GPIO */ + struct gpio_chip gpio_dev; +#endif /* tw28xx accounting */ u8 tw2865, tw2864, tw2815; -- cgit v1.2.3 From b050d46e4a64ab0b9df9a607a6c4dc7b28e9125b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 2 Aug 2017 10:54:13 -0400 Subject: media: DaVinci-VPBE: constify vpbe_dev_ops vpbe_dev_ops is only copied into the ops field at the end of a vpbe_device structure, so it can be const. Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c index 3679b1e7b39e..7f6462562579 100644 --- a/drivers/media/platform/davinci/vpbe.c +++ b/drivers/media/platform/davinci/vpbe.c @@ -790,7 +790,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) vpss_enable_clock(VPSS_VPBE_CLOCK, 0); } -static struct vpbe_device_ops vpbe_dev_ops = { +static const struct vpbe_device_ops vpbe_dev_ops = { .g_cropcap = vpbe_g_cropcap, .enum_outputs = vpbe_enum_outputs, .set_output = vpbe_set_output, -- cgit v1.2.3 From 7cc7a83394be1db510609d8d2f68c53b63a3ecff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 4 Aug 2017 04:07:51 -0400 Subject: media: adv7604: Prevent out of bounds access These can only be accessed with CAP_SYS_ADMIN so it's not a critical security issue. The problem is that "page" is controlled by the user in the ioctl(). The test to see if the bit is set in state->info->page_mask is not sufficient because "page" can be very high and shift wrap around to a bit which is set. Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 324d39bd68d0..f289b8aca1da 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -618,7 +618,7 @@ static int adv76xx_read_reg(struct v4l2_subdev *sd, unsigned int reg) unsigned int val; int err; - if (!(BIT(page) & state->info->page_mask)) + if (page >= ADV76XX_PAGE_MAX || !(BIT(page) & state->info->page_mask)) return -EINVAL; reg &= 0xff; @@ -633,7 +633,7 @@ static int adv76xx_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) struct adv76xx_state *state = to_state(sd); unsigned int page = reg >> 8; - if (!(BIT(page) & state->info->page_mask)) + if (page >= ADV76XX_PAGE_MAX || !(BIT(page) & state->info->page_mask)) return -EINVAL; reg &= 0xff; -- cgit v1.2.3 From 025a26fa14f8fd55d50ab284a30c016a5be953d0 Mon Sep 17 00:00:00 2001 From: Daniel Mentz Date: Thu, 3 Aug 2017 18:03:10 -0400 Subject: media: v4l2-compat-ioctl32: Copy v4l2_window->global_alpha Commit b2787845fb91 ("V4L/DVB (5289): Add support for video output overlays.") added the field global_alpha to struct v4l2_window but did not update the compat layer accordingly. This change adds global_alpha to struct v4l2_window32 and copies the value for global_alpha back and forth. Signed-off-by: Daniel Mentz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 6f52970f8b54..84ad195562c7 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -43,6 +43,7 @@ struct v4l2_window32 { compat_caddr_t clips; /* actually struct v4l2_clip32 * */ __u32 clipcount; compat_caddr_t bitmap; + __u8 global_alpha; }; static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) @@ -51,7 +52,8 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user copy_from_user(&kp->w, &up->w, sizeof(up->w)) || get_user(kp->field, &up->field) || get_user(kp->chromakey, &up->chromakey) || - get_user(kp->clipcount, &up->clipcount)) + get_user(kp->clipcount, &up->clipcount) || + get_user(kp->global_alpha, &up->global_alpha)) return -EFAULT; if (kp->clipcount > 2048) return -EINVAL; @@ -84,7 +86,8 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) || put_user(kp->field, &up->field) || put_user(kp->chromakey, &up->chromakey) || - put_user(kp->clipcount, &up->clipcount)) + put_user(kp->clipcount, &up->clipcount) || + put_user(kp->global_alpha, &up->global_alpha)) return -EFAULT; return 0; } -- cgit v1.2.3 From 9c7ba1d7634cef490b85bc64c4091ff004821bfd Mon Sep 17 00:00:00 2001 From: Daniel Mentz Date: Wed, 2 Aug 2017 23:42:17 -0400 Subject: media: v4l2-compat-ioctl32: Fix timespec conversion Certain syscalls like recvmmsg support 64 bit timespec values for the X32 ABI. The helper function compat_put_timespec converts a timespec value to a 32 bit or 64 bit value depending on what ABI is used. The v4l2 compat layer, however, is not designed to support 64 bit timespec values and always uses 32 bit values. Hence, compat_put_timespec must not be used. Without this patch, user space will be provided with bad timestamp values from the VIDIOC_DQEVENT ioctl. Also, fields of the struct v4l2_event32 that come immediately after timestamp get overwritten, namely the field named id. Fixes: 81993e81a994 ("compat: Get rid of (get|put)_compat_time(val|spec)") Cc: stable@vger.kernel.org Cc: H. Peter Anvin Cc: Laurent Pinchart Cc: Tiffany Lin Cc: Ricardo Ribalda Delgado Cc: Sakari Ailus Signed-off-by: Daniel Mentz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 84ad195562c7..af8b4c5b0efa 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -799,7 +799,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u copy_to_user(&up->u, &kp->u, sizeof(kp->u)) || put_user(kp->pending, &up->pending) || put_user(kp->sequence, &up->sequence) || - compat_put_timespec(&kp->timestamp, &up->timestamp) || + put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || + put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) || put_user(kp->id, &up->id) || copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) return -EFAULT; -- cgit v1.2.3 From 7ec2c0f72cb1199c97d92b97b4bfc9978a0ea791 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Thu, 27 Jul 2017 11:20:29 -0400 Subject: media: platform: Add Amlogic Meson AO CEC Controller driver The Amlogic SoC embeds a standalone CEC controller, this patch adds a driver for such controller. The controller does not need HPD to be active, and could support up to max 5 logical addresses, but only 1 is handled since the Suspend firmware can make use of this unique logical address to wake up the device. The Suspend firmware configuration will be added in an other patchset. Signed-off-by: Neil Armstrong Signed-off-by: Hans Verkuil [hans.verkuil@cisco.com:s/if (ret)/if (res)/ to fix obvious typo] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 11 + drivers/media/platform/Makefile | 2 + drivers/media/platform/meson/Makefile | 1 + drivers/media/platform/meson/ao-cec.c | 744 ++++++++++++++++++++++++++++++++++ 4 files changed, 758 insertions(+) create mode 100644 drivers/media/platform/meson/Makefile create mode 100644 drivers/media/platform/meson/ao-cec.c (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 0c741d12dbc9..df74fa96229d 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -537,6 +537,17 @@ menuconfig CEC_PLATFORM_DRIVERS if CEC_PLATFORM_DRIVERS +config VIDEO_MESON_AO_CEC + tristate "Amlogic Meson AO CEC driver" + depends on ARCH_MESON || COMPILE_TEST + select CEC_CORE + select CEC_NOTIFIER + ---help--- + This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the + generic CEC framework interface. + CEC bus is present in the HDMI connector and enables communication + between compatible devices. + config VIDEO_SAMSUNG_S5P_CEC tristate "Samsung S5P CEC driver" depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 9beadc760467..a52d7b62292d 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ + +obj-y += meson/ diff --git a/drivers/media/platform/meson/Makefile b/drivers/media/platform/meson/Makefile new file mode 100644 index 000000000000..597beb8f34d1 --- /dev/null +++ b/drivers/media/platform/meson/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_MESON_AO_CEC) += ao-cec.o diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c new file mode 100644 index 000000000000..8040a6285c3f --- /dev/null +++ b/drivers/media/platform/meson/ao-cec.c @@ -0,0 +1,744 @@ +/* + * Driver for Amlogic Meson AO CEC Controller + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved + * Copyright (C) 2017 BayLibre, SAS + * Author: Neil Armstrong + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* CEC Registers */ + +/* + * [2:1] cntl_clk + * - 0 = Disable clk (Power-off mode) + * - 1 = Enable gated clock (Normal mode) + * - 2 = Enable free-run clk (Debug mode) + */ +#define CEC_GEN_CNTL_REG 0x00 + +#define CEC_GEN_CNTL_RESET BIT(0) +#define CEC_GEN_CNTL_CLK_DISABLE 0 +#define CEC_GEN_CNTL_CLK_ENABLE 1 +#define CEC_GEN_CNTL_CLK_ENABLE_DBG 2 +#define CEC_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1) + +/* + * [7:0] cec_reg_addr + * [15:8] cec_reg_wrdata + * [16] cec_reg_wr + * - 0 = Read + * - 1 = Write + * [23] bus free + * [31:24] cec_reg_rddata + */ +#define CEC_RW_REG 0x04 + +#define CEC_RW_ADDR GENMASK(7, 0) +#define CEC_RW_WR_DATA GENMASK(15, 8) +#define CEC_RW_WRITE_EN BIT(16) +#define CEC_RW_BUS_BUSY BIT(23) +#define CEC_RW_RD_DATA GENMASK(31, 24) + +/* + * [1] tx intr + * [2] rx intr + */ +#define CEC_INTR_MASKN_REG 0x08 +#define CEC_INTR_CLR_REG 0x0c +#define CEC_INTR_STAT_REG 0x10 + +#define CEC_INTR_TX BIT(1) +#define CEC_INTR_RX BIT(2) + +/* CEC Commands */ + +#define CEC_TX_MSG_0_HEADER 0x00 +#define CEC_TX_MSG_1_OPCODE 0x01 +#define CEC_TX_MSG_2_OP1 0x02 +#define CEC_TX_MSG_3_OP2 0x03 +#define CEC_TX_MSG_4_OP3 0x04 +#define CEC_TX_MSG_5_OP4 0x05 +#define CEC_TX_MSG_6_OP5 0x06 +#define CEC_TX_MSG_7_OP6 0x07 +#define CEC_TX_MSG_8_OP7 0x08 +#define CEC_TX_MSG_9_OP8 0x09 +#define CEC_TX_MSG_A_OP9 0x0A +#define CEC_TX_MSG_B_OP10 0x0B +#define CEC_TX_MSG_C_OP11 0x0C +#define CEC_TX_MSG_D_OP12 0x0D +#define CEC_TX_MSG_E_OP13 0x0E +#define CEC_TX_MSG_F_OP14 0x0F +#define CEC_TX_MSG_LENGTH 0x10 +#define CEC_TX_MSG_CMD 0x11 +#define CEC_TX_WRITE_BUF 0x12 +#define CEC_TX_CLEAR_BUF 0x13 +#define CEC_RX_MSG_CMD 0x14 +#define CEC_RX_CLEAR_BUF 0x15 +#define CEC_LOGICAL_ADDR0 0x16 +#define CEC_LOGICAL_ADDR1 0x17 +#define CEC_LOGICAL_ADDR2 0x18 +#define CEC_LOGICAL_ADDR3 0x19 +#define CEC_LOGICAL_ADDR4 0x1A +#define CEC_CLOCK_DIV_H 0x1B +#define CEC_CLOCK_DIV_L 0x1C +#define CEC_QUIESCENT_25MS_BIT7_0 0x20 +#define CEC_QUIESCENT_25MS_BIT11_8 0x21 +#define CEC_STARTBITMINL2H_3MS5_BIT7_0 0x22 +#define CEC_STARTBITMINL2H_3MS5_BIT8 0x23 +#define CEC_STARTBITMAXL2H_3MS9_BIT7_0 0x24 +#define CEC_STARTBITMAXL2H_3MS9_BIT8 0x25 +#define CEC_STARTBITMINH_0MS6_BIT7_0 0x26 +#define CEC_STARTBITMINH_0MS6_BIT8 0x27 +#define CEC_STARTBITMAXH_1MS0_BIT7_0 0x28 +#define CEC_STARTBITMAXH_1MS0_BIT8 0x29 +#define CEC_STARTBITMINTOT_4MS3_BIT7_0 0x2A +#define CEC_STARTBITMINTOT_4MS3_BIT9_8 0x2B +#define CEC_STARTBITMAXTOT_4MS7_BIT7_0 0x2C +#define CEC_STARTBITMAXTOT_4MS7_BIT9_8 0x2D +#define CEC_LOGIC1MINL2H_0MS4_BIT7_0 0x2E +#define CEC_LOGIC1MINL2H_0MS4_BIT8 0x2F +#define CEC_LOGIC1MAXL2H_0MS8_BIT7_0 0x30 +#define CEC_LOGIC1MAXL2H_0MS8_BIT8 0x31 +#define CEC_LOGIC0MINL2H_1MS3_BIT7_0 0x32 +#define CEC_LOGIC0MINL2H_1MS3_BIT8 0x33 +#define CEC_LOGIC0MAXL2H_1MS7_BIT7_0 0x34 +#define CEC_LOGIC0MAXL2H_1MS7_BIT8 0x35 +#define CEC_LOGICMINTOTAL_2MS05_BIT7_0 0x36 +#define CEC_LOGICMINTOTAL_2MS05_BIT9_8 0x37 +#define CEC_LOGICMAXHIGH_2MS8_BIT7_0 0x38 +#define CEC_LOGICMAXHIGH_2MS8_BIT8 0x39 +#define CEC_LOGICERRLOW_3MS4_BIT7_0 0x3A +#define CEC_LOGICERRLOW_3MS4_BIT8 0x3B +#define CEC_NOMSMPPOINT_1MS05 0x3C +#define CEC_DELCNTR_LOGICERR 0x3E +#define CEC_TXTIME_17MS_BIT7_0 0x40 +#define CEC_TXTIME_17MS_BIT10_8 0x41 +#define CEC_TXTIME_2BIT_BIT7_0 0x42 +#define CEC_TXTIME_2BIT_BIT10_8 0x43 +#define CEC_TXTIME_4BIT_BIT7_0 0x44 +#define CEC_TXTIME_4BIT_BIT10_8 0x45 +#define CEC_STARTBITNOML2H_3MS7_BIT7_0 0x46 +#define CEC_STARTBITNOML2H_3MS7_BIT8 0x47 +#define CEC_STARTBITNOMH_0MS8_BIT7_0 0x48 +#define CEC_STARTBITNOMH_0MS8_BIT8 0x49 +#define CEC_LOGIC1NOML2H_0MS6_BIT7_0 0x4A +#define CEC_LOGIC1NOML2H_0MS6_BIT8 0x4B +#define CEC_LOGIC0NOML2H_1MS5_BIT7_0 0x4C +#define CEC_LOGIC0NOML2H_1MS5_BIT8 0x4D +#define CEC_LOGIC1NOMH_1MS8_BIT7_0 0x4E +#define CEC_LOGIC1NOMH_1MS8_BIT8 0x4F +#define CEC_LOGIC0NOMH_0MS9_BIT7_0 0x50 +#define CEC_LOGIC0NOMH_0MS9_BIT8 0x51 +#define CEC_LOGICERRLOW_3MS6_BIT7_0 0x52 +#define CEC_LOGICERRLOW_3MS6_BIT8 0x53 +#define CEC_CHKCONTENTION_0MS1 0x54 +#define CEC_PREPARENXTBIT_0MS05_BIT7_0 0x56 +#define CEC_PREPARENXTBIT_0MS05_BIT8 0x57 +#define CEC_NOMSMPACKPOINT_0MS45 0x58 +#define CEC_ACK0NOML2H_1MS5_BIT7_0 0x5A +#define CEC_ACK0NOML2H_1MS5_BIT8 0x5B +#define CEC_BUGFIX_DISABLE_0 0x60 +#define CEC_BUGFIX_DISABLE_1 0x61 +#define CEC_RX_MSG_0_HEADER 0x80 +#define CEC_RX_MSG_1_OPCODE 0x81 +#define CEC_RX_MSG_2_OP1 0x82 +#define CEC_RX_MSG_3_OP2 0x83 +#define CEC_RX_MSG_4_OP3 0x84 +#define CEC_RX_MSG_5_OP4 0x85 +#define CEC_RX_MSG_6_OP5 0x86 +#define CEC_RX_MSG_7_OP6 0x87 +#define CEC_RX_MSG_8_OP7 0x88 +#define CEC_RX_MSG_9_OP8 0x89 +#define CEC_RX_MSG_A_OP9 0x8A +#define CEC_RX_MSG_B_OP10 0x8B +#define CEC_RX_MSG_C_OP11 0x8C +#define CEC_RX_MSG_D_OP12 0x8D +#define CEC_RX_MSG_E_OP13 0x8E +#define CEC_RX_MSG_F_OP14 0x8F +#define CEC_RX_MSG_LENGTH 0x90 +#define CEC_RX_MSG_STATUS 0x91 +#define CEC_RX_NUM_MSG 0x92 +#define CEC_TX_MSG_STATUS 0x93 +#define CEC_TX_NUM_MSG 0x94 + + +/* CEC_TX_MSG_CMD definition */ +#define TX_NO_OP 0 /* No transaction */ +#define TX_REQ_CURRENT 1 /* Transmit earliest message in buffer */ +#define TX_ABORT 2 /* Abort transmitting earliest message */ +#define TX_REQ_NEXT 3 /* Overwrite earliest msg, transmit next */ + +/* tx_msg_status definition */ +#define TX_IDLE 0 /* No transaction */ +#define TX_BUSY 1 /* Transmitter is busy */ +#define TX_DONE 2 /* Message successfully transmitted */ +#define TX_ERROR 3 /* Message transmitted with error */ + +/* rx_msg_cmd */ +#define RX_NO_OP 0 /* No transaction */ +#define RX_ACK_CURRENT 1 /* Read earliest message in buffer */ +#define RX_DISABLE 2 /* Disable receiving latest message */ +#define RX_ACK_NEXT 3 /* Clear earliest msg, read next */ + +/* rx_msg_status */ +#define RX_IDLE 0 /* No transaction */ +#define RX_BUSY 1 /* Receiver is busy */ +#define RX_DONE 2 /* Message has been received successfully */ +#define RX_ERROR 3 /* Message has been received with error */ + +/* RX_CLEAR_BUF options */ +#define CLEAR_START 1 +#define CLEAR_STOP 0 + +/* CEC_LOGICAL_ADDRx options */ +#define LOGICAL_ADDR_MASK 0xf +#define LOGICAL_ADDR_VALID BIT(4) +#define LOGICAL_ADDR_DISABLE 0 + +#define CEC_CLK_RATE 32768 + +struct meson_ao_cec_device { + struct platform_device *pdev; + void __iomem *base; + struct clk *core; + spinlock_t cec_reg_lock; + struct cec_notifier *notify; + struct cec_adapter *adap; + struct cec_msg rx_msg; +}; + +#define writel_bits_relaxed(mask, val, addr) \ + writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr) + +static inline int meson_ao_cec_wait_busy(struct meson_ao_cec_device *ao_cec) +{ + ktime_t timeout = ktime_add_us(ktime_get(), 5000); + + while (readl_relaxed(ao_cec->base + CEC_RW_REG) & CEC_RW_BUS_BUSY) { + if (ktime_compare(ktime_get(), timeout) > 0) + return -ETIMEDOUT; + } + + return 0; +} + +static void meson_ao_cec_read(struct meson_ao_cec_device *ao_cec, + unsigned long address, u8 *data, + int *res) +{ + unsigned long flags; + u32 reg = FIELD_PREP(CEC_RW_ADDR, address); + int ret = 0; + + if (res && *res) + return; + + spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); + + ret = meson_ao_cec_wait_busy(ao_cec); + if (ret) + goto read_out; + + writel_relaxed(reg, ao_cec->base + CEC_RW_REG); + + ret = meson_ao_cec_wait_busy(ao_cec); + if (ret) + goto read_out; + + *data = FIELD_GET(CEC_RW_RD_DATA, + readl_relaxed(ao_cec->base + CEC_RW_REG)); + +read_out: + spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); + + if (res) + *res = ret; +} + +static void meson_ao_cec_write(struct meson_ao_cec_device *ao_cec, + unsigned long address, u8 data, + int *res) +{ + unsigned long flags; + u32 reg = FIELD_PREP(CEC_RW_ADDR, address) | + FIELD_PREP(CEC_RW_WR_DATA, data) | + CEC_RW_WRITE_EN; + int ret = 0; + + if (res && *res) + return; + + spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); + + ret = meson_ao_cec_wait_busy(ao_cec); + if (ret) + goto write_out; + + writel_relaxed(reg, ao_cec->base + CEC_RW_REG); + +write_out: + spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); + + if (res) + *res = ret; +} + +static inline void meson_ao_cec_irq_setup(struct meson_ao_cec_device *ao_cec, + bool enable) +{ + u32 cfg = CEC_INTR_TX | CEC_INTR_RX; + + writel_bits_relaxed(cfg, enable ? cfg : 0, + ao_cec->base + CEC_INTR_MASKN_REG); +} + +static inline int meson_ao_cec_clear(struct meson_ao_cec_device *ao_cec) +{ + int ret = 0; + + meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_DISABLE, &ret); + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret); + meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 1, &ret); + meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 1, &ret); + if (ret) + return ret; + + udelay(100); + + meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 0, &ret); + meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 0, &ret); + if (ret) + return ret; + + udelay(100); + + meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret); + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret); + + return ret; +} + +static int meson_ao_cec_arbit_bit_time_set(struct meson_ao_cec_device *ao_cec, + unsigned int bit_set, + unsigned int time_set) +{ + int ret = 0; + + switch (bit_set) { + case CEC_SIGNAL_FREE_TIME_RETRY: + meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT7_0, + time_set & 0xff, &ret); + meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT10_8, + (time_set >> 8) & 0x7, &ret); + break; + + case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR: + meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT7_0, + time_set & 0xff, &ret); + meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT10_8, + (time_set >> 8) & 0x7, &ret); + break; + + case CEC_SIGNAL_FREE_TIME_NEXT_XFER: + meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT7_0, + time_set & 0xff, &ret); + meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT10_8, + (time_set >> 8) & 0x7, &ret); + break; + } + + return ret; +} + +static irqreturn_t meson_ao_cec_irq(int irq, void *data) +{ + struct meson_ao_cec_device *ao_cec = data; + u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG); + + if (stat) + return IRQ_WAKE_THREAD; + + return IRQ_NONE; +} + +static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec) +{ + unsigned long tx_status = 0; + u8 stat; + int ret = 0; + + meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &stat, &ret); + if (ret) + goto tx_reg_err; + + switch (stat) { + case TX_DONE: + tx_status = CEC_TX_STATUS_OK; + break; + + case TX_BUSY: + tx_status = CEC_TX_STATUS_ARB_LOST; + break; + + case TX_IDLE: + tx_status = CEC_TX_STATUS_LOW_DRIVE; + break; + + case TX_ERROR: + default: + tx_status = CEC_TX_STATUS_NACK; + break; + } + + /* Clear Interruption */ + writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG); + + /* Stop TX */ + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret); + if (ret) + goto tx_reg_err; + + cec_transmit_attempt_done(ao_cec->adap, tx_status); + return; + +tx_reg_err: + cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR); +} + +static void meson_ao_cec_irq_rx(struct meson_ao_cec_device *ao_cec) +{ + int i, ret = 0; + u8 reg; + + meson_ao_cec_read(ao_cec, CEC_RX_MSG_STATUS, ®, &ret); + if (reg != RX_DONE) + goto rx_out; + + meson_ao_cec_read(ao_cec, CEC_RX_NUM_MSG, ®, &ret); + if (reg != 1) + goto rx_out; + + meson_ao_cec_read(ao_cec, CEC_RX_MSG_LENGTH, ®, &ret); + + ao_cec->rx_msg.len = reg + 1; + if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE) + ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE; + + for (i = 0; i < ao_cec->rx_msg.len; i++) { + u8 byte; + + meson_ao_cec_read(ao_cec, CEC_RX_MSG_0_HEADER + i, &byte, &ret); + + ao_cec->rx_msg.msg[i] = byte; + } + + if (ret) + goto rx_out; + + cec_received_msg(ao_cec->adap, &ao_cec->rx_msg); + +rx_out: + /* Clear Interruption */ + writel_relaxed(CEC_INTR_RX, ao_cec->base + CEC_INTR_CLR_REG); + + /* Ack RX message */ + meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_ACK_CURRENT, &ret); + meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret); + + /* Clear RX buffer */ + meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_START, &ret); + meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_STOP, &ret); +} + +static irqreturn_t meson_ao_cec_irq_thread(int irq, void *data) +{ + struct meson_ao_cec_device *ao_cec = data; + u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG); + + if (stat & CEC_INTR_TX) + meson_ao_cec_irq_tx(ao_cec); + + meson_ao_cec_irq_rx(ao_cec); + + return IRQ_HANDLED; +} + +static int meson_ao_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr) +{ + struct meson_ao_cec_device *ao_cec = adap->priv; + int ret = 0; + + meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, + LOGICAL_ADDR_DISABLE, &ret); + if (ret) + return ret; + + ret = meson_ao_cec_clear(ao_cec); + if (ret) + return ret; + + if (logical_addr == CEC_LOG_ADDR_INVALID) + return 0; + + meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, + logical_addr & LOGICAL_ADDR_MASK, &ret); + if (ret) + return ret; + + udelay(100); + + meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0, + (logical_addr & LOGICAL_ADDR_MASK) | + LOGICAL_ADDR_VALID, &ret); + + return ret; +} + +static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct meson_ao_cec_device *ao_cec = adap->priv; + int i, ret = 0; + u8 reg; + + meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, ®, &ret); + if (ret) + return ret; + + if (reg == TX_BUSY) { + dev_err(&ao_cec->pdev->dev, "%s: busy TX: aborting\n", + __func__); + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret); + } + + for (i = 0; i < msg->len; i++) { + meson_ao_cec_write(ao_cec, CEC_TX_MSG_0_HEADER + i, + msg->msg[i], &ret); + } + + meson_ao_cec_write(ao_cec, CEC_TX_MSG_LENGTH, msg->len - 1, &ret); + meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_REQ_CURRENT, &ret); + + return ret; +} + +static int meson_ao_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct meson_ao_cec_device *ao_cec = adap->priv; + int ret; + + meson_ao_cec_irq_setup(ao_cec, false); + + writel_bits_relaxed(CEC_GEN_CNTL_RESET, CEC_GEN_CNTL_RESET, + ao_cec->base + CEC_GEN_CNTL_REG); + + if (!enable) + return 0; + + /* Enable gated clock (Normal mode). */ + writel_bits_relaxed(CEC_GEN_CNTL_CLK_CTRL_MASK, + FIELD_PREP(CEC_GEN_CNTL_CLK_CTRL_MASK, + CEC_GEN_CNTL_CLK_ENABLE), + ao_cec->base + CEC_GEN_CNTL_REG); + + udelay(100); + + /* Release Reset */ + writel_bits_relaxed(CEC_GEN_CNTL_RESET, 0, + ao_cec->base + CEC_GEN_CNTL_REG); + + /* Clear buffers */ + ret = meson_ao_cec_clear(ao_cec); + if (ret) + return ret; + + /* CEC arbitration 3/5/7 bit time set. */ + ret = meson_ao_cec_arbit_bit_time_set(ao_cec, + CEC_SIGNAL_FREE_TIME_RETRY, + 0x118); + if (ret) + return ret; + ret = meson_ao_cec_arbit_bit_time_set(ao_cec, + CEC_SIGNAL_FREE_TIME_NEW_INITIATOR, + 0x000); + if (ret) + return ret; + ret = meson_ao_cec_arbit_bit_time_set(ao_cec, + CEC_SIGNAL_FREE_TIME_NEXT_XFER, + 0x2aa); + if (ret) + return ret; + + meson_ao_cec_irq_setup(ao_cec, true); + + return 0; +} + +static const struct cec_adap_ops meson_ao_cec_ops = { + .adap_enable = meson_ao_cec_adap_enable, + .adap_log_addr = meson_ao_cec_set_log_addr, + .adap_transmit = meson_ao_cec_transmit, +}; + +static int meson_ao_cec_probe(struct platform_device *pdev) +{ + struct meson_ao_cec_device *ao_cec; + struct platform_device *hdmi_dev; + struct device_node *np; + struct resource *res; + int ret, irq; + + np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); + if (!np) { + dev_err(&pdev->dev, "Failed to find hdmi node\n"); + return -ENODEV; + } + + hdmi_dev = of_find_device_by_node(np); + if (hdmi_dev == NULL) + return -EPROBE_DEFER; + + ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL); + if (!ao_cec) + return -ENOMEM; + + spin_lock_init(&ao_cec->cec_reg_lock); + + ao_cec->notify = cec_notifier_get(&hdmi_dev->dev); + if (!ao_cec->notify) + return -ENOMEM; + + ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec, + "meson_ao_cec", + CEC_CAP_LOG_ADDRS | + CEC_CAP_TRANSMIT | + CEC_CAP_RC | + CEC_CAP_PASSTHROUGH, + 1); /* Use 1 for now */ + if (IS_ERR(ao_cec->adap)) { + ret = PTR_ERR(ao_cec->adap); + goto out_probe_notify; + } + + ao_cec->adap->owner = THIS_MODULE; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ao_cec->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ao_cec->base)) { + ret = PTR_ERR(ao_cec->base); + goto out_probe_adapter; + } + + irq = platform_get_irq(pdev, 0); + ret = devm_request_threaded_irq(&pdev->dev, irq, + meson_ao_cec_irq, + meson_ao_cec_irq_thread, + 0, NULL, ao_cec); + if (ret) { + dev_err(&pdev->dev, "irq request failed\n"); + goto out_probe_adapter; + } + + ao_cec->core = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(ao_cec->core)) { + dev_err(&pdev->dev, "core clock request failed\n"); + ret = PTR_ERR(ao_cec->core); + goto out_probe_adapter; + } + + ret = clk_prepare_enable(ao_cec->core); + if (ret) { + dev_err(&pdev->dev, "core clock enable failed\n"); + goto out_probe_adapter; + } + + ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE); + if (ret) { + dev_err(&pdev->dev, "core clock set rate failed\n"); + goto out_probe_clk; + } + + device_reset_optional(&pdev->dev); + + ao_cec->pdev = pdev; + platform_set_drvdata(pdev, ao_cec); + + ret = cec_register_adapter(ao_cec->adap, &pdev->dev); + if (ret < 0) { + cec_notifier_put(ao_cec->notify); + goto out_probe_clk; + } + + /* Setup Hardware */ + writel_relaxed(CEC_GEN_CNTL_RESET, + ao_cec->base + CEC_GEN_CNTL_REG); + + cec_register_cec_notifier(ao_cec->adap, ao_cec->notify); + + return 0; + +out_probe_clk: + clk_disable_unprepare(ao_cec->core); + +out_probe_adapter: + cec_delete_adapter(ao_cec->adap); + +out_probe_notify: + cec_notifier_put(ao_cec->notify); + + dev_err(&pdev->dev, "CEC controller registration failed\n"); + + return ret; +} + +static int meson_ao_cec_remove(struct platform_device *pdev) +{ + struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev); + + clk_disable_unprepare(ao_cec->core); + + cec_unregister_adapter(ao_cec->adap); + + cec_notifier_put(ao_cec->notify); + + return 0; +} + +static const struct of_device_id meson_ao_cec_of_match[] = { + { .compatible = "amlogic,meson-gx-ao-cec", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match); + +static struct platform_driver meson_ao_cec_driver = { + .probe = meson_ao_cec_probe, + .remove = meson_ao_cec_remove, + .driver = { + .name = "meson-ao-cec", + .of_match_table = of_match_ptr(meson_ao_cec_of_match), + }, +}; + +module_platform_driver(meson_ao_cec_driver); + +MODULE_DESCRIPTION("Meson AO CEC Controller driver"); +MODULE_AUTHOR("Neil Armstrong "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From df0347f34f89a9d60c0d10e6bfc8b6fbe503454b Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Mon, 7 Aug 2017 09:44:27 -0400 Subject: media: staging: media: atomisp: use kvmalloc/kvzalloc Use kvmalloc()/kvzalloc() instead of atomisp_kernel_malloc() /atomisp_kernel_zalloc(). Signed-off-by: Geliang Tang Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/pci/atomisp2/atomisp_cmd.c | 31 +--------------------- .../media/atomisp/pci/atomisp2/atomisp_cmd.h | 2 -- .../atomisp/pci/atomisp2/atomisp_compat_css20.c | 4 +-- .../media/atomisp/pci/atomisp2/atomisp_internal.h | 2 -- 4 files changed, 3 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c index 7bf5dcd3a2d1..f48bf451c1f5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c @@ -82,35 +82,6 @@ union host { } ptr; }; -/* - * atomisp_kernel_malloc: chooses whether kmalloc() or vmalloc() is preferable. - * - * It is also a wrap functions to pass into css framework. - */ -void *atomisp_kernel_malloc(size_t bytes) -{ - /* vmalloc() is preferable if allocating more than 1 page */ - if (bytes > PAGE_SIZE) - return vmalloc(bytes); - - return kmalloc(bytes, GFP_KERNEL); -} - -/* - * atomisp_kernel_zalloc: chooses whether set 0 to the allocated memory. - * - * It is also a wrap functions to pass into css framework. - */ -void *atomisp_kernel_zalloc(size_t bytes, bool zero_mem) -{ - void *ptr = atomisp_kernel_malloc(bytes); - - if (ptr && zero_mem) - memset(ptr, 0, bytes); - - return ptr; -} - /* * get sensor:dis71430/ov2720 related info from v4l2_subdev->priv data field. * subdev->priv is set in mrst.c @@ -4316,7 +4287,7 @@ int atomisp_set_parameters(struct video_device *vdev, * are ready, the parameters will be set to CSS. * per-frame setting only works for the main output frame. */ - param = atomisp_kernel_zalloc(sizeof(*param), true); + param = kvzalloc(sizeof(*param), GFP_KERNEL); if (!param) { dev_err(asd->isp->dev, "%s: failed to alloc params buffer\n", __func__); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h index 1ccd91172f98..31ba4e613d13 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h @@ -78,8 +78,6 @@ static inline void __iomem *atomisp_get_io_virt_addr(unsigned int address) return ret; } */ -void *atomisp_kernel_malloc(size_t bytes); -void *atomisp_kernel_zalloc(size_t bytes, bool zero_mem); /* * Interrupt functions diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c index 36f934d95651..05897b747349 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c @@ -1671,9 +1671,9 @@ int atomisp_alloc_metadata_output_buf(struct atomisp_sub_device *asd) /* We allocate the cpu-side buffer used for communication with user * space */ for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { - asd->params.metadata_user[i] = atomisp_kernel_malloc( + asd->params.metadata_user[i] = kvmalloc( asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]. - stream_info.metadata_info.size); + stream_info.metadata_info.size, GFP_KERNEL); if (!asd->params.metadata_user[i]) { while (--i >= 0) { kvfree(asd->params.metadata_user[i]); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h index 4b03f28983ee..7542a72f1d0f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h @@ -301,8 +301,6 @@ struct atomisp_device { extern struct device *atomisp_dev; -extern void *atomisp_kernel_malloc(size_t bytes); - #define atomisp_is_wdt_running(a) timer_pending(&(a)->wdt) #ifdef ISP2401 extern void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe, -- cgit v1.2.3 From 38ffab3b52f8c93525c606a8609af4e47eb87644 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 4 Aug 2017 08:09:45 -0400 Subject: media: staging: media: atomisp: constify videobuf_queue_ops structures These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,&i@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c index c151c848cf8f..d8cfed358d55 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c @@ -643,14 +643,14 @@ static void atomisp_buf_release_output(struct videobuf_queue *vq, vb->state = VIDEOBUF_NEEDS_INIT; } -static struct videobuf_queue_ops videobuf_qops = { +static const struct videobuf_queue_ops videobuf_qops = { .buf_setup = atomisp_buf_setup, .buf_prepare = atomisp_buf_prepare, .buf_queue = atomisp_buf_queue, .buf_release = atomisp_buf_release, }; -static struct videobuf_queue_ops videobuf_qops_output = { +static const struct videobuf_queue_ops videobuf_qops_output = { .buf_setup = atomisp_buf_setup_output, .buf_prepare = atomisp_buf_prepare_output, .buf_queue = atomisp_buf_queue_output, -- cgit v1.2.3 From a827c1a96b397fe624d5c0c9746e673f4b4d9d50 Mon Sep 17 00:00:00 2001 From: Rene Hickersberger Date: Mon, 31 Jul 2017 07:43:15 -0400 Subject: media: staging: media: atomisp: i2c: gc0310: fixed brace coding style issue Fixed a brace coding style issue. Signed-off-by: Rene Hickersberger Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/gc0310.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/gc0310.c b/drivers/staging/media/atomisp/i2c/gc0310.c index 0c3caed595f0..35ed51ffe944 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.c +++ b/drivers/staging/media/atomisp/i2c/gc0310.c @@ -118,9 +118,8 @@ static int gc0310_write_reg(struct i2c_client *client, u16 data_length, /* high byte goes out first */ *wreg = (u8)(reg & 0xff); - if (data_length == GC0310_8BIT) { + if (data_length == GC0310_8BIT) data[1] = (u8)(val); - } ret = gc0310_i2c_write(client, len, data); if (ret) -- cgit v1.2.3 From e7d59935d382d022054fcc311ac97a909e00d338 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Tue, 25 Jul 2017 02:04:10 -0400 Subject: media: staging: media: atomisp: remove trailing whitespace Signed-off-by: Stephen Brennan Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ov2680.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ov2680.c b/drivers/staging/media/atomisp/i2c/ov2680.c index 8daf81dfabb7..51b7d61df0f5 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.c +++ b/drivers/staging/media/atomisp/i2c/ov2680.c @@ -89,7 +89,7 @@ static int ov2680_read_reg(struct i2c_client *client, "read from offset 0x%x error %d", reg, err); return err; } - + *val = 0; /* high byte comes first */ if (data_length == OV2680_8BIT) @@ -285,7 +285,6 @@ static int ov2680_g_fnumber(struct v4l2_subdev *sd, s32 *val) static int ov2680_g_fnumber_range(struct v4l2_subdev *sd, s32 *val) { - *val = (OV2680_F_NUMBER_DEFAULT_NUM << 24) | (OV2680_F_NUMBER_DEM << 16) | (OV2680_F_NUMBER_DEFAULT_NUM << 8) | OV2680_F_NUMBER_DEM; @@ -306,7 +305,7 @@ static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val) { struct ov2680_device *dev = to_ov2680_sensor(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - + *val = ov2680_res[dev->fmt_idx].bin_factor_y; dev_dbg(&client->dev, "++++ov2680_g_bin_factor_y\n"); return 0; @@ -399,7 +398,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg, struct ov2680_device *dev = to_ov2680_sensor(sd); u16 vts,hts; int ret,exp_val; - + dev_dbg(&client->dev, "+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",coarse_itg, gain, digitgain); hts = ov2680_res[dev->fmt_idx].pixels_per_line; @@ -542,7 +541,7 @@ static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) switch (cmd) { case ATOMISP_IOC_S_EXPOSURE: return ov2680_s_exposure(sd, arg); - + default: return -EINVAL; } @@ -983,7 +982,7 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on) if (on == 0){ ret = power_down(sd); } else { - ret = power_up(sd); + ret = power_up(sd); if (!ret) return ov2680_init(sd); } @@ -1207,7 +1206,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable) dev_dbg(&client->dev, "ov2680_s_stream one \n"); else dev_dbg(&client->dev, "ov2680_s_stream off \n"); - + ret = ov2680_write_reg(client, OV2680_8BIT, OV2680_SW_STREAM, enable ? OV2680_START_STREAMING : OV2680_STOP_STREAMING); @@ -1267,7 +1266,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd, dev_err(&client->dev, "ov2680_detect err s_config.\n"); goto fail_csi_cfg; } - + /* turn off sensor, after probed */ ret = power_down(sd); if (ret) { @@ -1385,7 +1384,7 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd, static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) { struct ov2680_device *dev = to_ov2680_sensor(sd); - + mutex_lock(&dev->input_lock); *frames = ov2680_res[dev->fmt_idx].skip_frames; mutex_unlock(&dev->input_lock); -- cgit v1.2.3 From 65058214f5c2ebe844916b92d1bece64fd00206e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 06:58:29 -0400 Subject: media: staging: media: atomisp: constify video_subdev structures These structures are both stored in fields of v4l2_subdev_ops structures, all of which are const, so these structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ap1302.c | 2 +- drivers/staging/media/atomisp/i2c/mt9m114.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ap1302.c b/drivers/staging/media/atomisp/i2c/ap1302.c index bacffbe962d4..de687c6fae57 100644 --- a/drivers/staging/media/atomisp/i2c/ap1302.c +++ b/drivers/staging/media/atomisp/i2c/ap1302.c @@ -1098,7 +1098,7 @@ static const struct v4l2_ctrl_config ctrls[] = { }, }; -static struct v4l2_subdev_sensor_ops ap1302_sensor_ops = { +static const struct v4l2_subdev_sensor_ops ap1302_sensor_ops = { .g_skip_frames = ap1302_g_skip_frames, }; diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.c b/drivers/staging/media/atomisp/i2c/mt9m114.c index 448e072ca037..36a0636a532f 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/mt9m114.c @@ -1806,7 +1806,7 @@ static const struct v4l2_subdev_video_ops mt9m114_video_ops = { .g_frame_interval = mt9m114_g_frame_interval, }; -static struct v4l2_subdev_sensor_ops mt9m114_sensor_ops = { +static const struct v4l2_subdev_sensor_ops mt9m114_sensor_ops = { .g_skip_frames = mt9m114_g_skip_frames, }; -- cgit v1.2.3 From 8e2803ffd64cc181917f911fe0b657421ee78d9c Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 31 Jul 2017 09:38:52 -0400 Subject: media: cx231xx: only unregister successfully registered i2c adapters This prevents potentially scary debug messages from the i2c core. Signed-off-by: Peter Rosin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-core.c | 3 +++ drivers/media/usb/cx231xx/cx231xx-i2c.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 46646ecd2dbc..f372ad3917a8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1311,6 +1311,7 @@ int cx231xx_dev_init(struct cx231xx *dev) dev->i2c_bus[0].i2c_period = I2C_SPEED_100K; /* 100 KHz */ dev->i2c_bus[0].i2c_nostop = 0; dev->i2c_bus[0].i2c_reserve = 0; + dev->i2c_bus[0].i2c_rc = -ENODEV; /* External Master 2 Bus */ dev->i2c_bus[1].nr = 1; @@ -1318,6 +1319,7 @@ int cx231xx_dev_init(struct cx231xx *dev) dev->i2c_bus[1].i2c_period = I2C_SPEED_100K; /* 100 KHz */ dev->i2c_bus[1].i2c_nostop = 0; dev->i2c_bus[1].i2c_reserve = 0; + dev->i2c_bus[1].i2c_rc = -ENODEV; /* Internal Master 3 Bus */ dev->i2c_bus[2].nr = 2; @@ -1325,6 +1327,7 @@ int cx231xx_dev_init(struct cx231xx *dev) dev->i2c_bus[2].i2c_period = I2C_SPEED_100K; /* 100kHz */ dev->i2c_bus[2].i2c_nostop = 0; dev->i2c_bus[2].i2c_reserve = 0; + dev->i2c_bus[2].i2c_rc = -ENODEV; /* register I2C buses */ errCode = cx231xx_i2c_register(&dev->i2c_bus[0]); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 3e49517cb5e0..8ce6b815d16d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -553,7 +553,8 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) */ void cx231xx_i2c_unregister(struct cx231xx_i2c *bus) { - i2c_del_adapter(&bus->i2c_adap); + if (!bus->i2c_rc) + i2c_del_adapter(&bus->i2c_adap); } /* -- cgit v1.2.3 From b3775edc66640cfdf205f533539a2f18055783c3 Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Thu, 27 Jul 2017 03:28:05 -0400 Subject: media: ov13858: Set default fps as current fps On format change, sometimes, sensor was streaming at a much higher FPS than the default. This was resulting in various problems like frame drops/corruption. Upon format change, set default vblank as current vblank. This will ensure that sensor will start streaming at default fps. Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 86550d8ddfee..8e6c8f00797d 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1377,6 +1377,7 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, struct ov13858 *ov13858 = to_ov13858(sd); const struct ov13858_mode *mode; struct v4l2_mbus_framefmt *framefmt; + s32 vblank_def; s64 h_blank; mutex_lock(&ov13858->mutex); @@ -1397,10 +1398,12 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, ov13858->pixel_rate, link_freq_configs[mode->link_freq_index].pixel_rate); /* Update limits and set FPS to default */ + vblank_def = ov13858->cur_mode->vts - ov13858->cur_mode->height; __v4l2_ctrl_modify_range( ov13858->vblank, OV13858_VBLANK_MIN, OV13858_VTS_MAX - ov13858->cur_mode->height, 1, - ov13858->cur_mode->vts - ov13858->cur_mode->height); + vblank_def); + __v4l2_ctrl_s_ctrl(ov13858->vblank, vblank_def); h_blank = link_freq_configs[mode->link_freq_index].pixels_per_line - ov13858->cur_mode->width; -- cgit v1.2.3 From 33eea13263ed7af4784f177037eb335e55fc6b4c Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Thu, 27 Jul 2017 03:44:19 -0400 Subject: media: ov13858: Fix initial expsoure max Previously, initial exposure max was set incorrectly to (0x7fff - 8). Now, limit exposure max to current resolution (VTS - 8). Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 8e6c8f00797d..85fd82f44add 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -66,7 +66,6 @@ /* Exposure control */ #define OV13858_REG_EXPOSURE 0x3500 #define OV13858_EXPOSURE_MIN 4 -#define OV13858_EXPOSURE_MAX (OV13858_VTS_MAX - 8) #define OV13858_EXPOSURE_STEP 1 #define OV13858_EXPOSURE_DEFAULT 0x640 @@ -1605,6 +1604,7 @@ static int ov13858_init_controls(struct ov13858 *ov13858) { struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); struct v4l2_ctrl_handler *ctrl_hdlr; + s64 exposure_max; int ret; ctrl_hdlr = &ov13858->ctrl_handler; @@ -1643,10 +1643,11 @@ static int ov13858_init_controls(struct ov13858 *ov13858) OV13858_PPL_1080MHZ - ov13858->cur_mode->width); ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + exposure_max = ov13858->cur_mode->vts - 8; ov13858->exposure = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN, - OV13858_EXPOSURE_MAX, OV13858_EXPOSURE_STEP, + exposure_max, OV13858_EXPOSURE_STEP, OV13858_EXPOSURE_DEFAULT); v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, -- cgit v1.2.3 From 89d8b615f2e5b249c0441e50c88c61c568b4f20b Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Sat, 29 Jul 2017 03:00:39 -0400 Subject: media: ov13858: Correct link-frequency and pixel-rate Previously both link-frequency and pixel-rate reported by the sensor was incorrect, resulting in incorrect FPS. Report link-frequency in Hz rather than link data rate in bps. Calculate pixel-rate from link-frequency. Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 85fd82f44add..867845bd4314 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -60,8 +60,8 @@ #define OV13858_VBLANK_MIN 56 /* HBLANK control - read only */ -#define OV13858_PPL_540MHZ 2244 -#define OV13858_PPL_1080MHZ 4488 +#define OV13858_PPL_270MHZ 2244 +#define OV13858_PPL_540MHZ 4488 /* Exposure control */ #define OV13858_REG_EXPOSURE 0x3500 @@ -943,31 +943,33 @@ static const char * const ov13858_test_pattern_menu[] = { /* Configurations for supported link frequencies */ #define OV13858_NUM_OF_LINK_FREQS 2 -#define OV13858_LINK_FREQ_1080MBPS 1080000000 -#define OV13858_LINK_FREQ_540MBPS 540000000 +#define OV13858_LINK_FREQ_540MHZ 540000000ULL +#define OV13858_LINK_FREQ_270MHZ 270000000ULL #define OV13858_LINK_FREQ_INDEX_0 0 #define OV13858_LINK_FREQ_INDEX_1 1 /* Menu items for LINK_FREQ V4L2 control */ static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = { - OV13858_LINK_FREQ_1080MBPS, - OV13858_LINK_FREQ_540MBPS + OV13858_LINK_FREQ_540MHZ, + OV13858_LINK_FREQ_270MHZ }; /* Link frequency configs */ static const struct ov13858_link_freq_config link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = { { - .pixel_rate = 864000000, - .pixels_per_line = OV13858_PPL_1080MHZ, + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + .pixel_rate = (OV13858_LINK_FREQ_540MHZ * 2 * 4) / 10, + .pixels_per_line = OV13858_PPL_540MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps), .regs = mipi_data_rate_1080mbps, } }, { - .pixel_rate = 432000000, - .pixels_per_line = OV13858_PPL_540MHZ, + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ + .pixel_rate = (OV13858_LINK_FREQ_270MHZ * 2 * 4) / 10, + .pixels_per_line = OV13858_PPL_270MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps), .regs = mipi_data_rate_540mbps, @@ -1637,10 +1639,10 @@ static int ov13858_init_controls(struct ov13858 *ov13858) ov13858->hblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width, + OV13858_PPL_540MHZ - ov13858->cur_mode->width, + OV13858_PPL_540MHZ - ov13858->cur_mode->width, 1, - OV13858_PPL_1080MHZ - ov13858->cur_mode->width); + OV13858_PPL_540MHZ - ov13858->cur_mode->width); ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; exposure_max = ov13858->cur_mode->vts - 8; -- cgit v1.2.3 From bfced6d1ec917436dd02e180bf52d71cd4a335a7 Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Fri, 28 Jul 2017 19:21:03 -0400 Subject: media: ov13858: Increase digital gain granularity, range Previously, possible digital gains were just 1x, 2x and 4x. These coarse gains were not sufficient in fine-tuning the image capture. Now, digital gain range is [0, 16x] with each step 1/1024, default 1x. This is achieved through OV13858 MWB R/G/B gain controls. Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 867845bd4314..45c0e96a4cba 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -77,13 +77,13 @@ #define OV13858_ANA_GAIN_DEFAULT 0x80 /* Digital gain control */ -#define OV13858_REG_DIGITAL_GAIN 0x350a -#define OV13858_DGTL_GAIN_MASK 0xf3 -#define OV13858_DGTL_GAIN_SHIFT 2 -#define OV13858_DGTL_GAIN_MIN 1 -#define OV13858_DGTL_GAIN_MAX 4 -#define OV13858_DGTL_GAIN_STEP 1 -#define OV13858_DGTL_GAIN_DEFAULT 1 +#define OV13858_REG_B_MWB_GAIN 0x5100 +#define OV13858_REG_G_MWB_GAIN 0x5102 +#define OV13858_REG_R_MWB_GAIN 0x5104 +#define OV13858_DGTL_GAIN_MIN 0 +#define OV13858_DGTL_GAIN_MAX 16384 /* Max = 16 X */ +#define OV13858_DGTL_GAIN_DEFAULT 1024 /* Default gain = 1 X */ +#define OV13858_DGTL_GAIN_STEP 1 /* Each step = 1/1024 */ /* Test Pattern Control */ #define OV13858_REG_TEST_PATTERN 0x4503 @@ -1162,21 +1162,21 @@ static int ov13858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) static int ov13858_update_digital_gain(struct ov13858 *ov13858, u32 d_gain) { int ret; - u32 val; - if (d_gain == 3) - return -EINVAL; + ret = ov13858_write_reg(ov13858, OV13858_REG_B_MWB_GAIN, + OV13858_REG_VALUE_16BIT, d_gain); + if (ret) + return ret; - ret = ov13858_read_reg(ov13858, OV13858_REG_DIGITAL_GAIN, - OV13858_REG_VALUE_08BIT, &val); + ret = ov13858_write_reg(ov13858, OV13858_REG_G_MWB_GAIN, + OV13858_REG_VALUE_16BIT, d_gain); if (ret) return ret; - val &= OV13858_DGTL_GAIN_MASK; - val |= (d_gain - 1) << OV13858_DGTL_GAIN_SHIFT; + ret = ov13858_write_reg(ov13858, OV13858_REG_R_MWB_GAIN, + OV13858_REG_VALUE_16BIT, d_gain); - return ov13858_write_reg(ov13858, OV13858_REG_DIGITAL_GAIN, - OV13858_REG_VALUE_08BIT, val); + return ret; } static int ov13858_enable_test_pattern(struct ov13858 *ov13858, u32 pattern) -- cgit v1.2.3 From 71bfcc6558444af7a434ece4b3f344581c65009e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 7 Aug 2017 15:02:32 -0400 Subject: media: vs6624: constify vs6624_default_fmt The structure vs6624_default_fmt is only copied into another structure field, so it can be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/vs6624.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index f0741ab338df..560738213c00 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -58,7 +58,7 @@ static const struct vs6624_format { }, }; -static struct v4l2_mbus_framefmt vs6624_default_fmt = { +static const struct v4l2_mbus_framefmt vs6624_default_fmt = { .width = VGA_WIDTH, .height = VGA_HEIGHT, .code = MEDIA_BUS_FMT_UYVY8_2X8, -- cgit v1.2.3 From 335bb883af31baa56be0f5f5630ac50310d222cd Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 29 Jul 2017 07:28:35 -0400 Subject: media: ddbridge: move/reorder functions The functions in ddbridge-core.c have been moved to different positions in newer versions of the dddvb vendor driver package (most notably in version 0.9.9b). Perform the same code move to keep the diff of the upcoming code bump simpler. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 660 ++++++++++++++--------------- 1 file changed, 327 insertions(+), 333 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index ec41804d78c7..d6dcc42ff222 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -404,43 +404,6 @@ static void ddb_buffers_free(struct ddb *dev) } } -static void ddb_input_start(struct ddb_input *input) -{ - struct ddb *dev = input->port->dev; - - spin_lock_irq(&input->lock); - input->cbuf = 0; - input->coff = 0; - - /* reset */ - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(2, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - - ddbwritel((1 << 16) | - (input->dma_buf_num << 11) | - (input->dma_buf_size >> 7), - DMA_BUFFER_SIZE(input->nr)); - ddbwritel(0, DMA_BUFFER_ACK(input->nr)); - - ddbwritel(1, DMA_BASE_WRITE); - ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); - ddbwritel(9, TS_INPUT_CONTROL(input->nr)); - input->running = 1; - spin_unlock_irq(&input->lock); -} - -static void ddb_input_stop(struct ddb_input *input) -{ - struct ddb *dev = input->port->dev; - - spin_lock_irq(&input->lock); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); - input->running = 0; - spin_unlock_irq(&input->lock); -} - static void ddb_output_start(struct ddb_output *output) { struct ddb *dev = output->port->dev; @@ -477,6 +440,43 @@ static void ddb_output_stop(struct ddb_output *output) spin_unlock_irq(&output->lock); } +static void ddb_input_stop(struct ddb_input *input) +{ + struct ddb *dev = input->port->dev; + + spin_lock_irq(&input->lock); + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); + input->running = 0; + spin_unlock_irq(&input->lock); +} + +static void ddb_input_start(struct ddb_input *input) +{ + struct ddb *dev = input->port->dev; + + spin_lock_irq(&input->lock); + input->cbuf = 0; + input->coff = 0; + + /* reset */ + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + ddbwritel(2, TS_INPUT_CONTROL(input->nr)); + ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + + ddbwritel((1 << 16) | + (input->dma_buf_num << 11) | + (input->dma_buf_size >> 7), + DMA_BUFFER_SIZE(input->nr)); + ddbwritel(0, DMA_BUFFER_ACK(input->nr)); + + ddbwritel(1, DMA_BASE_WRITE); + ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); + ddbwritel(9, TS_INPUT_CONTROL(input->nr)); + input->running = 1; + spin_unlock_irq(&input->lock); +} + static u32 ddb_output_free(struct ddb_output *output) { u32 idx, off, stat = output->stat; @@ -595,7 +595,98 @@ static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t co return count; } -/******************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static ssize_t ts_write(struct file *file, const __user char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + size_t left = count; + int stat; + + while (left) { + if (ddb_output_free(output) < 188) { + if (file->f_flags & O_NONBLOCK) + break; + if (wait_event_interruptible( + output->wq, ddb_output_free(output) >= 188) < 0) + break; + } + stat = ddb_output_write(output, buf, left); + if (stat < 0) + break; + buf += stat; + left -= stat; + } + return (left == count) ? -EAGAIN : (count - left); +} + +static ssize_t ts_read(struct file *file, __user char *buf, + size_t count, loff_t *ppos) +{ + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + struct ddb_input *input = output->port->input[0]; + int left, read; + + count -= count % 188; + left = count; + while (left) { + if (ddb_input_avail(input) < 188) { + if (file->f_flags & O_NONBLOCK) + break; + if (wait_event_interruptible( + input->wq, ddb_input_avail(input) >= 188) < 0) + break; + } + read = ddb_input_read(input, buf, left); + if (read < 0) + return read; + left -= read; + buf += read; + } + return (left == count) ? -EAGAIN : (count - left); +} + +static unsigned int ts_poll(struct file *file, poll_table *wait) +{ + /* + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + struct ddb_input *input = output->port->input[0]; + */ + unsigned int mask = 0; + +#if 0 + if (data_avail_to_read) + mask |= POLLIN | POLLRDNORM; + if (data_avail_to_write) + mask |= POLLOUT | POLLWRNORM; + + poll_wait(file, &read_queue, wait); + poll_wait(file, &write_queue, wait); +#endif + return mask; +} + +static const struct file_operations ci_fops = { + .owner = THIS_MODULE, + .read = ts_read, + .write = ts_write, + .open = dvb_generic_open, + .release = dvb_generic_release, + .poll = ts_poll, +}; + +static struct dvb_device dvbdev_ci = { + .readers = -1, + .writers = -1, + .users = -1, + .fops = &ci_fops, +}; + /******************************************************************************/ /******************************************************************************/ @@ -1261,251 +1352,72 @@ static int dvb_input_attach(struct ddb_input *input) return 0; } -/****************************************************************************/ -/****************************************************************************/ - -static ssize_t ts_write(struct file *file, const __user char *buf, - size_t count, loff_t *ppos) +static int port_has_ci(struct ddb_port *port) { - struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - size_t left = count; - int stat; - - while (left) { - if (ddb_output_free(output) < 188) { - if (file->f_flags & O_NONBLOCK) - break; - if (wait_event_interruptible( - output->wq, ddb_output_free(output) >= 188) < 0) - break; - } - stat = ddb_output_write(output, buf, left); - if (stat < 0) - break; - buf += stat; - left -= stat; - } - return (left == count) ? -EAGAIN : (count - left); + u8 val; + return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; } -static ssize_t ts_read(struct file *file, __user char *buf, - size_t count, loff_t *ppos) +static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id) { - struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; - int left, read; + u8 probe[1] = { 0x00 }, data[4]; - count -= count % 188; - left = count; - while (left) { - if (ddb_input_avail(input) < 188) { - if (file->f_flags & O_NONBLOCK) - break; - if (wait_event_interruptible( - input->wq, ddb_input_avail(input) >= 188) < 0) - break; - } - read = ddb_input_read(input, buf, left); - if (read < 0) - return read; - left -= read; - buf += read; + *type = DDB_XO2_TYPE_NONE; + + if (i2c_io(&port->i2c->adap, 0x10, probe, 1, data, 4)) + return 0; + if (data[0] == 'D' && data[1] == 'F') { + *id = data[2]; + *type = DDB_XO2_TYPE_DUOFLEX; + return 1; } - return (left == count) ? -EAGAIN : (count - left); + if (data[0] == 'C' && data[1] == 'I') { + *id = data[2]; + *type = DDB_XO2_TYPE_CI; + return 1; + } + return 0; } -static unsigned int ts_poll(struct file *file, poll_table *wait) +static int port_has_stv0900(struct ddb_port *port) { - /* - struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; - */ - unsigned int mask = 0; - -#if 0 - if (data_avail_to_read) - mask |= POLLIN | POLLRDNORM; - if (data_avail_to_write) - mask |= POLLOUT | POLLWRNORM; - - poll_wait(file, &read_queue, wait); - poll_wait(file, &write_queue, wait); -#endif - return mask; + u8 val; + if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) + return 0; + return 1; } -static const struct file_operations ci_fops = { - .owner = THIS_MODULE, - .read = ts_read, - .write = ts_write, - .open = dvb_generic_open, - .release = dvb_generic_release, - .poll = ts_poll, -}; - -static struct dvb_device dvbdev_ci = { - .readers = -1, - .writers = -1, - .users = -1, - .fops = &ci_fops, -}; - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - -static void input_tasklet(unsigned long data) -{ - struct ddb_input *input = (struct ddb_input *) data; - struct ddb *dev = input->port->dev; - - spin_lock(&input->lock); - if (!input->running) { - spin_unlock(&input->lock); - return; - } - input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); - - if (input->port->class == DDB_PORT_TUNER) { - if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) - dev_err(&dev->pdev->dev, "Overflow input %d\n", input->nr); - while (input->cbuf != ((input->stat >> 11) & 0x1f) - || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) { - dvb_dmx_swfilter_packets(&input->demux, - input->vbuf[input->cbuf], - input->dma_buf_size / 188); - - input->cbuf = (input->cbuf + 1) % input->dma_buf_num; - ddbwritel((input->cbuf << 11), - DMA_BUFFER_ACK(input->nr)); - input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); - } - } - if (input->port->class == DDB_PORT_CI) - wake_up(&input->wq); - spin_unlock(&input->lock); -} - -static void output_tasklet(unsigned long data) -{ - struct ddb_output *output = (struct ddb_output *) data; - struct ddb *dev = output->port->dev; - - spin_lock(&output->lock); - if (!output->running) { - spin_unlock(&output->lock); - return; - } - output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); - wake_up(&output->wq); - spin_unlock(&output->lock); -} - - -static struct cxd2099_cfg cxd_cfg = { - .bitrate = 62000, - .adr = 0x40, - .polarity = 1, - .clock_mode = 1, - .max_i2c = 512, -}; - -static int ddb_ci_attach(struct ddb_port *port) -{ - int ret; - - ret = dvb_register_adapter(&port->output->adap, - "DDBridge", - THIS_MODULE, - &port->dev->pdev->dev, - adapter_nr); - if (ret < 0) - return ret; - port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); - if (!port->en) { - dvb_unregister_adapter(&port->output->adap); - return -ENODEV; - } - ddb_input_start(port->input[0]); - ddb_output_start(port->output); - dvb_ca_en50221_init(&port->output->adap, - port->en, 0, 1); - ret = dvb_register_device(&port->output->adap, &port->output->dev, - &dvbdev_ci, (void *) port->output, - DVB_DEVICE_SEC, 0); - return ret; -} - -static int ddb_port_attach(struct ddb_port *port) +static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) { - struct device *dev = &port->dev->pdev->dev; - int ret = 0; - - switch (port->class) { - case DDB_PORT_TUNER: - ret = dvb_input_attach(port->input[0]); - if (ret < 0) - break; - ret = dvb_input_attach(port->input[1]); - break; - case DDB_PORT_CI: - ret = ddb_ci_attach(port); - break; - default: - break; - } - if (ret < 0) - dev_err(dev, "port_attach on port %d failed\n", port->nr); - return ret; + if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) + return 0; + return 1; } -static int ddb_ports_attach(struct ddb *dev) +static int port_has_drxks(struct ddb_port *port) { - int i, ret = 0; - struct ddb_port *port; - - for (i = 0; i < dev->info->port_num; i++) { - port = &dev->port[i]; - ret = ddb_port_attach(port); - if (ret < 0) - break; - } - return ret; + u8 val; + if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) + return 0; + if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) + return 0; + return 1; } -static void ddb_ports_detach(struct ddb *dev) +static int port_has_stv0367(struct ddb_port *port) { - int i; - struct ddb_port *port; - - for (i = 0; i < dev->info->port_num; i++) { - port = &dev->port[i]; - switch (port->class) { - case DDB_PORT_TUNER: - dvb_input_detach(port->input[0]); - dvb_input_detach(port->input[1]); - break; - case DDB_PORT_CI: - dvb_unregister_device(port->output->dev); - if (port->en) { - ddb_input_stop(port->input[0]); - ddb_output_stop(port->output); - dvb_ca_en50221_release(port->en); - kfree(port->en); - port->en = NULL; - dvb_unregister_adapter(&port->output->adap); - } - break; - } - } + u8 val; + if (i2c_read_reg16(&port->i2c->adap, 0x1e, 0xf000, &val) < 0) + return 0; + if (val != 0x60) + return 0; + if (i2c_read_reg16(&port->i2c->adap, 0x1f, 0xf000, &val) < 0) + return 0; + if (val != 0x60) + return 0; + return 1; } -/****************************************************************************/ -/****************************************************************************/ - static int init_xo2(struct ddb_port *port) { struct i2c_adapter *i2c = &port->i2c->adap; @@ -1547,75 +1459,6 @@ static int init_xo2(struct ddb_port *port) return 0; } -static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id) -{ - u8 probe[1] = { 0x00 }, data[4]; - - *type = DDB_XO2_TYPE_NONE; - - if (i2c_io(&port->i2c->adap, 0x10, probe, 1, data, 4)) - return 0; - if (data[0] == 'D' && data[1] == 'F') { - *id = data[2]; - *type = DDB_XO2_TYPE_DUOFLEX; - return 1; - } - if (data[0] == 'C' && data[1] == 'I') { - *id = data[2]; - *type = DDB_XO2_TYPE_CI; - return 1; - } - return 0; -} - -/****************************************************************************/ -/****************************************************************************/ - -static int port_has_ci(struct ddb_port *port) -{ - u8 val; - return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; -} - -static int port_has_stv0900(struct ddb_port *port) -{ - u8 val; - if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) - return 0; - return 1; -} - -static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) -{ - if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, id) < 0) - return 0; - return 1; -} - -static int port_has_drxks(struct ddb_port *port) -{ - u8 val; - if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) - return 0; - if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) - return 0; - return 1; -} - -static int port_has_stv0367(struct ddb_port *port) -{ - u8 val; - if (i2c_read_reg16(&port->i2c->adap, 0x1e, 0xf000, &val) < 0) - return 0; - if (val != 0x60) - return 0; - if (i2c_read_reg16(&port->i2c->adap, 0x1f, 0xf000, &val) < 0) - return 0; - if (val != 0x60) - return 0; - return 1; -} - static int port_has_cxd28xx(struct ddb_port *port, u8 *id) { struct i2c_adapter *i2c = &port->i2c->adap; @@ -1758,6 +1601,158 @@ static void ddb_port_probe(struct ddb_port *port) port->nr, port->nr+1, modname); } +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static struct cxd2099_cfg cxd_cfg = { + .bitrate = 62000, + .adr = 0x40, + .polarity = 1, + .clock_mode = 1, + .max_i2c = 512, +}; + +static int ddb_ci_attach(struct ddb_port *port) +{ + int ret; + + ret = dvb_register_adapter(&port->output->adap, + "DDBridge", + THIS_MODULE, + &port->dev->pdev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); + if (!port->en) { + dvb_unregister_adapter(&port->output->adap); + return -ENODEV; + } + ddb_input_start(port->input[0]); + ddb_output_start(port->output); + dvb_ca_en50221_init(&port->output->adap, + port->en, 0, 1); + ret = dvb_register_device(&port->output->adap, &port->output->dev, + &dvbdev_ci, (void *) port->output, + DVB_DEVICE_SEC, 0); + return ret; +} + +static int ddb_port_attach(struct ddb_port *port) +{ + struct device *dev = &port->dev->pdev->dev; + int ret = 0; + + switch (port->class) { + case DDB_PORT_TUNER: + ret = dvb_input_attach(port->input[0]); + if (ret < 0) + break; + ret = dvb_input_attach(port->input[1]); + break; + case DDB_PORT_CI: + ret = ddb_ci_attach(port); + break; + default: + break; + } + if (ret < 0) + dev_err(dev, "port_attach on port %d failed\n", port->nr); + return ret; +} + +static int ddb_ports_attach(struct ddb *dev) +{ + int i, ret = 0; + struct ddb_port *port; + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + ret = ddb_port_attach(port); + if (ret < 0) + break; + } + return ret; +} + +static void ddb_ports_detach(struct ddb *dev) +{ + int i; + struct ddb_port *port; + + for (i = 0; i < dev->info->port_num; i++) { + port = &dev->port[i]; + switch (port->class) { + case DDB_PORT_TUNER: + dvb_input_detach(port->input[0]); + dvb_input_detach(port->input[1]); + break; + case DDB_PORT_CI: + dvb_unregister_device(port->output->dev); + if (port->en) { + ddb_input_stop(port->input[0]); + ddb_output_stop(port->output); + dvb_ca_en50221_release(port->en); + kfree(port->en); + port->en = NULL; + dvb_unregister_adapter(&port->output->adap); + } + break; + } + } +} + +static void input_tasklet(unsigned long data) +{ + struct ddb_input *input = (struct ddb_input *) data; + struct ddb *dev = input->port->dev; + + spin_lock(&input->lock); + if (!input->running) { + spin_unlock(&input->lock); + return; + } + input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); + + if (input->port->class == DDB_PORT_TUNER) { + if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) + dev_err(&dev->pdev->dev, "Overflow input %d\n", input->nr); + while (input->cbuf != ((input->stat >> 11) & 0x1f) + || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) { + dvb_dmx_swfilter_packets(&input->demux, + input->vbuf[input->cbuf], + input->dma_buf_size / 188); + + input->cbuf = (input->cbuf + 1) % input->dma_buf_num; + ddbwritel((input->cbuf << 11), + DMA_BUFFER_ACK(input->nr)); + input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); + } + } + if (input->port->class == DDB_PORT_CI) + wake_up(&input->wq); + spin_unlock(&input->lock); +} + +static void output_tasklet(unsigned long data) +{ + struct ddb_output *output = (struct ddb_output *) data; + struct ddb *dev = output->port->dev; + + spin_lock(&output->lock); + if (!output->running) { + spin_unlock(&output->lock); + return; + } + output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); + wake_up(&output->wq); + spin_unlock(&output->lock); +} + +/****************************************************************************/ +/****************************************************************************/ + static void ddb_input_init(struct ddb_port *port, int nr) { struct ddb *dev = port->dev; @@ -2084,7 +2079,6 @@ static void ddb_device_destroy(struct ddb *dev) device_destroy(ddb_class, MKDEV(ddb_major, 0)); } - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ -- cgit v1.2.3 From a96e5ab8a713e99b5d4a4b9110d7226f8dbc97ea Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 29 Jul 2017 07:28:36 -0400 Subject: media: ddbridge: split code into multiple files As of 0.9.9b, the ddbridge code has been split from one single file (ddbridge-core.c) into multiple files, with the purpose of taking care of different topics, and to be able to reuse code in different kernel modules (ddbridge.ko and octonet.ko). This applies the same code split, with a notable difference: In the vendor package, the split was done by moving all code parts into separate files, and in the "main" code files (ddbridge.c and octonet.c), a simple "#include ddbridge-core.c" was done. In this patch, the same split (codewise) is done, but all resulting .c/.o files will be handled by the makefile, with proper prototyping of all shared functions done in ddbridge.h. To avoid conflicts wrt the global space, the I2C functions and necessary prototypes for ddbridge-i2c.c are moved into ddbridge-i2c.h, which is to be included wherever required. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/Makefile | 2 +- drivers/media/pci/ddbridge/ddbridge-core.c | 589 +---------------------------- drivers/media/pci/ddbridge/ddbridge-i2c.c | 173 +++++++++ drivers/media/pci/ddbridge/ddbridge-i2c.h | 99 +++++ drivers/media/pci/ddbridge/ddbridge-main.c | 389 +++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge.h | 35 ++ 6 files changed, 710 insertions(+), 577 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.c create mode 100644 drivers/media/pci/ddbridge/ddbridge-i2c.h create mode 100644 drivers/media/pci/ddbridge/ddbridge-main.c (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index 7446c8b677b5..fe8ff0c681ad 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -2,7 +2,7 @@ # Makefile for the ddbridge device driver # -ddbridge-objs := ddbridge-core.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index d6dcc42ff222..7e164a370273 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -32,8 +32,9 @@ #include #include #include -#include "ddbridge.h" +#include "ddbridge.h" +#include "ddbridge-i2c.h" #include "ddbridge-regs.h" #include "tda18271c2dd.h" @@ -49,227 +50,8 @@ #include "stv6111.h" #include "lnbh25.h" -static int xo2_speed = 2; -module_param(xo2_speed, int, 0444); -MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); - -static int stv0910_single; -module_param(stv0910_single, int, 0444); -MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -/* MSI had problems with lost interrupts, fixed but needs testing */ -#undef CONFIG_PCI_MSI - -/******************************************************************************/ - -static int i2c_io(struct i2c_adapter *adapter, u8 adr, - u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) -{ - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = wbuf, .len = wlen }, - {.addr = adr, .flags = I2C_M_RD, - .buf = rbuf, .len = rlen } }; - return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -} - -static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) -{ - struct i2c_msg msg = {.addr = adr, .flags = 0, - .buf = data, .len = len}; - - return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; -} - -static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) -{ - struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = 1 } }; - return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; -} - -static int i2c_read_regs(struct i2c_adapter *adapter, - u8 adr, u8 reg, u8 *val, u8 len) -{ - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = ®, .len = 1 }, - {.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = len } }; - return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -} - -static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) -{ - return i2c_read_regs(adapter, adr, reg, val, 1); -} - -static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, - u16 reg, u8 *val) -{ - u8 msg[2] = {reg>>8, reg&0xff}; - struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, - .buf = msg, .len = 2}, - {.addr = adr, .flags = I2C_M_RD, - .buf = val, .len = 1} }; - return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; -} - -static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, - u8 reg, u8 val) -{ - u8 msg[2] = {reg, val}; - - return i2c_write(adap, adr, msg, 2); -} - -static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) -{ - u32 val = ddbreadl(adr); - - /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ - if (val == ~0) { - dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); - return 0; - } - - return val; -} - -static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) -{ - struct ddb *dev = i2c->dev; - long stat; - u32 val; - - i2c->done = 0; - ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); - stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); - if (stat == 0) { - dev_err(&dev->pdev->dev, "I2C timeout\n"); - { /* MSI debugging*/ - u32 istat = ddbreadl(INTERRUPT_STATUS); - dev_err(&dev->pdev->dev, "IRS %08x\n", istat); - ddbwritel(istat, INTERRUPT_ACK); - } - return -EIO; - } - val = ddbreadl(i2c->regs+I2C_COMMAND); - if (val & 0x70000) - return -EIO; - return 0; -} - -static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, - struct i2c_msg msg[], int num) -{ - struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); - struct ddb *dev = i2c->dev; - u8 addr = 0; - - if (num) - addr = msg[0].addr; - - if (num == 2 && msg[1].flags & I2C_M_RD && - !(msg[0].flags & I2C_M_RD)) { - memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, - msg[0].buf, msg[0].len); - ddbwritel(msg[0].len|(msg[1].len << 16), - i2c->regs+I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 1)) { - memcpy_fromio(msg[1].buf, - dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, - msg[1].len); - return num; - } - } - - if (num == 1 && !(msg[0].flags & I2C_M_RD)) { - ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 2)) - return num; - } - if (num == 1 && (msg[0].flags & I2C_M_RD)) { - ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 3)) { - ddbcpyfrom(msg[0].buf, - I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); - return num; - } - } - return -EIO; -} - - -static u32 ddb_i2c_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm ddb_i2c_algo = { - .master_xfer = ddb_i2c_master_xfer, - .functionality = ddb_i2c_functionality, -}; - -static void ddb_i2c_release(struct ddb *dev) -{ - int i; - struct ddb_i2c *i2c; - struct i2c_adapter *adap; - - for (i = 0; i < dev->info->port_num; i++) { - i2c = &dev->i2c[i]; - adap = &i2c->adap; - i2c_del_adapter(adap); - } -} - -static int ddb_i2c_init(struct ddb *dev) -{ - int i, j, stat = 0; - struct ddb_i2c *i2c; - struct i2c_adapter *adap; - - for (i = 0; i < dev->info->port_num; i++) { - i2c = &dev->i2c[i]; - i2c->dev = dev; - i2c->nr = i; - i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); - i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); - i2c->regs = 0x80 + i * 0x20; - ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); - ddbwritel((i2c->rbuf << 16) | i2c->wbuf, - i2c->regs + I2C_TASKADDRESS); - init_waitqueue_head(&i2c->wq); - - adap = &i2c->adap; - i2c_set_adapdata(adap, i2c); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; -#else -#ifdef I2C_CLASS_TV_ANALOG - adap->class = I2C_CLASS_TV_ANALOG; -#endif -#endif - strcpy(adap->name, "ddbridge"); - adap->algo = &ddb_i2c_algo; - adap->algo_data = (void *)i2c; - adap->dev.parent = &dev->pdev->dev; - stat = i2c_add_adapter(adap); - if (stat) - break; - } - if (stat) - for (j = 0; j < i; j++) { - i2c = &dev->i2c[j]; - adap = &i2c->adap; - i2c_del_adapter(adap); - } - return stat; -} - - /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ @@ -342,7 +124,7 @@ static int io_alloc(struct pci_dev *pdev, u8 **vbuf, return 0; } -static int ddb_buffers_alloc(struct ddb *dev) +int ddb_buffers_alloc(struct ddb *dev) { int i; struct ddb_port *port; @@ -382,7 +164,7 @@ static int ddb_buffers_alloc(struct ddb *dev) return 0; } -static void ddb_buffers_free(struct ddb *dev) +void ddb_buffers_free(struct ddb *dev) { int i; struct ddb_port *port; @@ -1662,7 +1444,7 @@ static int ddb_port_attach(struct ddb_port *port) return ret; } -static int ddb_ports_attach(struct ddb *dev) +int ddb_ports_attach(struct ddb *dev) { int i, ret = 0; struct ddb_port *port; @@ -1676,7 +1458,7 @@ static int ddb_ports_attach(struct ddb *dev) return ret; } -static void ddb_ports_detach(struct ddb *dev) +void ddb_ports_detach(struct ddb *dev) { int i; struct ddb_port *port; @@ -1787,7 +1569,7 @@ static void ddb_output_init(struct ddb_port *port, int nr) init_waitqueue_head(&output->wq); } -static void ddb_ports_init(struct ddb *dev) +void ddb_ports_init(struct ddb *dev) { int i; struct ddb_port *port; @@ -1809,7 +1591,7 @@ static void ddb_ports_init(struct ddb *dev) } } -static void ddb_ports_release(struct ddb *dev) +void ddb_ports_release(struct ddb *dev) { int i; struct ddb_port *port; @@ -1835,7 +1617,7 @@ static void irq_handle_i2c(struct ddb *dev, int n) wake_up(&i2c->wq); } -static irqreturn_t irq_handler(int irq, void *dev_id) +irqreturn_t irq_handler(int irq, void *dev_id) { struct ddb *dev = (struct ddb *) dev_id; u32 s = ddbreadl(INTERRUPT_STATUS); @@ -2038,7 +1820,7 @@ static char *ddb_devnode(struct device *device, umode_t *mode) return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); } -static int ddb_class_create(void) +int ddb_class_create(void) { ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); if (ddb_major < 0) @@ -2053,13 +1835,13 @@ static int ddb_class_create(void) return 0; } -static void ddb_class_destroy(void) +void ddb_class_destroy(void) { class_destroy(ddb_class); unregister_chrdev(ddb_major, DDB_NAME); } -static int ddb_device_create(struct ddb *dev) +int ddb_device_create(struct ddb *dev) { dev->nr = ddb_num++; dev->ddb_dev = device_create(ddb_class, NULL, @@ -2071,355 +1853,10 @@ static int ddb_device_create(struct ddb *dev) return 0; } -static void ddb_device_destroy(struct ddb *dev) +void ddb_device_destroy(struct ddb *dev) { ddb_num--; if (IS_ERR(dev->ddb_dev)) return; device_destroy(ddb_class, MKDEV(ddb_major, 0)); } - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - -static void ddb_unmap(struct ddb *dev) -{ - if (dev->regs) - iounmap(dev->regs); - vfree(dev); -} - - -static void ddb_remove(struct pci_dev *pdev) -{ - struct ddb *dev = pci_get_drvdata(pdev); - - ddb_ports_detach(dev); - ddb_i2c_release(dev); - - ddbwritel(0, INTERRUPT_ENABLE); - free_irq(dev->pdev->irq, dev); -#ifdef CONFIG_PCI_MSI - if (dev->msi) - pci_disable_msi(dev->pdev); -#endif - ddb_ports_release(dev); - ddb_buffers_free(dev); - ddb_device_destroy(dev); - - ddb_unmap(dev); - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); -} - - -static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct ddb *dev; - int stat = 0; - int irq_flag = IRQF_SHARED; - - if (pci_enable_device(pdev) < 0) - return -ENODEV; - - dev = vzalloc(sizeof(struct ddb)); - if (dev == NULL) - return -ENOMEM; - - dev->pdev = pdev; - pci_set_drvdata(pdev, dev); - dev->info = (struct ddb_info *) id->driver_data; - dev_info(&pdev->dev, "Detected %s\n", dev->info->name); - - dev->regs = ioremap(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0)); - if (!dev->regs) { - stat = -ENOMEM; - goto fail; - } - dev_info(&pdev->dev, "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); - -#ifdef CONFIG_PCI_MSI - if (pci_msi_enabled()) - stat = pci_enable_msi(dev->pdev); - if (stat) { - dev_info(&pdev->dev, "MSI not available.\n"); - } else { - irq_flag = 0; - dev->msi = 1; - } -#endif - stat = request_irq(dev->pdev->irq, irq_handler, - irq_flag, "DDBridge", (void *) dev); - if (stat < 0) - goto fail1; - ddbwritel(0, DMA_BASE_WRITE); - ddbwritel(0, DMA_BASE_READ); - ddbwritel(0xffffffff, INTERRUPT_ACK); - ddbwritel(0xfff0f, INTERRUPT_ENABLE); - ddbwritel(0, MSI1_ENABLE); - - /* board control */ - if (dev->info->board_control) { - ddbwritel(0, DDB_LINK_TAG(0) | BOARD_CONTROL); - msleep(100); - ddbwritel(dev->info->board_control_2, - DDB_LINK_TAG(0) | BOARD_CONTROL); - usleep_range(2000, 3000); - ddbwritel(dev->info->board_control_2 - | dev->info->board_control, - DDB_LINK_TAG(0) | BOARD_CONTROL); - usleep_range(2000, 3000); - } - - if (ddb_i2c_init(dev) < 0) - goto fail1; - ddb_ports_init(dev); - if (ddb_buffers_alloc(dev) < 0) { - dev_err(&pdev->dev, "Could not allocate buffer memory\n"); - goto fail2; - } - if (ddb_ports_attach(dev) < 0) - goto fail3; - ddb_device_create(dev); - return 0; - -fail3: - ddb_ports_detach(dev); - dev_err(&pdev->dev, "fail3\n"); - ddb_ports_release(dev); -fail2: - dev_err(&pdev->dev, "fail2\n"); - ddb_buffers_free(dev); -fail1: - dev_err(&pdev->dev, "fail1\n"); - if (dev->msi) - pci_disable_msi(dev->pdev); - if (stat == 0) - free_irq(dev->pdev->irq, dev); -fail: - dev_err(&pdev->dev, "fail\n"); - ddb_unmap(dev); - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); - return -1; -} - -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ - -static const struct ddb_info ddb_none = { - .type = DDB_NONE, - .name = "Digital Devices PCIe bridge", -}; - -static const struct ddb_info ddb_octopus = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus DVB adapter", - .port_num = 4, -}; - -static const struct ddb_info ddb_octopus_le = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus LE DVB adapter", - .port_num = 2, -}; - -static const struct ddb_info ddb_octopus_oem = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus OEM", - .port_num = 4, -}; - -static const struct ddb_info ddb_octopus_mini = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus Mini", - .port_num = 4, -}; - -static const struct ddb_info ddb_v6 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V6 DVB adapter", - .port_num = 3, -}; -static const struct ddb_info ddb_v6_5 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V6.5 DVB adapter", - .port_num = 4, -}; - -static const struct ddb_info ddb_v7 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V7 DVB adapter", - .port_num = 4, - .board_control = 2, - .board_control_2 = 4, - .ts_quirks = TS_QUIRK_REVERSED, -}; - -static const struct ddb_info ddb_v7a = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", - .port_num = 4, - .board_control = 2, - .board_control_2 = 4, - .ts_quirks = TS_QUIRK_REVERSED, -}; - -static const struct ddb_info ddb_dvbct = { - .type = DDB_OCTOPUS, - .name = "Digital Devices DVBCT V6.1 DVB adapter", - .port_num = 3, -}; - -static const struct ddb_info ddb_ctv7 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine CT V7 DVB adapter", - .port_num = 4, - .board_control = 3, - .board_control_2 = 4, -}; - -static const struct ddb_info ddb_satixS2v3 = { - .type = DDB_OCTOPUS, - .name = "Mystique SaTiX-S2 V3 DVB adapter", - .port_num = 3, -}; - -static const struct ddb_info ddb_octopusv3 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus V3 DVB adapter", - .port_num = 4, -}; - -/*** MaxA8 adapters ***********************************************************/ - -static struct ddb_info ddb_ct2_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 CT2", - .port_num = 4, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, -}; - -static struct ddb_info ddb_c2t2_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2", - .port_num = 4, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, -}; - -static struct ddb_info ddb_isdbt_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 ISDBT", - .port_num = 4, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, -}; - -static struct ddb_info ddb_c2t2i_v0_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2I V0", - .port_num = 4, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, -}; - -static struct ddb_info ddb_c2t2i_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2I", - .port_num = 4, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, -}; - -/******************************************************************************/ - -#define DDVID 0xdd01 /* Digital Devices Vendor ID */ - -#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ - .vendor = _vend, .device = _dev, \ - .subvendor = _subvend, .subdevice = _subdev, \ - .driver_data = (unsigned long)&_driverdata } - -static const struct pci_device_id ddb_id_tbl[] = { - DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), - DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), - DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), - DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), - DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), - DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), - DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), - DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a), - DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), - DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), - DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), - DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8), - DDB_ID(DDVID, 0x0006, DDVID, 0x0039, ddb_ctv7), - /* in case sub-ids got deleted in flash */ - DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - {0} -}; -MODULE_DEVICE_TABLE(pci, ddb_id_tbl); - - -static struct pci_driver ddb_pci_driver = { - .name = "DDBridge", - .id_table = ddb_id_tbl, - .probe = ddb_probe, - .remove = ddb_remove, -}; - -static __init int module_init_ddbridge(void) -{ - int ret; - - pr_info("Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n"); - - ret = ddb_class_create(); - if (ret < 0) - return ret; - ret = pci_register_driver(&ddb_pci_driver); - if (ret < 0) - ddb_class_destroy(); - return ret; -} - -static __exit void module_exit_ddbridge(void) -{ - pci_unregister_driver(&ddb_pci_driver); - ddb_class_destroy(); -} - -module_init(module_init_ddbridge); -module_exit(module_exit_ddbridge); - -MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); -MODULE_AUTHOR("Ralph Metzler"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.5"); diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c new file mode 100644 index 000000000000..45287f98ee92 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -0,0 +1,173 @@ +/* + * ddbridge.c: Digital Devices PCIe bridge driver + * + * Copyright (C) 2010-2011 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * To obtain the license, point your browser to + * http://www.gnu.org/copyleft/gpl.html + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddbridge.h" +#include "ddbridge-regs.h" +#include "ddbridge-i2c.h" + +/******************************************************************************/ + +static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) +{ + struct ddb *dev = i2c->dev; + long stat; + u32 val; + + i2c->done = 0; + ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); + stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); + if (stat == 0) { + dev_err(&dev->pdev->dev, "I2C timeout\n"); + { /* MSI debugging*/ + u32 istat = ddbreadl(INTERRUPT_STATUS); + dev_err(&dev->pdev->dev, "IRS %08x\n", istat); + ddbwritel(istat, INTERRUPT_ACK); + } + return -EIO; + } + val = ddbreadl(i2c->regs+I2C_COMMAND); + if (val & 0x70000) + return -EIO; + return 0; +} + +static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, + struct i2c_msg msg[], int num) +{ + struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); + struct ddb *dev = i2c->dev; + u8 addr = 0; + + if (num) + addr = msg[0].addr; + + if (num == 2 && msg[1].flags & I2C_M_RD && + !(msg[0].flags & I2C_M_RD)) { + memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, + msg[0].buf, msg[0].len); + ddbwritel(msg[0].len|(msg[1].len << 16), + i2c->regs+I2C_TASKLENGTH); + if (!ddb_i2c_cmd(i2c, addr, 1)) { + memcpy_fromio(msg[1].buf, + dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, + msg[1].len); + return num; + } + } + + if (num == 1 && !(msg[0].flags & I2C_M_RD)) { + ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); + if (!ddb_i2c_cmd(i2c, addr, 2)) + return num; + } + if (num == 1 && (msg[0].flags & I2C_M_RD)) { + ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); + if (!ddb_i2c_cmd(i2c, addr, 3)) { + ddbcpyfrom(msg[0].buf, + I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); + return num; + } + } + return -EIO; +} + + +static u32 ddb_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm ddb_i2c_algo = { + .master_xfer = ddb_i2c_master_xfer, + .functionality = ddb_i2c_functionality, +}; + +void ddb_i2c_release(struct ddb *dev) +{ + int i; + struct ddb_i2c *i2c; + struct i2c_adapter *adap; + + for (i = 0; i < dev->info->port_num; i++) { + i2c = &dev->i2c[i]; + adap = &i2c->adap; + i2c_del_adapter(adap); + } +} + +int ddb_i2c_init(struct ddb *dev) +{ + int i, j, stat = 0; + struct ddb_i2c *i2c; + struct i2c_adapter *adap; + + for (i = 0; i < dev->info->port_num; i++) { + i2c = &dev->i2c[i]; + i2c->dev = dev; + i2c->nr = i; + i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); + i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); + i2c->regs = 0x80 + i * 0x20; + ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); + ddbwritel((i2c->rbuf << 16) | i2c->wbuf, + i2c->regs + I2C_TASKADDRESS); + init_waitqueue_head(&i2c->wq); + + adap = &i2c->adap; + i2c_set_adapdata(adap, i2c); +#ifdef I2C_ADAP_CLASS_TV_DIGITAL + adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; +#else +#ifdef I2C_CLASS_TV_ANALOG + adap->class = I2C_CLASS_TV_ANALOG; +#endif +#endif + strcpy(adap->name, "ddbridge"); + adap->algo = &ddb_i2c_algo; + adap->algo_data = (void *)i2c; + adap->dev.parent = &dev->pdev->dev; + stat = i2c_add_adapter(adap); + if (stat) + break; + } + if (stat) + for (j = 0; j < i; j++) { + i2c = &dev->i2c[j]; + adap = &i2c->adap; + i2c_del_adapter(adap); + } + return stat; +} diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.h b/drivers/media/pci/ddbridge/ddbridge-i2c.h new file mode 100644 index 000000000000..e1aa3b74f672 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.h @@ -0,0 +1,99 @@ +/* + * ddbridge.c: Digital Devices PCIe bridge driver + * + * Copyright (C) 2010-2011 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * To obtain the license, point your browser to + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __DDBRIDGE_I2C_H__ +#define __DDBRIDGE_I2C_H__ + +#include + +#include "ddbridge.h" + +/******************************************************************************/ + +void ddb_i2c_release(struct ddb *dev); +int ddb_i2c_init(struct ddb *dev); + +/******************************************************************************/ + +static int __maybe_unused i2c_io(struct i2c_adapter *adapter, u8 adr, + u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) +{ + struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, + .buf = wbuf, .len = wlen }, + { .addr = adr, .flags = I2C_M_RD, + .buf = rbuf, .len = rlen } }; + + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; +} + +static int __maybe_unused i2c_write(struct i2c_adapter *adap, u8 adr, + u8 *data, int len) +{ + struct i2c_msg msg = { .addr = adr, .flags = 0, + .buf = data, .len = len }; + + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; +} + +static int __maybe_unused i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) +{ + struct i2c_msg msgs[1] = { { .addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1 } }; + + return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; +} + +static int __maybe_unused i2c_read_regs(struct i2c_adapter *adapter, + u8 adr, u8 reg, u8 *val, u8 len) +{ + struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, + .buf = ®, .len = 1 }, + { .addr = adr, .flags = I2C_M_RD, + .buf = val, .len = len } }; + + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; +} + +static int __maybe_unused i2c_read_reg(struct i2c_adapter *adapter, u8 adr, + u8 reg, u8 *val) +{ + return i2c_read_regs(adapter, adr, reg, val, 1); +} + +static int __maybe_unused i2c_read_reg16(struct i2c_adapter *adapter, + u8 adr, u16 reg, u8 *val) +{ + u8 msg[2] = { reg >> 8, reg & 0xff }; + struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, + .buf = msg, .len = 2 }, + { .addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1 } }; + + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; +} + +static int __maybe_unused i2c_write_reg(struct i2c_adapter *adap, + u8 adr, u8 reg, u8 val) +{ + u8 msg[2] = { reg, val }; + + return i2c_write(adap, adr, msg, 2); +} + +#endif /* __DDBRIDGE_I2C_H__ */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c new file mode 100644 index 000000000000..41c0adc176b1 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -0,0 +1,389 @@ +/* + * ddbridge.c: Digital Devices PCIe bridge driver + * + * Copyright (C) 2010-2011 Digital Devices GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * To obtain the license, point your browser to + * http://www.gnu.org/copyleft/gpl.html + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddbridge.h" +#include "ddbridge-i2c.h" +#include "ddbridge-regs.h" + +int xo2_speed = 2; +module_param(xo2_speed, int, 0444); +MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); + +int stv0910_single; +module_param(stv0910_single, int, 0444); +MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); + +/******************************************************************************/ + +static void ddb_unmap(struct ddb *dev) +{ + if (dev->regs) + iounmap(dev->regs); + vfree(dev); +} + + +static void ddb_remove(struct pci_dev *pdev) +{ + struct ddb *dev = pci_get_drvdata(pdev); + + ddb_ports_detach(dev); + ddb_i2c_release(dev); + + ddbwritel(0, INTERRUPT_ENABLE); + free_irq(dev->pdev->irq, dev); +#ifdef CONFIG_PCI_MSI + if (dev->msi) + pci_disable_msi(dev->pdev); +#endif + ddb_ports_release(dev); + ddb_buffers_free(dev); + ddb_device_destroy(dev); + + ddb_unmap(dev); + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); +} + + +static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct ddb *dev; + int stat = 0; + int irq_flag = IRQF_SHARED; + + if (pci_enable_device(pdev) < 0) + return -ENODEV; + + dev = vzalloc(sizeof(struct ddb)); + if (dev == NULL) + return -ENOMEM; + + dev->pdev = pdev; + pci_set_drvdata(pdev, dev); + dev->info = (struct ddb_info *) id->driver_data; + dev_info(&pdev->dev, "Detected %s\n", dev->info->name); + + dev->regs = ioremap(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); + if (!dev->regs) { + stat = -ENOMEM; + goto fail; + } + dev_info(&pdev->dev, "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); + +#ifdef CONFIG_PCI_MSI + if (pci_msi_enabled()) + stat = pci_enable_msi(dev->pdev); + if (stat) { + dev_info(&pdev->dev, "MSI not available.\n"); + } else { + irq_flag = 0; + dev->msi = 1; + } +#endif + stat = request_irq(dev->pdev->irq, irq_handler, + irq_flag, "DDBridge", (void *) dev); + if (stat < 0) + goto fail1; + ddbwritel(0, DMA_BASE_WRITE); + ddbwritel(0, DMA_BASE_READ); + ddbwritel(0xffffffff, INTERRUPT_ACK); + ddbwritel(0xfff0f, INTERRUPT_ENABLE); + ddbwritel(0, MSI1_ENABLE); + + /* board control */ + if (dev->info->board_control) { + ddbwritel(0, DDB_LINK_TAG(0) | BOARD_CONTROL); + msleep(100); + ddbwritel(dev->info->board_control_2, + DDB_LINK_TAG(0) | BOARD_CONTROL); + usleep_range(2000, 3000); + ddbwritel(dev->info->board_control_2 + | dev->info->board_control, + DDB_LINK_TAG(0) | BOARD_CONTROL); + usleep_range(2000, 3000); + } + + if (ddb_i2c_init(dev) < 0) + goto fail1; + ddb_ports_init(dev); + if (ddb_buffers_alloc(dev) < 0) { + dev_err(&pdev->dev, "Could not allocate buffer memory\n"); + goto fail2; + } + if (ddb_ports_attach(dev) < 0) + goto fail3; + ddb_device_create(dev); + return 0; + +fail3: + ddb_ports_detach(dev); + dev_err(&pdev->dev, "fail3\n"); + ddb_ports_release(dev); +fail2: + dev_err(&pdev->dev, "fail2\n"); + ddb_buffers_free(dev); +fail1: + dev_err(&pdev->dev, "fail1\n"); + if (dev->msi) + pci_disable_msi(dev->pdev); + if (stat == 0) + free_irq(dev->pdev->irq, dev); +fail: + dev_err(&pdev->dev, "fail\n"); + ddb_unmap(dev); + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + return -1; +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +static const struct ddb_info ddb_none = { + .type = DDB_NONE, + .name = "Digital Devices PCIe bridge", +}; + +static const struct ddb_info ddb_octopus = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus DVB adapter", + .port_num = 4, +}; + +static const struct ddb_info ddb_octopus_le = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus LE DVB adapter", + .port_num = 2, +}; + +static const struct ddb_info ddb_octopus_oem = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus OEM", + .port_num = 4, +}; + +static const struct ddb_info ddb_octopus_mini = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus Mini", + .port_num = 4, +}; + +static const struct ddb_info ddb_v6 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V6 DVB adapter", + .port_num = 3, +}; +static const struct ddb_info ddb_v6_5 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V6.5 DVB adapter", + .port_num = 4, +}; + +static const struct ddb_info ddb_v7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 DVB adapter", + .port_num = 4, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + +static const struct ddb_info ddb_v7a = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", + .port_num = 4, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + +static const struct ddb_info ddb_dvbct = { + .type = DDB_OCTOPUS, + .name = "Digital Devices DVBCT V6.1 DVB adapter", + .port_num = 3, +}; + +static const struct ddb_info ddb_ctv7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine CT V7 DVB adapter", + .port_num = 4, + .board_control = 3, + .board_control_2 = 4, +}; + +static const struct ddb_info ddb_satixS2v3 = { + .type = DDB_OCTOPUS, + .name = "Mystique SaTiX-S2 V3 DVB adapter", + .port_num = 3, +}; + +static const struct ddb_info ddb_octopusv3 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus V3 DVB adapter", + .port_num = 4, +}; + +/*** MaxA8 adapters ***********************************************************/ + +static struct ddb_info ddb_ct2_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 CT2", + .port_num = 4, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, +}; + +static struct ddb_info ddb_c2t2_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2", + .port_num = 4, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, +}; + +static struct ddb_info ddb_isdbt_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 ISDBT", + .port_num = 4, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, +}; + +static struct ddb_info ddb_c2t2i_v0_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2I V0", + .port_num = 4, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, +}; + +static struct ddb_info ddb_c2t2i_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2I", + .port_num = 4, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, +}; + +/******************************************************************************/ + +#define DDVID 0xdd01 /* Digital Devices Vendor ID */ + +#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ + .vendor = _vend, .device = _dev, \ + .subvendor = _subvend, .subdevice = _subdev, \ + .driver_data = (unsigned long)&_driverdata } + +static const struct pci_device_id ddb_id_tbl[] = { + DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), + DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), + DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), + DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), + DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), + DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), + DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), + DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), + DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), + DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a), + DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), + DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), + DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), + DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), + DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8), + DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8), + DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8), + DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8), + DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8), + DDB_ID(DDVID, 0x0006, DDVID, 0x0039, ddb_ctv7), + /* in case sub-ids got deleted in flash */ + DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + {0} +}; +MODULE_DEVICE_TABLE(pci, ddb_id_tbl); + + +static struct pci_driver ddb_pci_driver = { + .name = "DDBridge", + .id_table = ddb_id_tbl, + .probe = ddb_probe, + .remove = ddb_remove, +}; + +static __init int module_init_ddbridge(void) +{ + int ret; + + pr_info("Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n"); + + ret = ddb_class_create(); + if (ret < 0) + return ret; + ret = pci_register_driver(&ddb_pci_driver); + if (ret < 0) + ddb_class_destroy(); + return ret; +} + +static __exit void module_exit_ddbridge(void) +{ + pci_unregister_driver(&ddb_pci_driver); + ddb_class_destroy(); +} + +module_init(module_init_ddbridge); +module_exit(module_exit_ddbridge); + +MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); +MODULE_AUTHOR("Ralph Metzler"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.5"); diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 4783a17175a8..4290a1e28531 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -39,6 +39,9 @@ #include "dvb_net.h" #include "cxd2099.h" +/* MSI had problems with lost interrupts, fixed but needs testing */ +#undef CONFIG_PCI_MSI + #define DDB_MAX_I2C 4 #define DDB_MAX_PORT 4 #define DDB_MAX_INPUT 8 @@ -205,4 +208,36 @@ struct ddb { /****************************************************************************/ +static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) +{ + u32 val = ddbreadl(adr); + + /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ + if (val == ~0) { + dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); + return 0; + } + + return val; +} + +/****************************************************************************/ + +/* ddbridge-main.c (modparams) */ +extern int xo2_speed; +extern int stv0910_single; + +/* ddbridge-core.c */ +void ddb_ports_detach(struct ddb *dev); +void ddb_ports_release(struct ddb *dev); +void ddb_buffers_free(struct ddb *dev); +void ddb_device_destroy(struct ddb *dev); +irqreturn_t irq_handler(int irq, void *dev_id); +void ddb_ports_init(struct ddb *dev); +int ddb_buffers_alloc(struct ddb *dev); +int ddb_ports_attach(struct ddb *dev); +int ddb_device_create(struct ddb *dev); +int ddb_class_create(void); +void ddb_class_destroy(void); + #endif -- cgit v1.2.3 From 22e743898dcd693cf587593781699db2fa888e23 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:52 -0400 Subject: media: ddbridge: bump ddbridge code to version 0.9.29 This huge patch bumps the ddbridge driver to version 0.9.29. Compared to the vendor driver package, DD OctoNET including GTL link support, and all DVB-C Modulator card support has been removed since this requires large changes to the underlying DVB core API, which should eventually be done separately, and, after that, the functionality/device support can be added back rather easy. While the diff is rather large, the bump is mostly a big refactor of all data structures. Yet, the MSI support (message signaled interrupts) is greatly improved, also all currently available CI single/duo bridge cards are fully supported. More changes compared to the upstream driver: - the DDB_USE_WORKER flag/define was removed, kernel worker functionality will be used. - coding style is properly fixed (zero complaints from checkpatch) - all (not much though) CamelCase has been fixed to kernel_case - (private) IOCTLs temporarily removed (which are mainly used to provide rarely-used FPGA update functionality) Great care has been taken to keep all previous changes and fixes (e.g. kernel logging via dev_*(), pointer annotations and such) intact. Permission to reuse and mainline the driver code was formally granted by Ralph Metzler . Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 3289 +++++++++++++++++++++------- drivers/media/pci/ddbridge/ddbridge-i2c.c | 217 +- drivers/media/pci/ddbridge/ddbridge-i2c.h | 41 +- drivers/media/pci/ddbridge/ddbridge-main.c | 490 +++-- drivers/media/pci/ddbridge/ddbridge-regs.h | 138 +- drivers/media/pci/ddbridge/ddbridge.h | 364 ++- 6 files changed, 3376 insertions(+), 1163 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 7e164a370273..6cda798a80a4 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1,7 +1,10 @@ /* - * ddbridge.c: Digital Devices PCIe bridge driver + * ddbridge-core.c: Digital Devices bridge core functions + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Marcus Metzler + * Ralph Metzler * - * Copyright (C) 2010-2011 Digital Devices GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,8 +20,6 @@ * http://www.gnu.org/copyleft/gpl.html */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -49,77 +50,290 @@ #include "stv0910.h" #include "stv6111.h" #include "lnbh25.h" +#include "cxd2099.h" + +/****************************************************************************/ + +#define DDB_MAX_ADAPTER 64 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ +DEFINE_MUTEX(redirect_lock); + +static struct ddb *ddbs[DDB_MAX_ADAPTER]; + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static struct ddb_regset octopus_input = { + .base = 0x200, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_output = { + .base = 0x280, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_idma = { + .base = 0x300, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_idma_buf = { + .base = 0x2000, + .num = 0x08, + .size = 0x100, +}; + +static struct ddb_regset octopus_odma = { + .base = 0x380, + .num = 0x04, + .size = 0x10, +}; + +static struct ddb_regset octopus_odma_buf = { + .base = 0x2800, + .num = 0x04, + .size = 0x100, +}; + +static struct ddb_regset octopus_i2c = { + .base = 0x80, + .num = 0x04, + .size = 0x20, +}; + +static struct ddb_regset octopus_i2c_buf = { + .base = 0x1000, + .num = 0x04, + .size = 0x200, +}; + +/****************************************************************************/ + +struct ddb_regmap octopus_map = { + .irq_base_i2c = 0, + .irq_base_idma = 8, + .irq_base_odma = 16, + .i2c = &octopus_i2c, + .i2c_buf = &octopus_i2c_buf, + .idma = &octopus_idma, + .idma_buf = &octopus_idma_buf, + .odma = &octopus_odma, + .odma_buf = &octopus_odma_buf, + .input = &octopus_input, + .output = &octopus_output, +}; + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ -#if 0 -static void set_table(struct ddb *dev, u32 off, - dma_addr_t *pbuf, u32 num) +static void ddb_set_dma_table(struct ddb_io *io) { - u32 i, base; + struct ddb *dev = io->port->dev; + struct ddb_dma *dma = io->dma; + u32 i; u64 mem; - base = DMA_BASE_ADDRESS_TABLE + off; - for (i = 0; i < num; i++) { - mem = pbuf[i]; - ddbwritel(mem & 0xffffffff, base + i * 8); - ddbwritel(mem >> 32, base + i * 8 + 4); + if (!dma) + return; + for (i = 0; i < dma->num; i++) { + mem = dma->pbuf[i]; + ddbwritel(dev, mem & 0xffffffff, dma->bufregs + i * 8); + ddbwritel(dev, mem >> 32, dma->bufregs + i * 8 + 4); + } + dma->bufval = ((dma->div & 0x0f) << 16) | + ((dma->num & 0x1f) << 11) | + ((dma->size >> 7) & 0x7ff); +} + +static void ddb_set_dma_tables(struct ddb *dev) +{ + u32 i; + + for (i = 0; i < DDB_MAX_PORT; i++) { + if (dev->port[i].input[0]) + ddb_set_dma_table(dev->port[i].input[0]); + if (dev->port[i].input[1]) + ddb_set_dma_table(dev->port[i].input[1]); + if (dev->port[i].output) + ddb_set_dma_table(dev->port[i].output); } } -#endif -static void ddb_address_table(struct ddb *dev) + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static void ddb_redirect_dma(struct ddb *dev, + struct ddb_dma *sdma, + struct ddb_dma *ddma) { - u32 i, j, base; + u32 i, base; u64 mem; - dma_addr_t *pbuf; - - for (i = 0; i < dev->info->port_num * 2; i++) { - base = DMA_BASE_ADDRESS_TABLE + i * 0x100; - pbuf = dev->input[i].pbuf; - for (j = 0; j < dev->input[i].dma_buf_num; j++) { - mem = pbuf[j]; - ddbwritel(mem & 0xffffffff, base + j * 8); - ddbwritel(mem >> 32, base + j * 8 + 4); - } + + sdma->bufval = ddma->bufval; + base = sdma->bufregs; + for (i = 0; i < ddma->num; i++) { + mem = ddma->pbuf[i]; + ddbwritel(dev, mem & 0xffffffff, base + i * 8); + ddbwritel(dev, mem >> 32, base + i * 8 + 4); + } +} + +static int ddb_unredirect(struct ddb_port *port) +{ + struct ddb_input *oredi, *iredi = 0; + struct ddb_output *iredo = 0; + + /* dev_info(port->dev->dev, + * "unredirect %d.%d\n", port->dev->nr, port->nr); + */ + mutex_lock(&redirect_lock); + if (port->output->dma->running) { + mutex_unlock(&redirect_lock); + return -EBUSY; } - for (i = 0; i < dev->info->port_num; i++) { - base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100; - pbuf = dev->output[i].pbuf; - for (j = 0; j < dev->output[i].dma_buf_num; j++) { - mem = pbuf[j]; - ddbwritel(mem & 0xffffffff, base + j * 8); - ddbwritel(mem >> 32, base + j * 8 + 4); + oredi = port->output->redi; + if (!oredi) + goto done; + if (port->input[0]) { + iredi = port->input[0]->redi; + iredo = port->input[0]->redo; + + if (iredo) { + iredo->port->output->redi = oredi; + if (iredo->port->input[0]) { + iredo->port->input[0]->redi = iredi; + ddb_redirect_dma(oredi->port->dev, + oredi->dma, iredo->dma); + } + port->input[0]->redo = 0; + ddb_set_dma_table(port->input[0]); } + oredi->redi = iredi; + port->input[0]->redi = 0; + } + oredi->redo = 0; + port->output->redi = 0; + + ddb_set_dma_table(oredi); +done: + mutex_unlock(&redirect_lock); + return 0; +} + +static int ddb_redirect(u32 i, u32 p) +{ + struct ddb *idev = ddbs[(i >> 4) & 0x3f]; + struct ddb_input *input, *input2; + struct ddb *pdev = ddbs[(p >> 4) & 0x3f]; + struct ddb_port *port; + + if (!idev->has_dma || !pdev->has_dma) + return -EINVAL; + if (!idev || !pdev) + return -EINVAL; + + port = &pdev->port[p & 0x0f]; + if (!port->output) + return -EINVAL; + if (ddb_unredirect(port)) + return -EBUSY; + + if (i == 8) + return 0; + + input = &idev->input[i & 7]; + if (!input) + return -EINVAL; + + mutex_lock(&redirect_lock); + if (port->output->dma->running || input->dma->running) { + mutex_unlock(&redirect_lock); + return -EBUSY; } + input2 = port->input[0]; + if (input2) { + if (input->redi) { + input2->redi = input->redi; + input->redi = 0; + } else + input2->redi = input; + } + input->redo = port->output; + port->output->redi = input; + + ddb_redirect_dma(input->port->dev, input->dma, port->output->dma); + mutex_unlock(&redirect_lock); + return 0; } -static void io_free(struct pci_dev *pdev, u8 **vbuf, - dma_addr_t *pbuf, u32 size, int num) +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) { int i; - for (i = 0; i < num; i++) { - if (vbuf[i]) { - pci_free_consistent(pdev, size, vbuf[i], pbuf[i]); - vbuf[i] = NULL; + if (!dma) + return; + for (i = 0; i < dma->num; i++) { + if (dma->vbuf[i]) { + if (alt_dma) { + dma_unmap_single(&pdev->dev, dma->pbuf[i], + dma->size, + dir ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); + kfree(dma->vbuf[i]); + dma->vbuf[i] = NULL; + } else { + dma_free_coherent(&pdev->dev, dma->size, + dma->vbuf[i], dma->pbuf[i]); + } + + dma->vbuf[i] = NULL; } } } -static int io_alloc(struct pci_dev *pdev, u8 **vbuf, - dma_addr_t *pbuf, u32 size, int num) +static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) { int i; - for (i = 0; i < num; i++) { - vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]); - if (!vbuf[i]) - return -ENOMEM; + if (!dma) + return 0; + for (i = 0; i < dma->num; i++) { + if (alt_dma) { + dma->vbuf[i] = kmalloc(dma->size, __GFP_RETRY_MAYFAIL); + if (!dma->vbuf[i]) + return -ENOMEM; + dma->pbuf[i] = dma_map_single(&pdev->dev, + dma->vbuf[i], + dma->size, + dir ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, dma->pbuf[i])) { + kfree(dma->vbuf[i]); + dma->vbuf[i] = NULL; + return -ENOMEM; + } + } else { + dma->vbuf[i] = dma_alloc_coherent(&pdev->dev, + dma->size, + &dma->pbuf[i], + GFP_KERNEL); + if (!dma->vbuf[i]) + return -ENOMEM; + } } return 0; } @@ -129,38 +343,35 @@ int ddb_buffers_alloc(struct ddb *dev) int i; struct ddb_port *port; - for (i = 0; i < dev->info->port_num; i++) { + for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; switch (port->class) { case DDB_PORT_TUNER: - if (io_alloc(dev->pdev, port->input[0]->vbuf, - port->input[0]->pbuf, - port->input[0]->dma_buf_size, - port->input[0]->dma_buf_num) < 0) - return -1; - if (io_alloc(dev->pdev, port->input[1]->vbuf, - port->input[1]->pbuf, - port->input[1]->dma_buf_size, - port->input[1]->dma_buf_num) < 0) - return -1; + if (port->input[0]->dma) + if (dma_alloc(dev->pdev, port->input[0]->dma, 0) + < 0) + return -1; + if (port->input[1]->dma) + if (dma_alloc(dev->pdev, port->input[1]->dma, 0) + < 0) + return -1; break; case DDB_PORT_CI: - if (io_alloc(dev->pdev, port->input[0]->vbuf, - port->input[0]->pbuf, - port->input[0]->dma_buf_size, - port->input[0]->dma_buf_num) < 0) - return -1; - if (io_alloc(dev->pdev, port->output->vbuf, - port->output->pbuf, - port->output->dma_buf_size, - port->output->dma_buf_num) < 0) - return -1; + case DDB_PORT_LOOP: + if (port->input[0]->dma) + if (dma_alloc(dev->pdev, port->input[0]->dma, 0) + < 0) + return -1; + if (port->output->dma) + if (dma_alloc(dev->pdev, port->output->dma, 1) + < 0) + return -1; break; default: break; } } - ddb_address_table(dev); + ddb_set_dma_tables(dev); return 0; } @@ -169,111 +380,233 @@ void ddb_buffers_free(struct ddb *dev) int i; struct ddb_port *port; - for (i = 0; i < dev->info->port_num; i++) { + for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; - io_free(dev->pdev, port->input[0]->vbuf, - port->input[0]->pbuf, - port->input[0]->dma_buf_size, - port->input[0]->dma_buf_num); - io_free(dev->pdev, port->input[1]->vbuf, - port->input[1]->pbuf, - port->input[1]->dma_buf_size, - port->input[1]->dma_buf_num); - io_free(dev->pdev, port->output->vbuf, - port->output->pbuf, - port->output->dma_buf_size, - port->output->dma_buf_num); + + if (port->input[0] && port->input[0]->dma) + dma_free(dev->pdev, port->input[0]->dma, 0); + if (port->input[1] && port->input[1]->dma) + dma_free(dev->pdev, port->input[1]->dma, 0); + if (port->output && port->output->dma) + dma_free(dev->pdev, port->output->dma, 1); + } +} + +static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) +{ + struct ddb *dev = output->port->dev; + u32 bitrate = output->port->obr, max_bitrate = 72000; + u32 gap = 4, nco = 0; + + *con = 0x1c; + if (output->port->gap != 0xffffffff) { + flags |= 1; + gap = output->port->gap; + } + if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) { + *con = 0x10c; + if (dev->link[0].ids.regmapid >= 0x10003 && !(flags & 1)) { + if (!(flags & 2)) { + /* NCO */ + max_bitrate = 0; + gap = 0; + if (bitrate != 72000) { + if (bitrate >= 96000) + *con |= 0x800; + else { + *con |= 0x1000; + nco = (bitrate * 8192 + 71999) + / 72000; + } + } + } else { + /* Divider and gap */ + *con |= 0x1810; + if (bitrate <= 64000) { + max_bitrate = 64000; + nco = 8; + } else if (bitrate <= 72000) { + max_bitrate = 72000; + nco = 7; + } else { + max_bitrate = 96000; + nco = 5; + } + } + } else { + if (bitrate > 72000) { + *con |= 0x810; /* 96 MBit/s and gap */ + max_bitrate = 96000; + } + } } + if (max_bitrate > 0) { + if (bitrate > max_bitrate) + bitrate = max_bitrate; + if (bitrate < 31000) + bitrate = 31000; + gap = ((max_bitrate - bitrate) * 94) / bitrate; + if (gap < 2) + *con &= ~0x10; /* Disable gap */ + else + gap -= 2; + if (gap > 127) + gap = 127; + } + + *con2 = (nco << 16) | gap; } static void ddb_output_start(struct ddb_output *output) { struct ddb *dev = output->port->dev; + u32 con = 0x11c, con2 = 0; + + if (output->dma) { + spin_lock_irq(&output->dma->lock); + output->dma->cbuf = 0; + output->dma->coff = 0; + output->dma->stat = 0; + ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma)); + } + + if (output->port->input[0]->port->class == DDB_PORT_LOOP) + con = (1UL << 13) | 0x14; + else + calc_con(output, &con, &con2, 0); + + ddbwritel(dev, 0, TS_CONTROL(output)); + ddbwritel(dev, 2, TS_CONTROL(output)); + ddbwritel(dev, 0, TS_CONTROL(output)); + ddbwritel(dev, con, TS_CONTROL(output)); + ddbwritel(dev, con2, TS_CONTROL2(output)); + + if (output->dma) { + ddbwritel(dev, output->dma->bufval, + DMA_BUFFER_SIZE(output->dma)); + ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma)); + ddbwritel(dev, 1, DMA_BASE_READ); + ddbwritel(dev, 7, DMA_BUFFER_CONTROL(output->dma)); + } + + ddbwritel(dev, con | 1, TS_CONTROL(output)); - spin_lock_irq(&output->lock); - output->cbuf = 0; - output->coff = 0; - ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); - ddbwritel(2, TS_OUTPUT_CONTROL(output->nr)); - ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); - ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr)); - ddbwritel((1 << 16) | - (output->dma_buf_num << 11) | - (output->dma_buf_size >> 7), - DMA_BUFFER_SIZE(output->nr + 8)); - ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8)); - - ddbwritel(1, DMA_BASE_READ); - ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8)); - /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */ - ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr)); - output->running = 1; - spin_unlock_irq(&output->lock); + if (output->dma) { + output->dma->running = 1; + spin_unlock_irq(&output->dma->lock); + } } static void ddb_output_stop(struct ddb_output *output) { struct ddb *dev = output->port->dev; - spin_lock_irq(&output->lock); - ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); - ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8)); - output->running = 0; - spin_unlock_irq(&output->lock); + if (output->dma) + spin_lock_irq(&output->dma->lock); + + ddbwritel(dev, 0, TS_CONTROL(output)); + + if (output->dma) { + ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma)); + output->dma->running = 0; + spin_unlock_irq(&output->dma->lock); + } } static void ddb_input_stop(struct ddb_input *input) { struct ddb *dev = input->port->dev; - - spin_lock_irq(&input->lock); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); - input->running = 0; - spin_unlock_irq(&input->lock); + u32 tag = DDB_LINK_TAG(input->port->lnr); + + if (input->dma) + spin_lock_irq(&input->dma->lock); + ddbwritel(dev, 0, tag | TS_CONTROL(input)); + if (input->dma) { + ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma)); + input->dma->running = 0; + spin_unlock_irq(&input->dma->lock); + } } static void ddb_input_start(struct ddb_input *input) { struct ddb *dev = input->port->dev; - spin_lock_irq(&input->lock); - input->cbuf = 0; - input->coff = 0; + if (input->dma) { + spin_lock_irq(&input->dma->lock); + input->dma->cbuf = 0; + input->dma->coff = 0; + input->dma->stat = 0; + ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma)); + } + ddbwritel(dev, 0, TS_CONTROL(input)); + ddbwritel(dev, 2, TS_CONTROL(input)); + ddbwritel(dev, 0, TS_CONTROL(input)); + + if (input->dma) { + ddbwritel(dev, input->dma->bufval, + DMA_BUFFER_SIZE(input->dma)); + ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma)); + ddbwritel(dev, 1, DMA_BASE_WRITE); + ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma)); + } + + ddbwritel(dev, 0x09, TS_CONTROL(input)); + + if (input->dma) { + input->dma->running = 1; + spin_unlock_irq(&input->dma->lock); + } +} + + +static void ddb_input_start_all(struct ddb_input *input) +{ + struct ddb_input *i = input; + struct ddb_output *o; - /* reset */ - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); - ddbwritel(2, TS_INPUT_CONTROL(input->nr)); - ddbwritel(0, TS_INPUT_CONTROL(input->nr)); + mutex_lock(&redirect_lock); + while (i && (o = i->redo)) { + ddb_output_start(o); + i = o->port->input[0]; + if (i) + ddb_input_start(i); + } + ddb_input_start(input); + mutex_unlock(&redirect_lock); +} - ddbwritel((1 << 16) | - (input->dma_buf_num << 11) | - (input->dma_buf_size >> 7), - DMA_BUFFER_SIZE(input->nr)); - ddbwritel(0, DMA_BUFFER_ACK(input->nr)); +static void ddb_input_stop_all(struct ddb_input *input) +{ + struct ddb_input *i = input; + struct ddb_output *o; - ddbwritel(1, DMA_BASE_WRITE); - ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); - ddbwritel(9, TS_INPUT_CONTROL(input->nr)); - input->running = 1; - spin_unlock_irq(&input->lock); + mutex_lock(&redirect_lock); + ddb_input_stop(input); + while (i && (o = i->redo)) { + ddb_output_stop(o); + i = o->port->input[0]; + if (i) + ddb_input_stop(i); + } + mutex_unlock(&redirect_lock); } static u32 ddb_output_free(struct ddb_output *output) { - u32 idx, off, stat = output->stat; + u32 idx, off, stat = output->dma->stat; s32 diff; idx = (stat >> 11) & 0x1f; off = (stat & 0x7ff) << 7; - if (output->cbuf != idx) { - if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && - (output->dma_buf_size - output->coff <= 188)) + if (output->dma->cbuf != idx) { + if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && + (output->dma->size - output->dma->coff <= 188)) return 0; return 188; } - diff = off - output->coff; + diff = off - output->dma->coff; if (diff <= 0 || diff > 188) return 188; return 0; @@ -283,46 +616,51 @@ static ssize_t ddb_output_write(struct ddb_output *output, const __user u8 *buf, size_t count) { struct ddb *dev = output->port->dev; - u32 idx, off, stat = output->stat; + u32 idx, off, stat = output->dma->stat; u32 left = count, len; idx = (stat >> 11) & 0x1f; off = (stat & 0x7ff) << 7; while (left) { - len = output->dma_buf_size - output->coff; - if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && + len = output->dma->size - output->dma->coff; + if ((((output->dma->cbuf + 1) % output->dma->num) == idx) && (off == 0)) { if (len <= 188) break; len -= 188; } - if (output->cbuf == idx) { - if (off > output->coff) { -#if 1 - len = off - output->coff; + if (output->dma->cbuf == idx) { + if (off > output->dma->coff) { + len = off - output->dma->coff; len -= (len % 188); if (len <= 188) - -#endif break; len -= 188; } } if (len > left) len = left; - if (copy_from_user(output->vbuf[output->cbuf] + output->coff, + if (copy_from_user(output->dma->vbuf[output->dma->cbuf] + + output->dma->coff, buf, len)) return -EIO; + if (alt_dma) + dma_sync_single_for_device(dev->dev, + output->dma->pbuf[output->dma->cbuf], + output->dma->size, DMA_TO_DEVICE); left -= len; buf += len; - output->coff += len; - if (output->coff == output->dma_buf_size) { - output->coff = 0; - output->cbuf = ((output->cbuf + 1) % output->dma_buf_num); + output->dma->coff += len; + if (output->dma->coff == output->dma->size) { + output->dma->coff = 0; + output->dma->cbuf = ((output->dma->cbuf + 1) % + output->dma->num); } - ddbwritel((output->cbuf << 11) | (output->coff >> 7), - DMA_BUFFER_ACK(output->nr + 8)); + ddbwritel(dev, + (output->dma->cbuf << 11) | + (output->dma->coff >> 7), + DMA_BUFFER_ACK(output->dma)); } return count - left; } @@ -330,49 +668,57 @@ static ssize_t ddb_output_write(struct ddb_output *output, static u32 ddb_input_avail(struct ddb_input *input) { struct ddb *dev = input->port->dev; - u32 idx, off, stat = input->stat; - u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr)); + u32 idx, off, stat = input->dma->stat; + u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma)); idx = (stat >> 11) & 0x1f; off = (stat & 0x7ff) << 7; if (ctrl & 4) { - dev_err(&dev->pdev->dev, "IA %d %d %08x\n", idx, off, ctrl); - ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr)); + dev_err(dev->dev, "IA %d %d %08x\n", idx, off, ctrl); + ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma)); return 0; } - if (input->cbuf != idx) + if (input->dma->cbuf != idx) return 188; return 0; } -static ssize_t ddb_input_read(struct ddb_input *input, __user u8 *buf, size_t count) +static ssize_t ddb_input_read(struct ddb_input *input, + __user u8 *buf, size_t count) { struct ddb *dev = input->port->dev; u32 left = count; - u32 idx, free, stat = input->stat; + u32 idx, free, stat = input->dma->stat; int ret; idx = (stat >> 11) & 0x1f; while (left) { - if (input->cbuf == idx) + if (input->dma->cbuf == idx) return count - left; - free = input->dma_buf_size - input->coff; + free = input->dma->size - input->dma->coff; if (free > left) free = left; - ret = copy_to_user(buf, input->vbuf[input->cbuf] + - input->coff, free); + if (alt_dma) + dma_sync_single_for_cpu(dev->dev, + input->dma->pbuf[input->dma->cbuf], + input->dma->size, DMA_FROM_DEVICE); + ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] + + input->dma->coff, free); if (ret) return -EFAULT; - input->coff += free; - if (input->coff == input->dma_buf_size) { - input->coff = 0; - input->cbuf = (input->cbuf+1) % input->dma_buf_num; + input->dma->coff += free; + if (input->dma->coff == input->dma->size) { + input->dma->coff = 0; + input->dma->cbuf = (input->dma->cbuf + 1) % + input->dma->num; } left -= free; - ddbwritel((input->cbuf << 11) | (input->coff >> 7), - DMA_BUFFER_ACK(input->nr)); + buf += free; + ddbwritel(dev, + (input->dma->cbuf << 11) | (input->dma->coff >> 7), + DMA_BUFFER_ACK(input->dma)); } return count; } @@ -385,20 +731,24 @@ static ssize_t ts_write(struct file *file, const __user char *buf, { struct dvb_device *dvbdev = file->private_data; struct ddb_output *output = dvbdev->priv; + struct ddb *dev = output->port->dev; size_t left = count; int stat; + if (!dev->has_dma) + return -EINVAL; while (left) { if (ddb_output_free(output) < 188) { if (file->f_flags & O_NONBLOCK) break; if (wait_event_interruptible( - output->wq, ddb_output_free(output) >= 188) < 0) + output->dma->wq, + ddb_output_free(output) >= 188) < 0) break; } stat = ddb_output_write(output, buf, left); if (stat < 0) - break; + return stat; buf += stat; left -= stat; } @@ -411,91 +761,126 @@ static ssize_t ts_read(struct file *file, __user char *buf, struct dvb_device *dvbdev = file->private_data; struct ddb_output *output = dvbdev->priv; struct ddb_input *input = output->port->input[0]; - int left, read; + struct ddb *dev = output->port->dev; + size_t left = count; + int stat; - count -= count % 188; - left = count; + if (!dev->has_dma) + return -EINVAL; while (left) { if (ddb_input_avail(input) < 188) { if (file->f_flags & O_NONBLOCK) break; if (wait_event_interruptible( - input->wq, ddb_input_avail(input) >= 188) < 0) + input->dma->wq, + ddb_input_avail(input) >= 188) < 0) break; } - read = ddb_input_read(input, buf, left); - if (read < 0) - return read; - left -= read; - buf += read; + stat = ddb_input_read(input, buf, left); + if (stat < 0) + return stat; + left -= stat; + buf += stat; } - return (left == count) ? -EAGAIN : (count - left); + return (count && (left == count)) ? -EAGAIN : (count - left); } static unsigned int ts_poll(struct file *file, poll_table *wait) { - /* struct dvb_device *dvbdev = file->private_data; struct ddb_output *output = dvbdev->priv; struct ddb_input *input = output->port->input[0]; - */ + unsigned int mask = 0; -#if 0 - if (data_avail_to_read) + poll_wait(file, &input->dma->wq, wait); + poll_wait(file, &output->dma->wq, wait); + if (ddb_input_avail(input) >= 188) mask |= POLLIN | POLLRDNORM; - if (data_avail_to_write) + if (ddb_output_free(output) >= 188) mask |= POLLOUT | POLLWRNORM; - - poll_wait(file, &read_queue, wait); - poll_wait(file, &write_queue, wait); -#endif return mask; } +static int ts_release(struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + struct ddb_input *input = output->port->input[0]; + + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (!input) + return -EINVAL; + ddb_input_stop(input); + } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + if (!output) + return -EINVAL; + ddb_output_stop(output); + } + return dvb_generic_release(inode, file); +} + +static int ts_open(struct inode *inode, struct file *file) +{ + int err; + struct dvb_device *dvbdev = file->private_data; + struct ddb_output *output = dvbdev->priv; + struct ddb_input *input = output->port->input[0]; + + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (!input) + return -EINVAL; + if (input->redo || input->redi) + return -EBUSY; + } else if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + if (!output) + return -EINVAL; + } else + return -EINVAL; + err = dvb_generic_open(inode, file); + if (err < 0) + return err; + if ((file->f_flags & O_ACCMODE) == O_RDONLY) + ddb_input_start(input); + else if ((file->f_flags & O_ACCMODE) == O_WRONLY) + ddb_output_start(output); + return err; +} + static const struct file_operations ci_fops = { .owner = THIS_MODULE, .read = ts_read, .write = ts_write, - .open = dvb_generic_open, - .release = dvb_generic_release, + .open = ts_open, + .release = ts_release, .poll = ts_poll, + .mmap = 0, }; static struct dvb_device dvbdev_ci = { - .readers = -1, - .writers = -1, - .users = -1, + .priv = 0, + .readers = 1, + .writers = 1, + .users = 2, .fops = &ci_fops, }; -/******************************************************************************/ -/******************************************************************************/ - -#if 0 -static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) -{ - int i; - for (i = 0; i < dev->info->port_num * 2; i++) { - if (dev->input[i].fe == fe) - return &dev->input[i]; - } - return NULL; -} -#endif +/****************************************************************************/ +/****************************************************************************/ -static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) +static int locked_gate_ctrl(struct dvb_frontend *fe, int enable) { struct ddb_input *input = fe->sec_priv; struct ddb_port *port = input->port; + struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; int status; if (enable) { mutex_lock(&port->i2c_gate_lock); - status = input->gate_ctrl(fe, 1); + status = dvb->i2c_gate_ctrl(fe, 1); } else { - status = input->gate_ctrl(fe, 0); + status = dvb->i2c_gate_ctrl(fe, 0); mutex_unlock(&port->i2c_gate_lock); } return status; @@ -504,41 +889,42 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) static int demod_attach_drxk(struct ddb_input *input) { struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct dvb_frontend *fe; struct drxk_config config; - struct device *dev = &input->port->dev->pdev->dev; memset(&config, 0, sizeof(config)); - config.microcode_name = "drxk_a3.mc"; - config.qam_demod_parameter_count = 4; config.adr = 0x29 + (input->nr & 1); + config.microcode_name = "drxk_a3.mc"; - fe = input->fe = dvb_attach(drxk_attach, &config, i2c); - if (!input->fe) { + fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c); + if (!fe) { dev_err(dev, "No DRXK found!\n"); return -ENODEV; } fe->sec_priv = input; - input->gate_ctrl = fe->ops.i2c_gate_ctrl; - fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; + dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; return 0; } static int tuner_attach_tda18271(struct ddb_input *input) { struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct dvb_frontend *fe; - struct device *dev = &input->port->dev->pdev->dev; - if (input->fe->ops.i2c_gate_ctrl) - input->fe->ops.i2c_gate_ctrl(input->fe, 1); - fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); + if (dvb->fe->ops.i2c_gate_ctrl) + dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 1); + fe = dvb_attach(tda18271c2dd_attach, dvb->fe, i2c, 0x60); + if (dvb->fe->ops.i2c_gate_ctrl) + dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 0); if (!fe) { dev_err(dev, "No TDA18271 found!\n"); return -ENODEV; } - if (input->fe->ops.i2c_gate_ctrl) - input->fe->ops.i2c_gate_ctrl(input->fe, 0); return 0; } @@ -567,43 +953,43 @@ static struct stv0367_config ddb_stv0367_config[] = { static int demod_attach_stv0367(struct ddb_input *input) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; + struct dvb_frontend *fe; /* attach frontend */ - input->fe = dvb_attach(stv0367ddb_attach, + fe = dvb->fe = dvb_attach(stv0367ddb_attach, &ddb_stv0367_config[(input->nr & 1)], i2c); - if (!input->fe) { - dev_err(dev, "stv0367ddb_attach failed (not found?)\n"); + if (!dvb->fe) { + dev_err(dev, "No stv0367 found!\n"); return -ENODEV; } - - input->fe->sec_priv = input; - input->gate_ctrl = input->fe->ops.i2c_gate_ctrl; - input->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; - + fe->sec_priv = input; + dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; return 0; } static int tuner_tda18212_ping(struct ddb_input *input, unsigned short adr) { struct i2c_adapter *adapter = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; - + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; u8 tda_id[2]; u8 subaddr = 0x00; dev_dbg(dev, "stv0367-tda18212 tuner ping\n"); - if (input->fe->ops.i2c_gate_ctrl) - input->fe->ops.i2c_gate_ctrl(input->fe, 1); + if (dvb->fe->ops.i2c_gate_ctrl) + dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 1); if (i2c_read_regs(adapter, adr, subaddr, tda_id, sizeof(tda_id)) < 0) dev_dbg(dev, "tda18212 ping 1 fail\n"); if (i2c_read_regs(adapter, adr, subaddr, tda_id, sizeof(tda_id)) < 0) dev_warn(dev, "tda18212 ping failed, expect problems\n"); - if (input->fe->ops.i2c_gate_ctrl) - input->fe->ops.i2c_gate_ctrl(input->fe, 0); + if (dvb->fe->ops.i2c_gate_ctrl) + dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 0); return 0; } @@ -611,7 +997,9 @@ static int tuner_tda18212_ping(struct ddb_input *input, unsigned short adr) static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; + struct dvb_frontend *fe; struct cxd2841er_config cfg; /* the cxd2841er driver expects 8bit/shifted I2C addresses */ @@ -626,27 +1014,26 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24) cfg.flags |= CXD2841ER_TS_SERIAL; /* attach frontend */ - input->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c); + fe = dvb->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c); - if (!input->fe) { - dev_err(dev, "No Sony CXD28xx found!\n"); + if (!dvb->fe) { + dev_err(dev, "No cxd2837/38/43/54 found!\n"); return -ENODEV; } - - input->fe->sec_priv = input; - input->gate_ctrl = input->fe->ops.i2c_gate_ctrl; - input->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; - + fe->sec_priv = input; + dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl; + fe->ops.i2c_gate_ctrl = locked_gate_ctrl; return 0; } static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) { struct i2c_adapter *adapter = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct i2c_client *client; struct tda18212_config config = { - .fe = input->fe, + .fe = dvb->fe, .if_dvbt_6 = 3550, .if_dvbt_7 = 3700, .if_dvbt_8 = 4150, @@ -684,17 +1071,17 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) goto err; } - input->i2c_client[0] = client; + dvb->i2c_client[0] = client; return 0; err: - dev_warn(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); + dev_notice(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); return -ENODEV; } -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ static struct stv090x_config stv0900 = { .device = STV0900, @@ -707,6 +1094,9 @@ static struct stv090x_config stv0900 = { .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts1_tei = 1, + .ts2_tei = 1, + .repeater_level = STV090x_RPTLEVEL_16, .adc1_range = STV090x_ADC_1Vpp, @@ -726,6 +1116,9 @@ static struct stv090x_config stv0900_aa = { .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, + .ts1_tei = 1, + .ts2_tei = 1, + .repeater_level = STV090x_RPTLEVEL_16, .adc1_range = STV090x_ADC_1Vpp, @@ -749,17 +1142,18 @@ static struct stv6110x_config stv6110b = { static int demod_attach_stv0900(struct ddb_input *input, int type) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; - input->fe = dvb_attach(stv090x_attach, feconf, i2c, - (input->nr & 1) ? STV090x_DEMODULATOR_1 - : STV090x_DEMODULATOR_0); - if (!input->fe) { + dvb->fe = dvb_attach(stv090x_attach, feconf, i2c, + (input->nr & 1) ? STV090x_DEMODULATOR_1 + : STV090x_DEMODULATOR_0); + if (!dvb->fe) { dev_err(dev, "No STV0900 found!\n"); return -ENODEV; } - if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0, + if (!dvb_attach(lnbh24_attach, dvb->fe, i2c, 0, 0, (input->nr & 1) ? (0x09 - type) : (0x0b - type))) { dev_err(dev, "No LNBH24 found!\n"); @@ -771,19 +1165,20 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) static int tuner_attach_stv6110(struct ddb_input *input, int type) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; struct stv6110x_config *tunerconf = (input->nr & 1) ? &stv6110b : &stv6110a; const struct stv6110x_devctl *ctl; - ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c); + ctl = dvb_attach(stv6110x_attach, dvb->fe, tunerconf, i2c); if (!ctl) { dev_err(dev, "No STV6110X found!\n"); return -ENODEV; } dev_info(dev, "attach tuner input %d adr %02x\n", - input->nr, tunerconf->addr); + input->nr, tunerconf->addr); feconf->tuner_init = ctl->tuner_init; feconf->tuner_sleep = ctl->tuner_sleep; @@ -815,7 +1210,8 @@ static struct lnbh25_config lnbh25_cfg = { static int demod_attach_stv0910(struct ddb_input *input, int type) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct stv0910_cfg cfg = stv0910_p; struct lnbh25_config lnbcfg = lnbh25_cfg; @@ -824,13 +1220,13 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) if (type) cfg.parallel = 2; - input->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); - if (!input->fe) { + dvb->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); + if (!dvb->fe) { cfg.adr = 0x6c; - input->fe = dvb_attach(stv0910_attach, i2c, - &cfg, (input->nr & 1)); + dvb->fe = dvb_attach(stv0910_attach, i2c, + &cfg, (input->nr & 1)); } - if (!input->fe) { + if (!dvb->fe) { dev_err(dev, "No STV0910 found!\n"); return -ENODEV; } @@ -839,9 +1235,9 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) * i2c addresses */ lnbcfg.i2c_address = (((input->nr & 1) ? 0x0d : 0x0c) << 1); - if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + if (!dvb_attach(lnbh25_attach, dvb->fe, &lnbcfg, i2c)) { lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1); - if (!dvb_attach(lnbh25_attach, input->fe, &lnbcfg, i2c)) { + if (!dvb_attach(lnbh25_attach, dvb->fe, &lnbcfg, i2c)) { dev_err(dev, "No LNBH25 found!\n"); return -ENODEV; } @@ -853,13 +1249,14 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) static int tuner_attach_stv6111(struct ddb_input *input, int type) { struct i2c_adapter *i2c = &input->port->i2c->adap; - struct device *dev = &input->port->dev->pdev->dev; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct device *dev = input->port->dev->dev; struct dvb_frontend *fe; u8 adr = (type ? 0 : 4) + ((input->nr & 1) ? 0x63 : 0x60); - fe = dvb_attach(stv6111_attach, input->fe, i2c, adr); + fe = dvb_attach(stv6111_attach, dvb->fe, i2c, adr); if (!fe) { - fe = dvb_attach(stv6111_attach, input->fe, i2c, adr & ~4); + fe = dvb_attach(stv6111_attach, dvb->fe, i2c, adr & ~4); if (!fe) { dev_err(dev, "No STV6111 found at 0x%02x!\n", adr); return -ENODEV; @@ -868,294 +1265,375 @@ static int tuner_attach_stv6111(struct ddb_input *input, int type) return 0; } -static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, - int (*start_feed)(struct dvb_demux_feed *), - int (*stop_feed)(struct dvb_demux_feed *), - void *priv) -{ - dvbdemux->priv = priv; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = start_feed; - dvbdemux->stop_feed = stop_feed; - dvbdemux->write_to_decoder = NULL; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - return dvb_dmx_init(dvbdemux); -} - -static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, - struct dvb_demux *dvbdemux, - struct dmx_frontend *hw_frontend, - struct dmx_frontend *mem_frontend, - struct dvb_adapter *dvb_adapter) -{ - int ret; - - dmxdev->filternum = 256; - dmxdev->demux = &dvbdemux->dmx; - dmxdev->capabilities = 0; - ret = dvb_dmxdev_init(dmxdev, dvb_adapter); - if (ret < 0) - return ret; - - hw_frontend->source = DMX_FRONTEND_0; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); - mem_frontend->source = DMX_MEMORY_FE; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); - return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); -} - static int start_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct ddb_input *input = dvbdmx->priv; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; - if (!input->users) - ddb_input_start(input); + if (!dvb->users) + ddb_input_start_all(input); - return ++input->users; + return ++dvb->users; } static int stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct ddb_input *input = dvbdmx->priv; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; - if (--input->users) - return input->users; + if (--dvb->users) + return dvb->users; - ddb_input_stop(input); + ddb_input_stop_all(input); return 0; } - static void dvb_input_detach(struct ddb_input *input) { - struct dvb_adapter *adap = &input->adap; - struct dvb_demux *dvbdemux = &input->demux; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct dvb_demux *dvbdemux = &dvb->demux; struct i2c_client *client; - switch (input->attached) { - case 5: - client = input->i2c_client[0]; + switch (dvb->attached) { + case 0x31: + client = dvb->i2c_client[0]; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); } - if (input->fe2) { - dvb_unregister_frontend(input->fe2); - input->fe2 = NULL; - } - if (input->fe) { - dvb_unregister_frontend(input->fe); - dvb_frontend_detach(input->fe); - input->fe = NULL; - } - /* fall-through */ - case 4: - dvb_net_release(&input->dvbnet); - /* fall-through */ - case 3: - dvbdemux->dmx.close(&dvbdemux->dmx); + if (dvb->fe2) + dvb_unregister_frontend(dvb->fe2); + if (dvb->fe) + dvb_unregister_frontend(dvb->fe); + /* fallthrough */ + case 0x30: + if (dvb->fe2) + dvb_frontend_detach(dvb->fe2); + if (dvb->fe) + dvb_frontend_detach(dvb->fe); + dvb->fe = dvb->fe2 = NULL; + /* fallthrough */ + case 0x20: + dvb_net_release(&dvb->dvbnet); + /* fallthrough */ + case 0x12: dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, - &input->hw_frontend); + &dvb->hw_frontend); dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, - &input->mem_frontend); - dvb_dmxdev_release(&input->dmxdev); - /* fall-through */ - case 2: - dvb_dmx_release(&input->demux); - /* fall-through */ - case 1: - dvb_unregister_adapter(adap); + &dvb->mem_frontend); + /* fallthrough */ + case 0x11: + dvb_dmxdev_release(&dvb->dmxdev); + /* fallthrough */ + case 0x10: + dvb_dmx_release(&dvb->demux); + /* fallthrough */ + case 0x01: + break; + } + dvb->attached = 0x00; +} + +static int dvb_register_adapters(struct ddb *dev) +{ + int i, ret = 0; + struct ddb_port *port; + struct dvb_adapter *adap; + + if (adapter_alloc == 3) { + port = &dev->port[0]; + adap = port->dvb[0].adap; + ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, + port->dev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->dvb[0].adap_registered = 1; + for (i = 0; i < dev->port_num; i++) { + port = &dev->port[i]; + port->dvb[0].adap = adap; + port->dvb[1].adap = adap; + } + return 0; + } + + for (i = 0; i < dev->port_num; i++) { + port = &dev->port[i]; + switch (port->class) { + case DDB_PORT_TUNER: + adap = port->dvb[0].adap; + ret = dvb_register_adapter(adap, "DDBridge", + THIS_MODULE, + port->dev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->dvb[0].adap_registered = 1; + + if (adapter_alloc > 0) { + port->dvb[1].adap = port->dvb[0].adap; + break; + } + adap = port->dvb[1].adap; + ret = dvb_register_adapter(adap, "DDBridge", + THIS_MODULE, + port->dev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->dvb[1].adap_registered = 1; + break; + + case DDB_PORT_CI: + case DDB_PORT_LOOP: + adap = port->dvb[0].adap; + ret = dvb_register_adapter(adap, "DDBridge", + THIS_MODULE, + port->dev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->dvb[0].adap_registered = 1; + break; + default: + if (adapter_alloc < 2) + break; + adap = port->dvb[0].adap; + ret = dvb_register_adapter(adap, "DDBridge", + THIS_MODULE, + port->dev->dev, + adapter_nr); + if (ret < 0) + return ret; + port->dvb[0].adap_registered = 1; + break; + } + } + return ret; +} + +static void dvb_unregister_adapters(struct ddb *dev) +{ + int i; + struct ddb_port *port; + struct ddb_dvb *dvb; + + for (i = 0; i < dev->link[0].info->port_num; i++) { + port = &dev->port[i]; + + dvb = &port->dvb[0]; + if (dvb->adap_registered) + dvb_unregister_adapter(dvb->adap); + dvb->adap_registered = 0; + + dvb = &port->dvb[1]; + if (dvb->adap_registered) + dvb_unregister_adapter(dvb->adap); + dvb->adap_registered = 0; } - input->attached = 0; } static int dvb_input_attach(struct ddb_input *input) { - int ret; + int ret = 0; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; struct ddb_port *port = input->port; - struct dvb_adapter *adap = &input->adap; - struct dvb_demux *dvbdemux = &input->demux; - struct device *dev = &input->port->dev->pdev->dev; - int sony_osc24 = 0, sony_tspar = 0; - - ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, - &input->port->dev->pdev->dev, - adapter_nr); - if (ret < 0) { - dev_err(dev, "Could not register adapter. Check if you enabled enough adapters in dvb-core!\n"); + struct dvb_adapter *adap = dvb->adap; + struct dvb_demux *dvbdemux = &dvb->demux; + int par = 0, osc24 = 0; + + dvb->attached = 0x01; + + dvbdemux->priv = input; + dvbdemux->dmx.capabilities = DMX_TS_FILTERING | + DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; + dvbdemux->start_feed = start_feed; + dvbdemux->stop_feed = stop_feed; + dvbdemux->filternum = dvbdemux->feednum = 256; + ret = dvb_dmx_init(dvbdemux); + if (ret < 0) return ret; - } - input->attached = 1; + dvb->attached = 0x10; - ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", - start_feed, - stop_feed, input); + dvb->dmxdev.filternum = 256; + dvb->dmxdev.demux = &dvbdemux->dmx; + ret = dvb_dmxdev_init(&dvb->dmxdev, adap); if (ret < 0) return ret; - input->attached = 2; + dvb->attached = 0x11; - ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux, - &input->hw_frontend, - &input->mem_frontend, adap); + dvb->mem_frontend.source = DMX_MEMORY_FE; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->mem_frontend); + dvb->hw_frontend.source = DMX_FRONTEND_0; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend); + ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend); if (ret < 0) return ret; - input->attached = 3; + dvb->attached = 0x12; - ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux); + ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); if (ret < 0) return ret; - input->attached = 4; + dvb->attached = 0x20; - input->fe = NULL; + dvb->fe = dvb->fe2 = NULL; switch (port->type) { + case DDB_TUNER_MXL5XX: + dev_notice(port->dev->dev, "MaxLinear MxL5xx not supported\n"); + return -ENODEV; case DDB_TUNER_DVBS_ST: if (demod_attach_stv0900(input, 0) < 0) return -ENODEV; if (tuner_attach_stv6110(input, 0) < 0) return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - } break; case DDB_TUNER_DVBS_ST_AA: if (demod_attach_stv0900(input, 1) < 0) return -ENODEV; if (tuner_attach_stv6110(input, 1) < 0) return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - } break; - case DDB_TUNER_XO2_DVBS_STV0910: + case DDB_TUNER_DVBS_STV0910: if (demod_attach_stv0910(input, 0) < 0) return -ENODEV; if (tuner_attach_stv6111(input, 0) < 0) return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - } break; case DDB_TUNER_DVBS_STV0910_PR: if (demod_attach_stv0910(input, 1) < 0) return -ENODEV; if (tuner_attach_stv6111(input, 1) < 0) return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - } break; case DDB_TUNER_DVBS_STV0910_P: if (demod_attach_stv0910(input, 0) < 0) return -ENODEV; if (tuner_attach_stv6111(input, 1) < 0) return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - } break; case DDB_TUNER_DVBCT_TR: if (demod_attach_drxk(input) < 0) return -ENODEV; if (tuner_attach_tda18271(input) < 0) return -ENODEV; - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; - if (input->fe2) { - if (dvb_register_frontend(adap, input->fe2) < 0) - return -ENODEV; - input->fe2->tuner_priv = input->fe->tuner_priv; - memcpy(&input->fe2->ops.tuner_ops, - &input->fe->ops.tuner_ops, - sizeof(struct dvb_tuner_ops)); - } break; case DDB_TUNER_DVBCT_ST: if (demod_attach_stv0367(input) < 0) return -ENODEV; - if (tuner_attach_tda18212(input, port->type) < 0) + if (tuner_attach_tda18212(input, port->type) < 0) { + if (dvb->fe2) + dvb_frontend_detach(dvb->fe2); + if (dvb->fe) + dvb_frontend_detach(dvb->fe); return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; } break; case DDB_TUNER_DVBC2T2I_SONY_P: + if (input->port->dev->link[input->port->lnr].info->ts_quirks & + TS_QUIRK_ALT_OSC) + osc24 = 0; + else + osc24 = 1; case DDB_TUNER_DVBCT2_SONY_P: case DDB_TUNER_DVBC2T2_SONY_P: case DDB_TUNER_ISDBT_SONY_P: - if (port->type == DDB_TUNER_DVBC2T2I_SONY_P) - sony_osc24 = 1; - if (input->port->dev->info->ts_quirks & TS_QUIRK_ALT_OSC) - sony_osc24 = 0; - if (input->port->dev->info->ts_quirks & TS_QUIRK_SERIAL) - sony_tspar = 0; + if (input->port->dev->link[input->port->lnr].info->ts_quirks + & TS_QUIRK_SERIAL) + par = 0; else - sony_tspar = 1; - - if (demod_attach_cxd28xx(input, sony_tspar, sony_osc24) < 0) + par = 1; + if (demod_attach_cxd28xx(input, par, osc24) < 0) return -ENODEV; - if (tuner_attach_tda18212(input, port->type) < 0) + if (tuner_attach_tda18212(input, port->type) < 0) { + if (dvb->fe2) + dvb_frontend_detach(dvb->fe2); + if (dvb->fe) + dvb_frontend_detach(dvb->fe); return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; } break; - case DDB_TUNER_XO2_DVBC2T2I_SONY: - case DDB_TUNER_XO2_DVBCT2_SONY: - case DDB_TUNER_XO2_DVBC2T2_SONY: - case DDB_TUNER_XO2_ISDBT_SONY: - if (port->type == DDB_TUNER_XO2_DVBC2T2I_SONY) - sony_osc24 = 1; - - if (demod_attach_cxd28xx(input, 0, sony_osc24) < 0) + case DDB_TUNER_DVBC2T2I_SONY: + osc24 = 1; + case DDB_TUNER_DVBCT2_SONY: + case DDB_TUNER_DVBC2T2_SONY: + case DDB_TUNER_ISDBT_SONY: + if (demod_attach_cxd28xx(input, 0, osc24) < 0) return -ENODEV; - if (tuner_attach_tda18212(input, port->type) < 0) + if (tuner_attach_tda18212(input, port->type) < 0) { + if (dvb->fe2) + dvb_frontend_detach(dvb->fe2); + if (dvb->fe) + dvb_frontend_detach(dvb->fe); return -ENODEV; - if (input->fe) { - if (dvb_register_frontend(adap, input->fe) < 0) - return -ENODEV; } break; + default: + return 0; } - - input->attached = 5; + dvb->attached = 0x30; + if (dvb->fe) { + if (dvb_register_frontend(adap, dvb->fe) < 0) + return -ENODEV; + } + if (dvb->fe2) { + if (dvb_register_frontend(adap, dvb->fe2) < 0) + return -ENODEV; + dvb->fe2->tuner_priv = dvb->fe->tuner_priv; + memcpy(&dvb->fe2->ops.tuner_ops, + &dvb->fe->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } + dvb->attached = 0x31; return 0; } -static int port_has_ci(struct ddb_port *port) + +static int port_has_encti(struct ddb_port *port) +{ + struct device *dev = port->dev->dev; + u8 val; + int ret = i2c_read_reg(&port->i2c->adap, 0x20, 0, &val); + + if (!ret) + dev_info(dev, "[0x20]=0x%02x\n", val); + return ret ? 0 : 1; +} + +static int port_has_cxd(struct ddb_port *port, u8 *type) { u8 val; - return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; + u8 probe[4] = { 0xe0, 0x00, 0x00, 0x00 }, data[4]; + struct i2c_msg msgs[2] = {{ .addr = 0x40, .flags = 0, + .buf = probe, .len = 4 }, + { .addr = 0x40, .flags = I2C_M_RD, + .buf = data, .len = 4 } }; + val = i2c_transfer(&port->i2c->adap, msgs, 2); + if (val != 2) + return 0; + + if (data[0] == 0x02 && data[1] == 0x2b && data[3] == 0x43) + *type = 2; + else + *type = 1; + return 1; } static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id) { u8 probe[1] = { 0x00 }, data[4]; - *type = DDB_XO2_TYPE_NONE; - if (i2c_io(&port->i2c->adap, 0x10, probe, 1, data, 4)) return 0; if (data[0] == 'D' && data[1] == 'F') { *id = data[2]; - *type = DDB_XO2_TYPE_DUOFLEX; + *type = 1; return 1; } if (data[0] == 'C' && data[1] == 'I') { *id = data[2]; - *type = DDB_XO2_TYPE_CI; + *type = 2; return 1; } return 0; @@ -1164,6 +1642,7 @@ static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id) static int port_has_stv0900(struct ddb_port *port) { u8 val; + if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) return 0; return 1; @@ -1179,6 +1658,7 @@ static int port_has_stv0900_aa(struct ddb_port *port, u8 *id) static int port_has_drxks(struct ddb_port *port) { u8 val; + if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) return 0; if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) @@ -1189,6 +1669,7 @@ static int port_has_drxks(struct ddb_port *port) static int port_has_stv0367(struct ddb_port *port) { u8 val; + if (i2c_read_reg16(&port->i2c->adap, 0x1e, 0xf000, &val) < 0) return 0; if (val != 0x60) @@ -1203,7 +1684,7 @@ static int port_has_stv0367(struct ddb_port *port) static int init_xo2(struct ddb_port *port) { struct i2c_adapter *i2c = &port->i2c->adap; - struct device *dev = &port->dev->pdev->dev; + struct ddb *dev = port->dev; u8 val, data[2]; int res; @@ -1212,7 +1693,7 @@ static int init_xo2(struct ddb_port *port) return res; if (data[0] != 0x01) { - dev_info(dev, "Port %d: invalid XO2\n", port->nr); + dev_info(dev->dev, "Port %d: invalid XO2\n", port->nr); return -1; } @@ -1228,11 +1709,16 @@ static int init_xo2(struct ddb_port *port) i2c_write_reg(i2c, 0x10, 0x08, 0x07); /* speed: 0=55,1=75,2=90,3=104 MBit/s */ - i2c_write_reg(i2c, 0x10, 0x09, - ((xo2_speed >= 0 && xo2_speed <= 3) ? xo2_speed : 2)); + i2c_write_reg(i2c, 0x10, 0x09, xo2_speed); - i2c_write_reg(i2c, 0x10, 0x0a, 0x01); - i2c_write_reg(i2c, 0x10, 0x0b, 0x01); + if (dev->link[port->lnr].info->con_clock) { + dev_info(dev->dev, "Setting continuous clock for XO2\n"); + i2c_write_reg(i2c, 0x10, 0x0a, 0x03); + i2c_write_reg(i2c, 0x10, 0x0b, 0x03); + } else { + i2c_write_reg(i2c, 0x10, 0x0a, 0x01); + i2c_write_reg(i2c, 0x10, 0x0b, 0x01); + } usleep_range(2000, 3000); /* Start XO2 PLL */ @@ -1241,6 +1727,52 @@ static int init_xo2(struct ddb_port *port) return 0; } +static int init_xo2_ci(struct ddb_port *port) +{ + struct i2c_adapter *i2c = &port->i2c->adap; + struct ddb *dev = port->dev; + u8 val, data[2]; + int res; + + res = i2c_read_regs(i2c, 0x10, 0x04, data, 2); + if (res < 0) + return res; + + if (data[0] > 1) { + dev_info(dev->dev, "Port %d: invalid XO2 CI %02x\n", + port->nr, data[0]); + return -1; + } + dev_info(dev->dev, "Port %d: DuoFlex CI %u.%u\n", + port->nr, data[0], data[1]); + + i2c_read_reg(i2c, 0x10, 0x08, &val); + if (val != 0) { + i2c_write_reg(i2c, 0x10, 0x08, 0x00); + msleep(100); + } + /* Enable both CI */ + i2c_write_reg(i2c, 0x10, 0x08, 3); + usleep_range(2000, 3000); + + + /* speed: 0=55,1=75,2=90,3=104 MBit/s */ + i2c_write_reg(i2c, 0x10, 0x09, 1); + + i2c_write_reg(i2c, 0x10, 0x08, 0x83); + usleep_range(2000, 3000); + + if (dev->link[port->lnr].info->con_clock) { + dev_info(dev->dev, "Setting continuous clock for DuoFlex CI\n"); + i2c_write_reg(i2c, 0x10, 0x0a, 0x03); + i2c_write_reg(i2c, 0x10, 0x0b, 0x03); + } else { + i2c_write_reg(i2c, 0x10, 0x0a, 0x01); + i2c_write_reg(i2c, 0x10, 0x0b, 0x01); + } + return 0; +} + static int port_has_cxd28xx(struct ddb_port *port, u8 *id) { struct i2c_adapter *i2c = &port->i2c->adap; @@ -1255,140 +1787,453 @@ static int port_has_cxd28xx(struct ddb_port *port, u8 *id) return 1; } +static char *xo2names[] = { + "DUAL DVB-S2", "DUAL DVB-C/T/T2", + "DUAL DVB-ISDBT", "DUAL DVB-C/C2/T/T2", + "DUAL ATSC", "DUAL DVB-C/C2/T/T2,ISDB-T", + "", "" +}; + +static char *xo2types[] = { + "DVBS_ST", "DVBCT2_SONY", + "ISDBT_SONY", "DVBC2T2_SONY", + "ATSC_ST", "DVBC2T2I_SONY" +}; + static void ddb_port_probe(struct ddb_port *port) { struct ddb *dev = port->dev; - char *modname = "NO MODULE"; - u8 xo2_type, xo2_id, cxd_id, stv_id; + u32 l = port->lnr; + u8 id, type; + port->name = "NO MODULE"; + port->type_name = "NONE"; port->class = DDB_PORT_NONE; - if (port_has_ci(port)) { - modname = "CI"; + /* Handle missing ports and ports without I2C */ + + if (port->nr == ts_loop) { + port->name = "TS LOOP"; + port->class = DDB_PORT_LOOP; + return; + } + + if (port->nr == 1 && dev->link[l].info->type == DDB_OCTOPUS_CI && + dev->link[l].info->i2c_mask == 1) { + port->name = "NO TAB"; + port->class = DDB_PORT_NONE; + return; + } + + if (port->nr > 1 && dev->link[l].info->type == DDB_OCTOPUS_CI) { + port->name = "CI internal"; + port->type_name = "INTERNAL"; port->class = DDB_PORT_CI; - ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); - } else if (port_has_xo2(port, &xo2_type, &xo2_id)) { - dev_dbg(&dev->pdev->dev, "Port %d (TAB %d): XO2 type: %d, id: %d\n", - port->nr, port->nr+1, xo2_type, xo2_id); + port->type = DDB_CI_INTERNAL; + } - ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); + if (!port->i2c) + return; - switch (xo2_type) { - case DDB_XO2_TYPE_DUOFLEX: + /* Probe ports with I2C */ + + if (port_has_cxd(port, &id)) { + if (id == 1) { + port->name = "CI"; + port->type_name = "CXD2099"; + port->class = DDB_PORT_CI; + port->type = DDB_CI_EXTERNAL_SONY; + ddbwritel(dev, I2C_SPEED_400, + port->i2c->regs + I2C_TIMING); + } else { + dev_info(dev->dev, "Port %d: Uninitialized DuoFlex\n", + port->nr); + return; + } + } else if (port_has_xo2(port, &type, &id)) { + ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); + /*dev_info(dev->dev, "XO2 ID %02x\n", id);*/ + if (type == 2) { + port->name = "DuoFlex CI"; + port->class = DDB_PORT_CI; + port->type = DDB_CI_EXTERNAL_XO2; + port->type_name = "CI_XO2"; + init_xo2_ci(port); + return; + } + id >>= 2; + if (id > 5) { + port->name = "unknown XO2 DuoFlex"; + port->type_name = "UNKNOWN"; + } else { + port->name = xo2names[id]; + port->class = DDB_PORT_TUNER; + port->type = DDB_TUNER_XO2 + id; + port->type_name = xo2types[id]; init_xo2(port); - switch (xo2_id >> 2) { - case 0: - modname = "DUAL DVB-S2"; - port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_XO2_DVBS_STV0910; - break; - case 1: - modname = "DUAL DVB-C/T/T2"; - port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_XO2_DVBCT2_SONY; - break; - case 2: - modname = "DUAL DVB-ISDBT"; - port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_XO2_ISDBT_SONY; - break; - case 3: - modname = "DUAL DVB-C/C2/T/T2"; - port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_XO2_DVBC2T2_SONY; - break; - case 4: - modname = "DUAL ATSC (unsupported)"; - port->class = DDB_PORT_NONE; - port->type = DDB_TUNER_XO2_ATSC_ST; - break; - case 5: - modname = "DUAL DVB-C/C2/T/T2/ISDBT"; - port->class = DDB_PORT_TUNER; - port->type = DDB_TUNER_XO2_DVBC2T2I_SONY; - break; - default: - modname = "Unknown XO2 DuoFlex module\n"; - break; - } - break; - case DDB_XO2_TYPE_CI: - dev_info(&dev->pdev->dev, "DuoFlex CI modules not supported\n"); - break; - default: - dev_info(&dev->pdev->dev, "Unknown XO2 DuoFlex module\n"); - break; } - } else if (port_has_cxd28xx(port, &cxd_id)) { - switch (cxd_id) { + } else if (port_has_cxd28xx(port, &id)) { + switch (id) { case 0xa4: - modname = "DUAL DVB-C2T2 CXD2843"; - port->class = DDB_PORT_TUNER; + port->name = "DUAL DVB-C2T2 CXD2843"; port->type = DDB_TUNER_DVBC2T2_SONY_P; + port->type_name = "DVBC2T2_SONY"; break; case 0xb1: - modname = "DUAL DVB-CT2 CXD2837"; - port->class = DDB_PORT_TUNER; + port->name = "DUAL DVB-CT2 CXD2837"; port->type = DDB_TUNER_DVBCT2_SONY_P; + port->type_name = "DVBCT2_SONY"; break; case 0xb0: - modname = "DUAL ISDB-T CXD2838"; - port->class = DDB_PORT_TUNER; + port->name = "DUAL ISDB-T CXD2838"; port->type = DDB_TUNER_ISDBT_SONY_P; + port->type_name = "ISDBT_SONY"; break; case 0xc1: - modname = "DUAL DVB-C2T2 ISDB-T CXD2854"; - port->class = DDB_PORT_TUNER; + port->name = "DUAL DVB-C2T2 ISDB-T CXD2854"; port->type = DDB_TUNER_DVBC2T2I_SONY_P; + port->type_name = "DVBC2T2I_ISDBT_SONY"; break; default: - modname = "Unknown CXD28xx tuner"; - break; + return; } - ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); + port->class = DDB_PORT_TUNER; + ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); } else if (port_has_stv0900(port)) { - modname = "DUAL DVB-S2"; + port->name = "DUAL DVB-S2"; port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBS_ST; - ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); - } else if (port_has_stv0900_aa(port, &stv_id)) { - modname = "DUAL DVB-S2"; + port->type_name = "DVBS_ST"; + ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); + } else if (port_has_stv0900_aa(port, &id)) { + port->name = "DUAL DVB-S2"; port->class = DDB_PORT_TUNER; - switch (stv_id) { - case 0x51: - if (dev->info->ts_quirks & TS_QUIRK_REVERSED && - port->nr == 0) + if (id == 0x51) { + if (port->nr == 0 && + dev->link[l].info->ts_quirks & TS_QUIRK_REVERSED) port->type = DDB_TUNER_DVBS_STV0910_PR; else port->type = DDB_TUNER_DVBS_STV0910_P; - break; - default: + port->type_name = "DVBS_ST_0910"; + } else { port->type = DDB_TUNER_DVBS_ST_AA; - break; + port->type_name = "DVBS_ST_AA"; } - ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); + ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); } else if (port_has_drxks(port)) { - modname = "DUAL DVB-C/T"; + port->name = "DUAL DVB-C/T"; port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBCT_TR; - ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); + port->type_name = "DVBCT_TR"; + ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); } else if (port_has_stv0367(port)) { - modname = "DUAL DVB-C/T"; + port->name = "DUAL DVB-C/T"; port->class = DDB_PORT_TUNER; port->type = DDB_TUNER_DVBCT_ST; - ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); + port->type_name = "DVBCT_ST"; + ddbwritel(dev, I2C_SPEED_100, port->i2c->regs + I2C_TIMING); + } else if (port_has_encti(port)) { + port->name = "ENCTI"; + port->class = DDB_PORT_LOOP; } +} + + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static int wait_ci_ready(struct ddb_ci *ci) +{ + u32 count = 10; + + ndelay(500); + do { + if (ddbreadl(ci->port->dev, + CI_CONTROL(ci->nr)) & CI_READY) + break; + usleep_range(1, 2); + if ((--count) == 0) + return -1; + } while (1); + return 0; +} + +static int read_attribute_mem(struct dvb_ca_en50221 *ca, + int slot, int address) +{ + struct ddb_ci *ci = ca->data; + u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1); + + if (address > CI_BUFFER_SIZE) + return -1; + ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address, + CI_DO_READ_ATTRIBUTES(ci->nr)); + wait_ci_ready(ci); + val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off); + return val; +} + +static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, + int address, u8 value) +{ + struct ddb_ci *ci = ca->data; + + ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, + CI_DO_ATTRIBUTE_RW(ci->nr)); + wait_ci_ready(ci); + return 0; +} + +static int read_cam_control(struct dvb_ca_en50221 *ca, + int slot, u8 address) +{ + u32 count = 100; + struct ddb_ci *ci = ca->data; + u32 res; + + ddbwritel(ci->port->dev, CI_READ_CMD | address, + CI_DO_IO_RW(ci->nr)); + ndelay(500); + do { + res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr)); + if (res & CI_READY) + break; + usleep_range(1, 2); + if ((--count) == 0) + return -1; + } while (1); + return 0xff & res; +} + +static int write_cam_control(struct dvb_ca_en50221 *ca, int slot, + u8 address, u8 value) +{ + struct ddb_ci *ci = ca->data; + + ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address, + CI_DO_IO_RW(ci->nr)); + wait_ci_ready(ci); + return 0; +} - dev_info(&dev->pdev->dev, "Port %d (TAB %d): %s\n", - port->nr, port->nr+1, modname); +static int slot_reset(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + + ddbwritel(ci->port->dev, CI_POWER_ON, + CI_CONTROL(ci->nr)); + msleep(100); + ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM, + CI_CONTROL(ci->nr)); + ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM, + CI_CONTROL(ci->nr)); + udelay(20); + ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON, + CI_CONTROL(ci->nr)); + return 0; +} + +static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + + ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr)); + msleep(300); + return 0; +} + +static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); + + ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE, + CI_CONTROL(ci->nr)); + return 0; +} + +static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) +{ + struct ddb_ci *ci = ca->data; + u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr)); + int stat = 0; + + if (val & CI_CAM_DETECT) + stat |= DVB_CA_EN50221_POLL_CAM_PRESENT; + if (val & CI_CAM_READY) + stat |= DVB_CA_EN50221_POLL_CAM_READY; + return stat; +} + +static struct dvb_ca_en50221 en_templ = { + .read_attribute_mem = read_attribute_mem, + .write_attribute_mem = write_attribute_mem, + .read_cam_control = read_cam_control, + .write_cam_control = write_cam_control, + .slot_reset = slot_reset, + .slot_shutdown = slot_shutdown, + .slot_ts_enable = slot_ts_enable, + .poll_slot_status = poll_slot_status, +}; + +static void ci_attach(struct ddb_port *port) +{ + struct ddb_ci *ci = 0; + + ci = kzalloc(sizeof(*ci), GFP_KERNEL); + if (!ci) + return; + memcpy(&ci->en, &en_templ, sizeof(en_templ)); + ci->en.data = ci; + port->en = &ci->en; + ci->port = port; + ci->nr = port->nr - 2; +} + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static int write_creg(struct ddb_ci *ci, u8 data, u8 mask) +{ + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + + ci->port->creg = (ci->port->creg & ~mask) | data; + return i2c_write_reg(i2c, adr, 0x02, ci->port->creg); +} + +static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca, + int slot, int address) +{ + struct ddb_ci *ci = ca->data; + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + int res; + u8 val; + + res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val); + return res ? res : val; +} + +static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot, + int address, u8 value) +{ + struct ddb_ci *ci = ca->data; + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + + return i2c_write_reg16(i2c, adr, 0x8000 | address, value); +} + +static int read_cam_control_xo2(struct dvb_ca_en50221 *ca, + int slot, u8 address) +{ + struct ddb_ci *ci = ca->data; + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + u8 val; + int res; + + res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val); + return res ? res : val; +} + +static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot, + u8 address, u8 value) +{ + struct ddb_ci *ci = ca->data; + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + + return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value); +} + +static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + + dev_dbg(ci->port->dev->dev, "%s\n", __func__); + write_creg(ci, 0x01, 0x01); + write_creg(ci, 0x04, 0x04); + msleep(20); + write_creg(ci, 0x02, 0x02); + write_creg(ci, 0x00, 0x04); + write_creg(ci, 0x18, 0x18); + return 0; +} + +static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + + dev_dbg(ci->port->dev->dev, "%s\n", __func__); + write_creg(ci, 0x10, 0xff); + write_creg(ci, 0x08, 0x08); + return 0; +} + +static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot) +{ + struct ddb_ci *ci = ca->data; + + dev_info(ci->port->dev->dev, "%s\n", __func__); + write_creg(ci, 0x00, 0x10); + return 0; +} + +static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open) +{ + struct ddb_ci *ci = ca->data; + struct i2c_adapter *i2c = &ci->port->i2c->adap; + u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13; + u8 val = 0; + int stat = 0; + + i2c_read_reg(i2c, adr, 0x01, &val); + + if (val & 2) + stat |= DVB_CA_EN50221_POLL_CAM_PRESENT; + if (val & 1) + stat |= DVB_CA_EN50221_POLL_CAM_READY; + return stat; +} + +static struct dvb_ca_en50221 en_xo2_templ = { + .read_attribute_mem = read_attribute_mem_xo2, + .write_attribute_mem = write_attribute_mem_xo2, + .read_cam_control = read_cam_control_xo2, + .write_cam_control = write_cam_control_xo2, + .slot_reset = slot_reset_xo2, + .slot_shutdown = slot_shutdown_xo2, + .slot_ts_enable = slot_ts_enable_xo2, + .poll_slot_status = poll_slot_status_xo2, +}; + +static void ci_xo2_attach(struct ddb_port *port) +{ + struct ddb_ci *ci; + + ci = kzalloc(sizeof(*ci), GFP_KERNEL); + if (!ci) + return; + memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ)); + ci->en.data = ci; + port->en = &ci->en; + ci->port = port; + ci->nr = port->nr - 2; + ci->port->creg = 0; + write_creg(ci, 0x10, 0xff); + write_creg(ci, 0x08, 0x08); } /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ -static struct cxd2099_cfg cxd_cfg = { - .bitrate = 62000, +struct cxd2099_cfg cxd_cfg = { + .bitrate = 72000, .adr = 0x40, .polarity = 1, .clock_mode = 1, @@ -1397,33 +2242,36 @@ static struct cxd2099_cfg cxd_cfg = { static int ddb_ci_attach(struct ddb_port *port) { - int ret; + switch (port->type) { + case DDB_CI_EXTERNAL_SONY: + cxd_cfg.bitrate = ci_bitrate; + port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); + if (!port->en) + return -ENODEV; + dvb_ca_en50221_init(port->dvb[0].adap, + port->en, 0, 1); + break; - ret = dvb_register_adapter(&port->output->adap, - "DDBridge", - THIS_MODULE, - &port->dev->pdev->dev, - adapter_nr); - if (ret < 0) - return ret; - port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); - if (!port->en) { - dvb_unregister_adapter(&port->output->adap); - return -ENODEV; + case DDB_CI_EXTERNAL_XO2: + case DDB_CI_EXTERNAL_XO2_B: + ci_xo2_attach(port); + if (!port->en) + return -ENODEV; + dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); + break; + + case DDB_CI_INTERNAL: + ci_attach(port); + if (!port->en) + return -ENODEV; + dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); + break; } - ddb_input_start(port->input[0]); - ddb_output_start(port->output); - dvb_ca_en50221_init(&port->output->adap, - port->en, 0, 1); - ret = dvb_register_device(&port->output->adap, &port->output->dev, - &dvbdev_ci, (void *) port->output, - DVB_DEVICE_SEC, 0); - return ret; + return 0; } static int ddb_port_attach(struct ddb_port *port) { - struct device *dev = &port->dev->pdev->dev; int ret = 0; switch (port->class) { @@ -1432,15 +2280,27 @@ static int ddb_port_attach(struct ddb_port *port) if (ret < 0) break; ret = dvb_input_attach(port->input[1]); + if (ret < 0) + break; + port->input[0]->redi = port->input[0]; + port->input[1]->redi = port->input[1]; break; case DDB_PORT_CI: ret = ddb_ci_attach(port); + if (ret < 0) + break; + case DDB_PORT_LOOP: + ret = dvb_register_device(port->dvb[0].adap, + &port->dvb[0].dev, + &dvbdev_ci, (void *) port->output, + DVB_DEVICE_SEC, 0); break; default: break; } if (ret < 0) - dev_err(dev, "port_attach on port %d failed\n", port->nr); + dev_err(port->dev->dev, "port_attach on port %d failed\n", + port->nr); return ret; } @@ -1449,11 +2309,16 @@ int ddb_ports_attach(struct ddb *dev) int i, ret = 0; struct ddb_port *port; - for (i = 0; i < dev->info->port_num; i++) { + if (dev->port_num) { + ret = dvb_register_adapters(dev); + if (ret < 0) { + dev_err(dev->dev, "Registering adapters failed. Check DVB_MAX_ADAPTERS in config.\n"); + return ret; + } + } + for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; ret = ddb_port_attach(port); - if (ret < 0) - break; } return ret; } @@ -1463,132 +2328,346 @@ void ddb_ports_detach(struct ddb *dev) int i; struct ddb_port *port; - for (i = 0; i < dev->info->port_num; i++) { + for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; + switch (port->class) { case DDB_PORT_TUNER: dvb_input_detach(port->input[0]); dvb_input_detach(port->input[1]); break; case DDB_PORT_CI: - dvb_unregister_device(port->output->dev); + case DDB_PORT_LOOP: + if (port->dvb[0].dev) + dvb_unregister_device(port->dvb[0].dev); if (port->en) { - ddb_input_stop(port->input[0]); - ddb_output_stop(port->output); dvb_ca_en50221_release(port->en); kfree(port->en); port->en = NULL; - dvb_unregister_adapter(&port->output->adap); } break; } } + dvb_unregister_adapters(dev); +} + + +/* Copy input DMA pointers to output DMA and ACK. */ + +static void input_write_output(struct ddb_input *input, + struct ddb_output *output) +{ + ddbwritel(output->port->dev, + input->dma->stat, DMA_BUFFER_ACK(output->dma)); + output->dma->cbuf = (input->dma->stat >> 11) & 0x1f; + output->dma->coff = (input->dma->stat & 0x7ff) << 7; } -static void input_tasklet(unsigned long data) +static void output_ack_input(struct ddb_output *output, + struct ddb_input *input) { - struct ddb_input *input = (struct ddb_input *) data; + ddbwritel(input->port->dev, + output->dma->stat, DMA_BUFFER_ACK(input->dma)); +} + +static void input_write_dvb(struct ddb_input *input, + struct ddb_input *input2) +{ + struct ddb_dvb *dvb = &input2->port->dvb[input2->nr & 1]; + struct ddb_dma *dma, *dma2; struct ddb *dev = input->port->dev; + int ack = 1; - spin_lock(&input->lock); - if (!input->running) { - spin_unlock(&input->lock); - return; + dma = dma2 = input->dma; + /* if there also is an output connected, do not ACK. + * input_write_output will ACK. + */ + if (input->redo) { + dma2 = input->redo->dma; + ack = 0; + } + while (dma->cbuf != ((dma->stat >> 11) & 0x1f) + || (4 & dma->ctrl)) { + if (4 & dma->ctrl) { + /* dev_err(dev->dev, "Overflow dma %d\n", dma->nr); */ + ack = 1; + } + if (alt_dma) + dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf], + dma2->size, DMA_FROM_DEVICE); + dvb_dmx_swfilter_packets(&dvb->demux, + dma2->vbuf[dma->cbuf], + dma2->size / 188); + dma->cbuf = (dma->cbuf + 1) % dma2->num; + if (ack) + ddbwritel(dev, (dma->cbuf << 11), + DMA_BUFFER_ACK(dma)); + dma->stat = safe_ddbreadl(dev, DMA_BUFFER_CURRENT(dma)); + dma->ctrl = safe_ddbreadl(dev, DMA_BUFFER_CONTROL(dma)); } - input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); +} - if (input->port->class == DDB_PORT_TUNER) { - if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) - dev_err(&dev->pdev->dev, "Overflow input %d\n", input->nr); - while (input->cbuf != ((input->stat >> 11) & 0x1f) - || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) { - dvb_dmx_swfilter_packets(&input->demux, - input->vbuf[input->cbuf], - input->dma_buf_size / 188); +static void input_work(struct work_struct *work) +{ + struct ddb_dma *dma = container_of(work, struct ddb_dma, work); + struct ddb_input *input = (struct ddb_input *) dma->io; + struct ddb *dev = input->port->dev; + unsigned long flags; - input->cbuf = (input->cbuf + 1) % input->dma_buf_num; - ddbwritel((input->cbuf << 11), - DMA_BUFFER_ACK(input->nr)); - input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); - } + spin_lock_irqsave(&dma->lock, flags); + if (!dma->running) { + spin_unlock_irqrestore(&dma->lock, flags); + return; } - if (input->port->class == DDB_PORT_CI) - wake_up(&input->wq); - spin_unlock(&input->lock); + dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma)); + dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma)); + + if (input->redi) + input_write_dvb(input, input->redi); + if (input->redo) + input_write_output(input, input->redo); + wake_up(&dma->wq); + spin_unlock_irqrestore(&dma->lock, flags); +} + +static void input_handler(unsigned long data) +{ + struct ddb_input *input = (struct ddb_input *) data; + struct ddb_dma *dma = input->dma; + + + /* If there is no input connected, input_tasklet() will + * just copy pointers and ACK. So, there is no need to go + * through the tasklet scheduler. + */ + if (input->redi) + queue_work(ddb_wq, &dma->work); + else + input_work(&dma->work); } -static void output_tasklet(unsigned long data) +static void output_handler(unsigned long data) { struct ddb_output *output = (struct ddb_output *) data; + struct ddb_dma *dma = output->dma; struct ddb *dev = output->port->dev; - spin_lock(&output->lock); - if (!output->running) { - spin_unlock(&output->lock); + spin_lock(&dma->lock); + if (!dma->running) { + spin_unlock(&dma->lock); return; } - output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); - wake_up(&output->wq); - spin_unlock(&output->lock); + dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma)); + dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma)); + if (output->redi) + output_ack_input(output, output->redi); + wake_up(&dma->wq); + spin_unlock(&dma->lock); } /****************************************************************************/ /****************************************************************************/ -static void ddb_input_init(struct ddb_port *port, int nr) +static struct ddb_regmap *io_regmap(struct ddb_io *io, int link) +{ + struct ddb_info *info; + + if (link) + info = io->port->dev->link[io->port->lnr].info; + else + info = io->port->dev->link[0].info; + + if (!info) + return NULL; + + return info->regmap; +} + +static void ddb_dma_init(struct ddb_io *io, int nr, int out) +{ + struct ddb_dma *dma; + struct ddb_regmap *rm = io_regmap(io, 0); + + dma = out ? &io->port->dev->odma[nr] : &io->port->dev->idma[nr]; + io->dma = dma; + dma->io = io; + + spin_lock_init(&dma->lock); + init_waitqueue_head(&dma->wq); + if (out) { + dma->regs = rm->odma->base + rm->odma->size * nr; + dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr; + dma->num = OUTPUT_DMA_BUFS; + dma->size = OUTPUT_DMA_SIZE; + dma->div = OUTPUT_DMA_IRQ_DIV; + } else { + INIT_WORK(&dma->work, input_work); + dma->regs = rm->idma->base + rm->idma->size * nr; + dma->bufregs = rm->idma_buf->base + rm->idma_buf->size * nr; + dma->num = INPUT_DMA_BUFS; + dma->size = INPUT_DMA_SIZE; + dma->div = INPUT_DMA_IRQ_DIV; + } + ddbwritel(io->port->dev, 0, DMA_BUFFER_ACK(dma)); + dev_dbg(io->port->dev->dev, "init link %u, io %u, dma %u, dmaregs %08x bufregs %08x\n", + io->port->lnr, io->nr, nr, dma->regs, dma->bufregs); +} + +static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) { struct ddb *dev = port->dev; - struct ddb_input *input = &dev->input[nr]; + struct ddb_input *input = &dev->input[anr]; + struct ddb_regmap *rm; + port->input[pnr] = input; input->nr = nr; input->port = port; - input->dma_buf_num = INPUT_DMA_BUFS; - input->dma_buf_size = INPUT_DMA_SIZE; - ddbwritel(0, TS_INPUT_CONTROL(nr)); - ddbwritel(2, TS_INPUT_CONTROL(nr)); - ddbwritel(0, TS_INPUT_CONTROL(nr)); - ddbwritel(0, DMA_BUFFER_ACK(nr)); - tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input); - spin_lock_init(&input->lock); - init_waitqueue_head(&input->wq); + rm = io_regmap(input, 1); + input->regs = DDB_LINK_TAG(port->lnr) | + (rm->input->base + rm->input->size * nr); + dev_dbg(dev->dev, "init link %u, input %u, regs %08x\n", + port->lnr, nr, input->regs); + + if (dev->has_dma) { + struct ddb_regmap *rm0 = io_regmap(input, 0); + u32 base = rm0->irq_base_idma; + u32 dma_nr = nr; + + if (port->lnr) + dma_nr += 32 + (port->lnr - 1) * 8; + + dev_dbg(dev->dev, "init link %u, input %u, handler %u\n", + port->lnr, nr, dma_nr + base); + + dev->handler[0][dma_nr + base] = input_handler; + dev->handler_data[0][dma_nr + base] = (unsigned long) input; + ddb_dma_init(input, dma_nr, 0); + } } static void ddb_output_init(struct ddb_port *port, int nr) { struct ddb *dev = port->dev; struct ddb_output *output = &dev->output[nr]; + struct ddb_regmap *rm; + + port->output = output; output->nr = nr; output->port = port; - output->dma_buf_num = OUTPUT_DMA_BUFS; - output->dma_buf_size = OUTPUT_DMA_SIZE; + rm = io_regmap(output, 1); + output->regs = DDB_LINK_TAG(port->lnr) | + (rm->output->base + rm->output->size * nr); + + dev_dbg(dev->dev, "init link %u, output %u, regs %08x\n", + port->lnr, nr, output->regs); - ddbwritel(0, TS_OUTPUT_CONTROL(nr)); - ddbwritel(2, TS_OUTPUT_CONTROL(nr)); - ddbwritel(0, TS_OUTPUT_CONTROL(nr)); - tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output); - init_waitqueue_head(&output->wq); + if (dev->has_dma) { + struct ddb_regmap *rm0 = io_regmap(output, 0); + u32 base = rm0->irq_base_odma; + + dev->handler[0][nr + base] = output_handler; + dev->handler_data[0][nr + base] = (unsigned long) output; + ddb_dma_init(output, nr, 1); + } +} + +static int ddb_port_match_i2c(struct ddb_port *port) +{ + struct ddb *dev = port->dev; + u32 i; + + for (i = 0; i < dev->i2c_num; i++) { + if (dev->i2c[i].link == port->lnr && + dev->i2c[i].nr == port->nr) { + port->i2c = &dev->i2c[i]; + return 1; + } + } + return 0; } void ddb_ports_init(struct ddb *dev) { - int i; + u32 i, l, p; struct ddb_port *port; + struct ddb_info *info; + struct ddb_regmap *rm; + + for (p = l = 0; l < DDB_MAX_LINK; l++) { + info = dev->link[l].info; + if (!info) + continue; + rm = info->regmap; + if (!rm) + continue; + for (i = 0; i < info->port_num; i++, p++) { + port = &dev->port[p]; + port->dev = dev; + port->nr = i; + port->lnr = l; + port->pnr = p; + port->gap = 0xffffffff; + port->obr = ci_bitrate; + mutex_init(&port->i2c_gate_lock); + + ddb_port_match_i2c(port); + ddb_port_probe(port); + + port->dvb[0].adap = &dev->adap[2 * p]; + port->dvb[1].adap = &dev->adap[2 * p + 1]; + + if ((port->class == DDB_PORT_NONE) && i && + dev->port[p - 1].type == DDB_CI_EXTERNAL_XO2) { + port->class = DDB_PORT_CI; + port->type = DDB_CI_EXTERNAL_XO2_B; + port->name = "DuoFlex CI_B"; + port->i2c = dev->port[p - 1].i2c; + } - for (i = 0; i < dev->info->port_num; i++) { - port = &dev->port[i]; - port->dev = dev; - port->nr = i; - port->i2c = &dev->i2c[i]; - port->input[0] = &dev->input[2 * i]; - port->input[1] = &dev->input[2 * i + 1]; - port->output = &dev->output[i]; + dev_info(dev->dev, "Port %u: Link %u, Link Port %u (TAB %u): %s\n", + port->pnr, port->lnr, port->nr, port->nr + 1, + port->name); - mutex_init(&port->i2c_gate_lock); - ddb_port_probe(port); - ddb_input_init(port, 2 * i); - ddb_input_init(port, 2 * i + 1); - ddb_output_init(port, i); + if (port->class == DDB_PORT_CI && + port->type == DDB_CI_EXTERNAL_XO2) { + ddb_input_init(port, 2 * i, 0, 2 * i); + ddb_output_init(port, i); + continue; + } + + if (port->class == DDB_PORT_CI && + port->type == DDB_CI_EXTERNAL_XO2_B) { + ddb_input_init(port, 2 * i - 1, 0, 2 * i - 1); + ddb_output_init(port, i); + continue; + } + + if (port->class == DDB_PORT_NONE) + continue; + + switch (dev->link[l].info->type) { + case DDB_OCTOPUS_CI: + if (i >= 2) { + ddb_input_init(port, 2 + i, 0, 2 + i); + ddb_input_init(port, 4 + i, 1, 4 + i); + ddb_output_init(port, i); + break; + } /* fallthrough */ + case DDB_OCTOPUS: + ddb_input_init(port, 2 * i, 0, 2 * i); + ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); + ddb_output_init(port, i); + break; + case DDB_OCTOPUS_MAX_CT: + ddb_input_init(port, 2 * i, 0, 2 * p); + ddb_input_init(port, 2 * i + 1, 1, 2 * p + 1); + break; + default: + break; + } + } } + dev->port_num = p; } void ddb_ports_release(struct ddb *dev) @@ -1596,12 +2675,14 @@ void ddb_ports_release(struct ddb *dev) int i; struct ddb_port *port; - for (i = 0; i < dev->info->port_num; i++) { + for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; - port->dev = dev; - tasklet_kill(&port->input[0]->tasklet); - tasklet_kill(&port->input[1]->tasklet); - tasklet_kill(&port->output->tasklet); + if (port->input[0] && port->input[0]->dma) + cancel_work_sync(&port->input[0]->dma->work); + if (port->input[1] && port->input[1]->dma) + cancel_work_sync(&port->input[1]->dma->work); + if (port->output && port->output->dma) + cancel_work_sync(&port->output->dma->work); } } @@ -1609,90 +2690,158 @@ void ddb_ports_release(struct ddb *dev) /****************************************************************************/ /****************************************************************************/ -static void irq_handle_i2c(struct ddb *dev, int n) +#define IRQ_HANDLE(_nr) \ + do { if ((s & (1UL << ((_nr) & 0x1f))) && dev->handler[0][_nr]) \ + dev->handler[0][_nr](dev->handler_data[0][_nr]); } \ + while (0) + +static void irq_handle_msg(struct ddb *dev, u32 s) { - struct ddb_i2c *i2c = &dev->i2c[n]; + dev->i2c_irq++; + IRQ_HANDLE(0); + IRQ_HANDLE(1); + IRQ_HANDLE(2); + IRQ_HANDLE(3); +} - i2c->done = 1; - wake_up(&i2c->wq); +static void irq_handle_io(struct ddb *dev, u32 s) +{ + dev->ts_irq++; + if ((s & 0x000000f0)) { + IRQ_HANDLE(4); + IRQ_HANDLE(5); + IRQ_HANDLE(6); + IRQ_HANDLE(7); + } + if ((s & 0x0000ff00)) { + IRQ_HANDLE(8); + IRQ_HANDLE(9); + IRQ_HANDLE(10); + IRQ_HANDLE(11); + IRQ_HANDLE(12); + IRQ_HANDLE(13); + IRQ_HANDLE(14); + IRQ_HANDLE(15); + } + if ((s & 0x00ff0000)) { + IRQ_HANDLE(16); + IRQ_HANDLE(17); + IRQ_HANDLE(18); + IRQ_HANDLE(19); + IRQ_HANDLE(20); + IRQ_HANDLE(21); + IRQ_HANDLE(22); + IRQ_HANDLE(23); + } + if ((s & 0xff000000)) { + IRQ_HANDLE(24); + IRQ_HANDLE(25); + IRQ_HANDLE(26); + IRQ_HANDLE(27); + IRQ_HANDLE(28); + IRQ_HANDLE(29); + IRQ_HANDLE(30); + IRQ_HANDLE(31); + } } -irqreturn_t irq_handler(int irq, void *dev_id) +irqreturn_t ddb_irq_handler0(int irq, void *dev_id) { struct ddb *dev = (struct ddb *) dev_id; - u32 s = ddbreadl(INTERRUPT_STATUS); + u32 s = ddbreadl(dev, INTERRUPT_STATUS); - if (!s) - return IRQ_NONE; + do { + if (s & 0x80000000) + return IRQ_NONE; + if (!(s & 0xfffff00)) + return IRQ_NONE; + ddbwritel(dev, s & 0xfffff00, INTERRUPT_ACK); + irq_handle_io(dev, s); + } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + + return IRQ_HANDLED; +} + +irqreturn_t ddb_irq_handler1(int irq, void *dev_id) +{ + struct ddb *dev = (struct ddb *) dev_id; + u32 s = ddbreadl(dev, INTERRUPT_STATUS); do { - ddbwritel(s, INTERRUPT_ACK); - - if (s & 0x00000001) - irq_handle_i2c(dev, 0); - if (s & 0x00000002) - irq_handle_i2c(dev, 1); - if (s & 0x00000004) - irq_handle_i2c(dev, 2); - if (s & 0x00000008) - irq_handle_i2c(dev, 3); - - if (s & 0x00000100) - tasklet_schedule(&dev->input[0].tasklet); - if (s & 0x00000200) - tasklet_schedule(&dev->input[1].tasklet); - if (s & 0x00000400) - tasklet_schedule(&dev->input[2].tasklet); - if (s & 0x00000800) - tasklet_schedule(&dev->input[3].tasklet); - if (s & 0x00001000) - tasklet_schedule(&dev->input[4].tasklet); - if (s & 0x00002000) - tasklet_schedule(&dev->input[5].tasklet); - if (s & 0x00004000) - tasklet_schedule(&dev->input[6].tasklet); - if (s & 0x00008000) - tasklet_schedule(&dev->input[7].tasklet); - - if (s & 0x00010000) - tasklet_schedule(&dev->output[0].tasklet); - if (s & 0x00020000) - tasklet_schedule(&dev->output[1].tasklet); - if (s & 0x00040000) - tasklet_schedule(&dev->output[2].tasklet); - if (s & 0x00080000) - tasklet_schedule(&dev->output[3].tasklet); - - /* if (s & 0x000f0000) printk(KERN_DEBUG "%08x\n", istat); */ - } while ((s = ddbreadl(INTERRUPT_STATUS))); + if (s & 0x80000000) + return IRQ_NONE; + if (!(s & 0x0000f)) + return IRQ_NONE; + ddbwritel(dev, s & 0x0000f, INTERRUPT_ACK); + irq_handle_msg(dev, s); + } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); return IRQ_HANDLED; } -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ +irqreturn_t ddb_irq_handler(int irq, void *dev_id) +{ + struct ddb *dev = (struct ddb *) dev_id; + u32 s = ddbreadl(dev, INTERRUPT_STATUS); + int ret = IRQ_HANDLED; + + if (!s) + return IRQ_NONE; + do { + if (s & 0x80000000) + return IRQ_NONE; + ddbwritel(dev, s, INTERRUPT_ACK); + + if (s & 0x0000000f) + irq_handle_msg(dev, s); + if (s & 0x0fffff00) + irq_handle_io(dev, s); + } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); + + return ret; +} + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ -static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) +static int reg_wait(struct ddb *dev, u32 reg, u32 bit) +{ + u32 count = 0; + + while (safe_ddbreadl(dev, reg) & bit) { + ndelay(10); + if (++count == 100) + return -1; + } + return 0; +} + +static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf, + u32 rlen) { u32 data, shift; + u32 tag = DDB_LINK_TAG(lnr); + struct ddb_link *link = &dev->link[lnr]; + mutex_lock(&link->flash_mutex); if (wlen > 4) - ddbwritel(1, SPI_CONTROL); + ddbwritel(dev, 1, tag | SPI_CONTROL); while (wlen > 4) { /* FIXME: check for big-endian */ - data = swab32(*(u32 *)wbuf); + data = swab32(*(u32 *) wbuf); wbuf += 4; wlen -= 4; - ddbwritel(data, SPI_DATA); - while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) - ; + ddbwritel(dev, data, tag | SPI_DATA); + if (reg_wait(dev, tag | SPI_CONTROL, 4)) + goto fail; } - if (rlen) - ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); + ddbwritel(dev, 0x0001 | ((wlen << (8 + 3)) & 0x1f00), + tag | SPI_CONTROL); else - ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); + ddbwritel(dev, 0x0003 | ((wlen << (8 + 3)) & 0x1f00), + tag | SPI_CONTROL); data = 0; shift = ((4 - wlen) * 8); @@ -1704,33 +2853,34 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) } if (shift) data <<= shift; - ddbwritel(data, SPI_DATA); - while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) - ; + ddbwritel(dev, data, tag | SPI_DATA); + if (reg_wait(dev, tag | SPI_CONTROL, 4)) + goto fail; if (!rlen) { - ddbwritel(0, SPI_CONTROL); - return 0; + ddbwritel(dev, 0, tag | SPI_CONTROL); + goto exit; } if (rlen > 4) - ddbwritel(1, SPI_CONTROL); + ddbwritel(dev, 1, tag | SPI_CONTROL); while (rlen > 4) { - ddbwritel(0xffffffff, SPI_DATA); - while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) - ; - data = ddbreadl(SPI_DATA); + ddbwritel(dev, 0xffffffff, tag | SPI_DATA); + if (reg_wait(dev, tag | SPI_CONTROL, 4)) + goto fail; + data = ddbreadl(dev, tag | SPI_DATA); *(u32 *) rbuf = swab32(data); rbuf += 4; rlen -= 4; } - ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); - ddbwritel(0xffffffff, SPI_DATA); - while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004) - ; + ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00), + tag | SPI_CONTROL); + ddbwritel(dev, 0xffffffff, tag | SPI_DATA); + if (reg_wait(dev, tag | SPI_CONTROL, 4)) + goto fail; - data = ddbreadl(SPI_DATA); - ddbwritel(0, SPI_CONTROL); + data = ddbreadl(dev, tag | SPI_DATA); + ddbwritel(dev, 0, tag | SPI_CONTROL); if (rlen < 4) data <<= ((4 - rlen) * 8); @@ -1741,31 +2891,47 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) rbuf++; rlen--; } +exit: + mutex_unlock(&link->flash_mutex); return 0; +fail: + mutex_unlock(&link->flash_mutex); + return -1; } -#define DDB_MAGIC 'd' +int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len) +{ + u8 cmd[4] = {0x03, (addr >> 16) & 0xff, + (addr >> 8) & 0xff, addr & 0xff}; -struct ddb_flashio { - __user __u8 *write_buf; - __u32 write_len; - __user __u8 *read_buf; - __u32 read_len; -}; + return flashio(dev, link, cmd, 4, buf, len); +} -#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) +/* + * TODO/FIXME: add/implement IOCTLs from upstream driver + */ #define DDB_NAME "ddbridge" static u32 ddb_num; -static struct ddb *ddbs[32]; -static struct class *ddb_class; static int ddb_major; +static DEFINE_MUTEX(ddb_mutex); + +static int ddb_release(struct inode *inode, struct file *file) +{ + struct ddb *dev = file->private_data; + + dev->ddb_dev_users--; + return 0; +} static int ddb_open(struct inode *inode, struct file *file) { struct ddb *dev = ddbs[iminor(inode)]; + if (dev->ddb_dev_users) + return -EBUSY; + dev->ddb_dev_users++; file->private_data = dev; return 0; } @@ -1773,90 +2939,685 @@ static int ddb_open(struct inode *inode, struct file *file) static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ddb *dev = file->private_data; - __user void *parg = (__user void *)arg; - int res; - switch (cmd) { - case IOCTL_DDB_FLASHIO: - { - struct ddb_flashio fio; - u8 *rbuf, *wbuf; + dev_warn(dev->dev, "DDB IOCTLs unsupported (cmd: %d, arg: %lu)\n", + cmd, arg); - if (copy_from_user(&fio, parg, sizeof(fio))) - return -EFAULT; + return -ENOTTY; +} - if (fio.write_len > 1028 || fio.read_len > 1028) - return -EINVAL; - if (fio.write_len + fio.read_len > 1028) - return -EINVAL; +static const struct file_operations ddb_fops = { + .unlocked_ioctl = ddb_ioctl, + .open = ddb_open, + .release = ddb_release, +}; + +static char *ddb_devnode(struct device *device, umode_t *mode) +{ + struct ddb *dev = dev_get_drvdata(device); - wbuf = &dev->iobuf[0]; - rbuf = wbuf + fio.write_len; + return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); +} - if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) - return -EFAULT; - res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len); - if (res) - return res; - if (copy_to_user(fio.read_buf, rbuf, fio.read_len)) - return -EFAULT; +#define __ATTR_MRO(_name, _show) { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = _show, \ +} + +#define __ATTR_MWO(_name, _store) { \ + .attr = { .name = __stringify(_name), .mode = 0222 }, \ + .store = _store, \ +} + +static ssize_t ports_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%d\n", dev->port_num); +} + +static ssize_t ts_irq_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%d\n", dev->ts_irq); +} + +static ssize_t i2c_irq_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%d\n", dev->i2c_irq); +} + +static ssize_t fan_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + u32 val; + + val = ddbreadl(dev, GPIO_OUTPUT) & 1; + return sprintf(buf, "%d\n", val); +} + +static ssize_t fan_store(struct device *device, struct device_attribute *d, + const char *buf, size_t count) +{ + struct ddb *dev = dev_get_drvdata(device); + u32 val; + + if (sscanf(buf, "%u\n", &val) != 1) + return -EINVAL; + ddbwritel(dev, 1, GPIO_DIRECTION); + ddbwritel(dev, val & 1, GPIO_OUTPUT); + return count; +} + +static ssize_t fanspeed_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[8] - 0x30; + struct ddb_link *link = &dev->link[num]; + u32 spd; + + spd = ddblreadl(link, TEMPMON_FANCONTROL) & 0xff; + return sprintf(buf, "%u\n", spd * 100); +} + +static ssize_t temp_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + struct ddb_link *link = &dev->link[0]; + struct i2c_adapter *adap; + int temp, temp2; + u8 tmp[2]; + + if (!link->info->temp_num) + return sprintf(buf, "no sensor\n"); + adap = &dev->i2c[link->info->temp_bus].adap; + if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0) + return sprintf(buf, "read_error\n"); + temp = (tmp[0] << 3) | (tmp[1] >> 5); + temp *= 125; + if (link->info->temp_num == 2) { + if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0) + return sprintf(buf, "read_error\n"); + temp2 = (tmp[0] << 3) | (tmp[1] >> 5); + temp2 *= 125; + return sprintf(buf, "%d %d\n", temp, temp2); + } + return sprintf(buf, "%d\n", temp); +} + +static ssize_t ctemp_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + struct i2c_adapter *adap; + int temp; + u8 tmp[2]; + int num = attr->attr.name[4] - 0x30; + + adap = &dev->i2c[num].adap; + if (!adap) + return 0; + if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0) + if (i2c_read_regs(adap, 0x4d, 0, tmp, 2) < 0) + return sprintf(buf, "no sensor\n"); + temp = tmp[0] * 1000; + return sprintf(buf, "%d\n", temp); +} + +static ssize_t led_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[3] - 0x30; + + return sprintf(buf, "%d\n", dev->leds & (1 << num) ? 1 : 0); +} + + +static void ddb_set_led(struct ddb *dev, int num, int val) +{ + if (!dev->link[0].info->led_num) + return; + switch (dev->port[num].class) { + case DDB_PORT_TUNER: + switch (dev->port[num].type) { + case DDB_TUNER_DVBS_ST: + i2c_write_reg16(&dev->i2c[num].adap, + 0x69, 0xf14c, val ? 2 : 0); + break; + case DDB_TUNER_DVBCT_ST: + i2c_write_reg16(&dev->i2c[num].adap, + 0x1f, 0xf00e, 0); + i2c_write_reg16(&dev->i2c[num].adap, + 0x1f, 0xf00f, val ? 1 : 0); + break; + case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2I_SONY: + { + u8 v; + + i2c_read_reg(&dev->i2c[num].adap, 0x10, 0x08, &v); + v = (v & ~0x10) | (val ? 0x10 : 0); + i2c_write_reg(&dev->i2c[num].adap, 0x10, 0x08, v); + break; + } + default: + break; + } break; } - default: - return -ENOTTY; +} + +static ssize_t led_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[3] - 0x30; + u32 val; + + if (sscanf(buf, "%u\n", &val) != 1) + return -EINVAL; + if (val) + dev->leds |= (1 << num); + else + dev->leds &= ~(1 << num); + ddb_set_led(dev, num, val); + return count; +} + +static ssize_t snr_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + char snr[32]; + int num = attr->attr.name[3] - 0x30; + + if (dev->port[num].type >= DDB_TUNER_XO2) { + if (i2c_read_regs(&dev->i2c[num].adap, 0x10, 0x10, snr, 16) < 0) + return sprintf(buf, "NO SNR\n"); + snr[16] = 0; + } else { + /* serial number at 0x100-0x11f */ + if (i2c_read_regs16(&dev->i2c[num].adap, + 0x57, 0x100, snr, 32) < 0) + if (i2c_read_regs16(&dev->i2c[num].adap, + 0x50, 0x100, snr, 32) < 0) + return sprintf(buf, "NO SNR\n"); + snr[31] = 0; /* in case it is not terminated on EEPROM */ } + return sprintf(buf, "%s\n", snr); +} + + +static ssize_t snr_store(struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[3] - 0x30; + u8 snr[34] = { 0x01, 0x00 }; + + return 0; /* NOE: remove completely? */ + if (count > 31) + return -EINVAL; + if (dev->port[num].type >= DDB_TUNER_XO2) + return -EINVAL; + memcpy(snr + 2, buf, count); + i2c_write(&dev->i2c[num].adap, 0x57, snr, 34); + i2c_write(&dev->i2c[num].adap, 0x50, snr, 34); + return count; +} + +static ssize_t bsnr_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + char snr[16]; + + ddbridge_flashread(dev, 0, snr, 0x10, 15); + snr[15] = 0; /* in case it is not terminated on EEPROM */ + return sprintf(buf, "%s\n", snr); +} + +static ssize_t bpsnr_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + char snr[32]; + + if (!dev->i2c_num) + return 0; + + if (i2c_read_regs16(&dev->i2c[0].adap, + 0x50, 0x0000, snr, 32) < 0 || + snr[0] == 0xff) + return sprintf(buf, "NO SNR\n"); + snr[31] = 0; /* in case it is not terminated on EEPROM */ + return sprintf(buf, "%s\n", snr); +} + +static ssize_t redirect_show(struct device *device, + struct device_attribute *attr, char *buf) +{ return 0; } -static const struct file_operations ddb_fops = { - .unlocked_ioctl = ddb_ioctl, - .open = ddb_open, -}; +static ssize_t redirect_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int i, p; + int res; -static char *ddb_devnode(struct device *device, umode_t *mode) + if (sscanf(buf, "%x %x\n", &i, &p) != 2) + return -EINVAL; + res = ddb_redirect(i, p); + if (res < 0) + return res; + dev_info(device, "redirect: %02x, %02x\n", i, p); + return count; +} + +static ssize_t gap_show(struct device *device, + struct device_attribute *attr, char *buf) { struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[3] - 0x30; - return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); + return sprintf(buf, "%d\n", dev->port[num].gap); + +} + +static ssize_t gap_store(struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[3] - 0x30; + unsigned int val; + + if (sscanf(buf, "%u\n", &val) != 1) + return -EINVAL; + if (val > 20) + return -EINVAL; + dev->port[num].gap = val; + return count; +} + +static ssize_t version_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%08x %08x\n", + dev->link[0].ids.hwid, dev->link[0].ids.regmapid); } +static ssize_t hwid_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "0x%08X\n", dev->link[0].ids.hwid); +} + +static ssize_t regmap_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "0x%08X\n", dev->link[0].ids.regmapid); +} + +static ssize_t devid_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + int num = attr->attr.name[5] - 0x30; + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%08x\n", dev->link[num].ids.devid); +} + +static struct device_attribute ddb_attrs[] = { + __ATTR_RO(version), + __ATTR_RO(ports), + __ATTR_RO(ts_irq), + __ATTR_RO(i2c_irq), + __ATTR(gap0, 0664, gap_show, gap_store), + __ATTR(gap1, 0664, gap_show, gap_store), + __ATTR(gap2, 0664, gap_show, gap_store), + __ATTR(gap3, 0664, gap_show, gap_store), + __ATTR_MRO(devid0, devid_show), + __ATTR_MRO(devid1, devid_show), + __ATTR_MRO(devid2, devid_show), + __ATTR_MRO(devid3, devid_show), + __ATTR_RO(hwid), + __ATTR_RO(regmap), + __ATTR(redirect, 0664, redirect_show, redirect_store), + __ATTR_MRO(snr, bsnr_show), + __ATTR_RO(bpsnr), + __ATTR_NULL, +}; + +static struct device_attribute ddb_attrs_temp[] = { + __ATTR_RO(temp), +}; + +static struct device_attribute ddb_attrs_fan[] = { + __ATTR(fan, 0664, fan_show, fan_store), +}; + +static struct device_attribute ddb_attrs_snr[] = { + __ATTR(snr0, 0664, snr_show, snr_store), + __ATTR(snr1, 0664, snr_show, snr_store), + __ATTR(snr2, 0664, snr_show, snr_store), + __ATTR(snr3, 0664, snr_show, snr_store), +}; + +static struct device_attribute ddb_attrs_ctemp[] = { + __ATTR_MRO(temp0, ctemp_show), + __ATTR_MRO(temp1, ctemp_show), + __ATTR_MRO(temp2, ctemp_show), + __ATTR_MRO(temp3, ctemp_show), +}; + +static struct device_attribute ddb_attrs_led[] = { + __ATTR(led0, 0664, led_show, led_store), + __ATTR(led1, 0664, led_show, led_store), + __ATTR(led2, 0664, led_show, led_store), + __ATTR(led3, 0664, led_show, led_store), +}; + +static struct device_attribute ddb_attrs_fanspeed[] = { + __ATTR_MRO(fanspeed0, fanspeed_show), + __ATTR_MRO(fanspeed1, fanspeed_show), + __ATTR_MRO(fanspeed2, fanspeed_show), + __ATTR_MRO(fanspeed3, fanspeed_show), +}; + +static struct class ddb_class = { + .name = "ddbridge", + .owner = THIS_MODULE, + .devnode = ddb_devnode, +}; + int ddb_class_create(void) { ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); if (ddb_major < 0) return ddb_major; - - ddb_class = class_create(THIS_MODULE, DDB_NAME); - if (IS_ERR(ddb_class)) { - unregister_chrdev(ddb_major, DDB_NAME); - return PTR_ERR(ddb_class); - } - ddb_class->devnode = ddb_devnode; + if (class_register(&ddb_class) < 0) + return -1; return 0; } void ddb_class_destroy(void) { - class_destroy(ddb_class); + class_unregister(&ddb_class); unregister_chrdev(ddb_major, DDB_NAME); } +static void ddb_device_attrs_del(struct ddb *dev) +{ + int i; + + for (i = 0; i < 4; i++) + if (dev->link[i].info && dev->link[i].info->tempmon_irq) + device_remove_file(dev->ddb_dev, + &ddb_attrs_fanspeed[i]); + for (i = 0; i < dev->link[0].info->temp_num; i++) + device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]); + for (i = 0; i < dev->link[0].info->fan_num; i++) + device_remove_file(dev->ddb_dev, &ddb_attrs_fan[i]); + for (i = 0; i < dev->i2c_num && i < 4; i++) { + if (dev->link[0].info->led_num) + device_remove_file(dev->ddb_dev, &ddb_attrs_led[i]); + device_remove_file(dev->ddb_dev, &ddb_attrs_snr[i]); + device_remove_file(dev->ddb_dev, &ddb_attrs_ctemp[i]); + } + for (i = 0; ddb_attrs[i].attr.name != NULL; i++) + device_remove_file(dev->ddb_dev, &ddb_attrs[i]); +} + +static int ddb_device_attrs_add(struct ddb *dev) +{ + int i; + + for (i = 0; ddb_attrs[i].attr.name != NULL; i++) + if (device_create_file(dev->ddb_dev, &ddb_attrs[i])) + goto fail; + for (i = 0; i < dev->link[0].info->temp_num; i++) + if (device_create_file(dev->ddb_dev, &ddb_attrs_temp[i])) + goto fail; + for (i = 0; i < dev->link[0].info->fan_num; i++) + if (device_create_file(dev->ddb_dev, &ddb_attrs_fan[i])) + goto fail; + for (i = 0; (i < dev->i2c_num) && (i < 4); i++) { + if (device_create_file(dev->ddb_dev, &ddb_attrs_snr[i])) + goto fail; + if (device_create_file(dev->ddb_dev, &ddb_attrs_ctemp[i])) + goto fail; + if (dev->link[0].info->led_num) + if (device_create_file(dev->ddb_dev, + &ddb_attrs_led[i])) + goto fail; + } + for (i = 0; i < 4; i++) + if (dev->link[i].info && dev->link[i].info->tempmon_irq) + if (device_create_file(dev->ddb_dev, + &ddb_attrs_fanspeed[i])) + goto fail; + return 0; +fail: + return -1; +} + int ddb_device_create(struct ddb *dev) { - dev->nr = ddb_num++; - dev->ddb_dev = device_create(ddb_class, NULL, + int res = 0; + + if (ddb_num == DDB_MAX_ADAPTER) + return -ENOMEM; + mutex_lock(&ddb_mutex); + dev->nr = ddb_num; + ddbs[dev->nr] = dev; + dev->ddb_dev = device_create(&ddb_class, dev->dev, MKDEV(ddb_major, dev->nr), dev, "ddbridge%d", dev->nr); - ddbs[dev->nr] = dev; - if (IS_ERR(dev->ddb_dev)) - return -1; - return 0; + if (IS_ERR(dev->ddb_dev)) { + res = PTR_ERR(dev->ddb_dev); + dev_info(dev->dev, "Could not create ddbridge%d\n", dev->nr); + goto fail; + } + res = ddb_device_attrs_add(dev); + if (res) { + ddb_device_attrs_del(dev); + device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); + ddbs[dev->nr] = 0; + dev->ddb_dev = ERR_PTR(-ENODEV); + } else + ddb_num++; +fail: + mutex_unlock(&ddb_mutex); + return res; } void ddb_device_destroy(struct ddb *dev) { - ddb_num--; if (IS_ERR(dev->ddb_dev)) return; - device_destroy(ddb_class, MKDEV(ddb_major, 0)); + ddb_device_attrs_del(dev); + device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); +} + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static void tempmon_setfan(struct ddb_link *link) +{ + u32 temp, temp2, pwm; + + if ((ddblreadl(link, TEMPMON_CONTROL) & + TEMPMON_CONTROL_OVERTEMP) != 0) { + dev_info(link->dev->dev, "Over temperature condition\n"); + link->overtemperature_error = 1; + } + temp = (ddblreadl(link, TEMPMON_SENSOR0) >> 8) & 0xFF; + if (temp & 0x80) + temp = 0; + temp2 = (ddblreadl(link, TEMPMON_SENSOR1) >> 8) & 0xFF; + if (temp2 & 0x80) + temp2 = 0; + if (temp2 > temp) + temp = temp2; + + pwm = (ddblreadl(link, TEMPMON_FANCONTROL) >> 8) & 0x0F; + if (pwm > 10) + pwm = 10; + + if (temp >= link->temp_tab[pwm]) { + while (pwm < 10 && temp >= link->temp_tab[pwm + 1]) + pwm += 1; + } else { + while (pwm > 1 && temp < link->temp_tab[pwm - 2]) + pwm -= 1; + } + ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL); +} + +static void temp_handler(unsigned long data) +{ + struct ddb_link *link = (struct ddb_link *) data; + + spin_lock(&link->temp_lock); + tempmon_setfan(link); + spin_unlock(&link->temp_lock); +} + +static int tempmon_init(struct ddb_link *link, int first_time) +{ + struct ddb *dev = link->dev; + int status = 0; + u32 l = link->nr; + + spin_lock_irq(&link->temp_lock); + if (first_time) { + static u8 temperature_table[11] = { + 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80 }; + + memcpy(link->temp_tab, temperature_table, + sizeof(temperature_table)); + } + dev->handler[l][link->info->tempmon_irq] = temp_handler; + dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link; + ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN | + TEMPMON_CONTROL_INTENABLE), + TEMPMON_CONTROL); + ddblwritel(link, (3 << 8), TEMPMON_FANCONTROL); + + link->overtemperature_error = + ((ddblreadl(link, TEMPMON_CONTROL) & + TEMPMON_CONTROL_OVERTEMP) != 0); + if (link->overtemperature_error) { + dev_info(link->dev->dev, "Over temperature condition\n"); + status = -1; + } + tempmon_setfan(link); + spin_unlock_irq(&link->temp_lock); + return status; +} + +static int ddb_init_tempmon(struct ddb_link *link) +{ + struct ddb_info *info = link->info; + + if (!info->tempmon_irq) + return 0; + if (info->type == DDB_OCTOPUS_MAX_CT) + if (link->ids.regmapid < 0x00010002) + return 0; + spin_lock_init(&link->temp_lock); + dev_dbg(link->dev->dev, "init_tempmon\n"); + return tempmon_init(link, 1); +} + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static int ddb_init_boards(struct ddb *dev) +{ + struct ddb_info *info; + struct ddb_link *link; + u32 l; + + for (l = 0; l < DDB_MAX_LINK; l++) { + link = &dev->link[l]; + info = link->info; + + if (!info) + continue; + if (info->board_control) { + ddbwritel(dev, 0, DDB_LINK_TAG(l) | BOARD_CONTROL); + msleep(100); + ddbwritel(dev, info->board_control_2, + DDB_LINK_TAG(l) | BOARD_CONTROL); + usleep_range(2000, 3000); + ddbwritel(dev, + info->board_control_2 | info->board_control, + DDB_LINK_TAG(l) | BOARD_CONTROL); + usleep_range(2000, 3000); + } + ddb_init_tempmon(link); + } + return 0; +} + +int ddb_init(struct ddb *dev) +{ + mutex_init(&dev->link[0].flash_mutex); + if (no_init) { + ddb_device_create(dev); + return 0; + } + + ddb_init_boards(dev); + + if (ddb_i2c_init(dev) < 0) + goto fail; + ddb_ports_init(dev); + if (ddb_buffers_alloc(dev) < 0) { + dev_info(dev->dev, "Could not allocate buffer memory\n"); + goto fail2; + } + if (ddb_ports_attach(dev) < 0) + goto fail3; + + ddb_device_create(dev); + + if (dev->link[0].info->fan_num) { + ddbwritel(dev, 1, GPIO_DIRECTION); + ddbwritel(dev, 1, GPIO_OUTPUT); + } + return 0; + +fail3: + ddb_ports_detach(dev); + dev_err(dev->dev, "fail3\n"); + ddb_ports_release(dev); +fail2: + dev_err(dev->dev, "fail2\n"); + ddb_buffers_free(dev); + ddb_i2c_release(dev); +fail: + dev_err(dev->dev, "fail1\n"); + return -1; } diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c index 45287f98ee92..376d8a7ca0b9 100644 --- a/drivers/media/pci/ddbridge/ddbridge-i2c.c +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -1,24 +1,21 @@ /* - * ddbridge.c: Digital Devices PCIe bridge driver + * ddbridge-i2c.c: Digital Devices bridge i2c driver * - * Copyright (C) 2010-2011 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 only, as published by the Free Software Foundation. * - * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * To obtain the license, point your browser to - * http://www.gnu.org/copyleft/gpl.html */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -34,30 +31,47 @@ #include #include "ddbridge.h" -#include "ddbridge-regs.h" #include "ddbridge-i2c.h" +#include "ddbridge-regs.h" /******************************************************************************/ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) { struct ddb *dev = i2c->dev; - long stat; + unsigned long stat; u32 val; - i2c->done = 0; - ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); - stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); + ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND); + stat = wait_for_completion_timeout(&i2c->completion, HZ); + val = ddbreadl(dev, i2c->regs + I2C_COMMAND); if (stat == 0) { - dev_err(&dev->pdev->dev, "I2C timeout\n"); - { /* MSI debugging*/ - u32 istat = ddbreadl(INTERRUPT_STATUS); - dev_err(&dev->pdev->dev, "IRS %08x\n", istat); - ddbwritel(istat, INTERRUPT_ACK); + dev_err(dev->dev, "I2C timeout, card %d, port %d, link %u\n", + dev->nr, i2c->nr, i2c->link); + { + u32 istat = ddbreadl(dev, INTERRUPT_STATUS); + + dev_err(dev->dev, "DDBridge IRS %08x\n", istat); + if (i2c->link) { + u32 listat = ddbreadl(dev, + DDB_LINK_TAG(i2c->link) | + INTERRUPT_STATUS); + + dev_err(dev->dev, "DDBridge link %u IRS %08x\n", + i2c->link, listat); + } + if (istat & 1) { + ddbwritel(dev, istat & 1, INTERRUPT_ACK); + } else { + u32 mon = ddbreadl(dev, + i2c->regs + I2C_MONITOR); + + dev_err(dev->dev, "I2C cmd=%08x mon=%08x\n", + val, mon); + } } return -EIO; } - val = ddbreadl(i2c->regs+I2C_COMMAND); if (val & 0x70000) return -EIO; return 0; @@ -66,48 +80,54 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, struct i2c_msg msg[], int num) { - struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); + struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); struct ddb *dev = i2c->dev; u8 addr = 0; - if (num) - addr = msg[0].addr; - - if (num == 2 && msg[1].flags & I2C_M_RD && - !(msg[0].flags & I2C_M_RD)) { - memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, - msg[0].buf, msg[0].len); - ddbwritel(msg[0].len|(msg[1].len << 16), - i2c->regs+I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 1)) { - memcpy_fromio(msg[1].buf, - dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, - msg[1].len); - return num; - } - } - - if (num == 1 && !(msg[0].flags & I2C_M_RD)) { - ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 2)) - return num; - } - if (num == 1 && (msg[0].flags & I2C_M_RD)) { - ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 3)) { - ddbcpyfrom(msg[0].buf, - I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); + addr = msg[0].addr; + if (msg[0].len > i2c->bsize) + return -EIO; + switch (num) { + case 1: + if (msg[0].flags & I2C_M_RD) { + ddbwritel(dev, msg[0].len << 16, + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 3)) + break; + ddbcpyfrom(dev, msg[0].buf, + i2c->rbuf, msg[0].len); return num; } + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 2)) + break; + return num; + case 2: + if ((msg[0].flags & I2C_M_RD) == I2C_M_RD) + break; + if ((msg[1].flags & I2C_M_RD) != I2C_M_RD) + break; + if (msg[1].len > i2c->bsize) + break; + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len | (msg[1].len << 16), + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 1)) + break; + ddbcpyfrom(dev, msg[1].buf, + i2c->rbuf, + msg[1].len); + return num; + default: + break; } return -EIO; } - static u32 ddb_i2c_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static const struct i2c_algorithm ddb_i2c_algo = { @@ -119,55 +139,90 @@ void ddb_i2c_release(struct ddb *dev) { int i; struct ddb_i2c *i2c; - struct i2c_adapter *adap; - for (i = 0; i < dev->info->port_num; i++) { + for (i = 0; i < dev->i2c_num; i++) { i2c = &dev->i2c[i]; - adap = &i2c->adap; - i2c_del_adapter(adap); + i2c_del_adapter(&i2c->adap); } } -int ddb_i2c_init(struct ddb *dev) +static void i2c_handler(unsigned long priv) +{ + struct ddb_i2c *i2c = (struct ddb_i2c *) priv; + + complete(&i2c->completion); +} + +static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, + struct ddb_regmap *regmap, int link, int i, int num) { - int i, j, stat = 0; - struct ddb_i2c *i2c; struct i2c_adapter *adap; - for (i = 0; i < dev->info->port_num; i++) { - i2c = &dev->i2c[i]; - i2c->dev = dev; - i2c->nr = i; - i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); - i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); - i2c->regs = 0x80 + i * 0x20; - ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); - ddbwritel((i2c->rbuf << 16) | i2c->wbuf, - i2c->regs + I2C_TASKADDRESS); - init_waitqueue_head(&i2c->wq); - - adap = &i2c->adap; - i2c_set_adapdata(adap, i2c); + i2c->nr = i; + i2c->dev = dev; + i2c->link = link; + i2c->bsize = regmap->i2c_buf->size; + i2c->wbuf = DDB_LINK_TAG(link) | + (regmap->i2c_buf->base + i2c->bsize * i); + i2c->rbuf = i2c->wbuf; /* + i2c->bsize / 2 */ + i2c->regs = DDB_LINK_TAG(link) | + (regmap->i2c->base + regmap->i2c->size * i); + ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING); + ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff), + i2c->regs + I2C_TASKADDRESS); + init_completion(&i2c->completion); + + adap = &i2c->adap; + i2c_set_adapdata(adap, i2c); #ifdef I2C_ADAP_CLASS_TV_DIGITAL - adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; + adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; #else #ifdef I2C_CLASS_TV_ANALOG - adap->class = I2C_CLASS_TV_ANALOG; + adap->class = I2C_CLASS_TV_ANALOG; #endif #endif - strcpy(adap->name, "ddbridge"); - adap->algo = &ddb_i2c_algo; - adap->algo_data = (void *)i2c; - adap->dev.parent = &dev->pdev->dev; - stat = i2c_add_adapter(adap); - if (stat) - break; + snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x", + dev->nr, i2c->link, i); + adap->algo = &ddb_i2c_algo; + adap->algo_data = (void *)i2c; + adap->dev.parent = dev->dev; + return i2c_add_adapter(adap); +} + +int ddb_i2c_init(struct ddb *dev) +{ + int stat = 0; + u32 i, j, num = 0, l, base; + struct ddb_i2c *i2c; + struct i2c_adapter *adap; + struct ddb_regmap *regmap; + + for (l = 0; l < DDB_MAX_LINK; l++) { + if (!dev->link[l].info) + continue; + regmap = dev->link[l].info->regmap; + if (!regmap || !regmap->i2c) + continue; + base = regmap->irq_base_i2c; + for (i = 0; i < regmap->i2c->num; i++) { + if (!(dev->link[l].info->i2c_mask & (1 << i))) + continue; + i2c = &dev->i2c[num]; + dev->handler_data[l][i + base] = (unsigned long) i2c; + dev->handler[l][i + base] = i2c_handler; + stat = ddb_i2c_add(dev, i2c, regmap, l, i, num); + if (stat) + break; + num++; + } } - if (stat) - for (j = 0; j < i; j++) { + if (stat) { + for (j = 0; j < num; j++) { i2c = &dev->i2c[j]; adap = &i2c->adap; i2c_del_adapter(adap); } + } else + dev->i2c_num = num; return stat; } diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.h b/drivers/media/pci/ddbridge/ddbridge-i2c.h index e1aa3b74f672..7ed220506c05 100644 --- a/drivers/media/pci/ddbridge/ddbridge-i2c.h +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.h @@ -1,20 +1,19 @@ /* - * ddbridge.c: Digital Devices PCIe bridge driver + * ddbridge-i2c.c: Digital Devices bridge i2c driver * - * Copyright (C) 2010-2011 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 only, as published by the Free Software Foundation. * - * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * To obtain the license, point your browser to - * http://www.gnu.org/copyleft/gpl.html */ #ifndef __DDBRIDGE_I2C_H__ @@ -70,24 +69,26 @@ static int __maybe_unused i2c_read_regs(struct i2c_adapter *adapter, return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; } -static int __maybe_unused i2c_read_reg(struct i2c_adapter *adapter, u8 adr, - u8 reg, u8 *val) -{ - return i2c_read_regs(adapter, adr, reg, val, 1); -} - -static int __maybe_unused i2c_read_reg16(struct i2c_adapter *adapter, - u8 adr, u16 reg, u8 *val) +static int __maybe_unused i2c_read_regs16(struct i2c_adapter *adapter, + u8 adr, u16 reg, u8 *val, u8 len) { u8 msg[2] = { reg >> 8, reg & 0xff }; struct i2c_msg msgs[2] = { { .addr = adr, .flags = 0, .buf = msg, .len = 2 }, { .addr = adr, .flags = I2C_M_RD, - .buf = val, .len = 1 } }; + .buf = val, .len = len } }; return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; } +static int __maybe_unused i2c_write_reg16(struct i2c_adapter *adap, + u8 adr, u16 reg, u8 val) +{ + u8 msg[3] = { reg >> 8, reg & 0xff, val }; + + return i2c_write(adap, adr, msg, 3); +} + static int __maybe_unused i2c_write_reg(struct i2c_adapter *adap, u8 adr, u8 reg, u8 val) { @@ -96,4 +97,16 @@ static int __maybe_unused i2c_write_reg(struct i2c_adapter *adap, return i2c_write(adap, adr, msg, 2); } +static int __maybe_unused i2c_read_reg16(struct i2c_adapter *adapter, + u8 adr, u16 reg, u8 *val) +{ + return i2c_read_regs16(adapter, adr, reg, val, 1); +} + +static int __maybe_unused i2c_read_reg(struct i2c_adapter *adapter, + u8 adr, u8 reg, u8 *val) +{ + return i2c_read_regs(adapter, adr, reg, val, 1); +} + #endif /* __DDBRIDGE_I2C_H__ */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 41c0adc176b1..73b041118bbf 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -1,20 +1,19 @@ /* * ddbridge.c: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2011 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 only, as published by the Free Software Foundation. * - * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * To obtain the license, point your browser to - * http://www.gnu.org/copyleft/gpl.html */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -37,15 +36,56 @@ #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +/****************************************************************************/ +/* module parameters */ + +int adapter_alloc; +module_param(adapter_alloc, int, 0444); +MODULE_PARM_DESC(adapter_alloc, + "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); + +#ifdef CONFIG_PCI_MSI +int msi = 1; +module_param(msi, int, 0444); +MODULE_PARM_DESC(msi, + " Control MSI interrupts: 0-disable, 1-enable (default)"); +#endif + +int ci_bitrate = 70000; +module_param(ci_bitrate, int, 0444); +MODULE_PARM_DESC(ci_bitrate, " Bitrate in KHz for output to CI."); + +int ts_loop = -1; +module_param(ts_loop, int, 0444); +MODULE_PARM_DESC(ts_loop, "TS in/out test loop on port ts_loop"); + int xo2_speed = 2; module_param(xo2_speed, int, 0444); MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards"); +#ifdef __arm__ +int alt_dma = 1; +#else +int alt_dma; +#endif +module_param(alt_dma, int, 0444); +MODULE_PARM_DESC(alt_dma, "use alternative DMA buffer handling"); + +int no_init; +module_param(no_init, int, 0444); +MODULE_PARM_DESC(no_init, "do not initialize most devices"); + int stv0910_single; module_param(stv0910_single, int, 0444); MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); -/******************************************************************************/ +/****************************************************************************/ + +struct workqueue_struct *ddb_wq; + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ static void ddb_unmap(struct ddb *dev) { @@ -54,170 +94,261 @@ static void ddb_unmap(struct ddb *dev) vfree(dev); } - -static void ddb_remove(struct pci_dev *pdev) +static void ddb_irq_disable(struct ddb *dev) { - struct ddb *dev = pci_get_drvdata(pdev); - - ddb_ports_detach(dev); - ddb_i2c_release(dev); + ddbwritel(dev, 0, INTERRUPT_ENABLE); + ddbwritel(dev, 0, MSI1_ENABLE); +} - ddbwritel(0, INTERRUPT_ENABLE); +static void ddb_irq_exit(struct ddb *dev) +{ + ddb_irq_disable(dev); + if (dev->msi == 2) + free_irq(dev->pdev->irq + 1, dev); free_irq(dev->pdev->irq, dev); #ifdef CONFIG_PCI_MSI if (dev->msi) pci_disable_msi(dev->pdev); #endif +} + +static void ddb_remove(struct pci_dev *pdev) +{ + struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); + + ddb_device_destroy(dev); + ddb_ports_detach(dev); + ddb_i2c_release(dev); + + ddb_irq_exit(dev); ddb_ports_release(dev); ddb_buffers_free(dev); - ddb_device_destroy(dev); ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); } +#ifdef CONFIG_PCI_MSI +static void ddb_irq_msi(struct ddb *dev, int nr) +{ + int stat; + + if (msi && pci_msi_enabled()) { + stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI); + if (stat >= 1) { + dev->msi = stat; + dev_info(dev->dev, "using %d MSI interrupt(s)\n", + dev->msi); + } else + dev_info(dev->dev, "MSI not available.\n"); + } +} +#endif -static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static int ddb_irq_init(struct ddb *dev) +{ + int stat; + int irq_flag = IRQF_SHARED; + + ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); + ddbwritel(dev, 0x00000000, MSI1_ENABLE); + ddbwritel(dev, 0x00000000, MSI2_ENABLE); + ddbwritel(dev, 0x00000000, MSI3_ENABLE); + ddbwritel(dev, 0x00000000, MSI4_ENABLE); + ddbwritel(dev, 0x00000000, MSI5_ENABLE); + ddbwritel(dev, 0x00000000, MSI6_ENABLE); + ddbwritel(dev, 0x00000000, MSI7_ENABLE); + +#ifdef CONFIG_PCI_MSI + ddb_irq_msi(dev, 2); + + if (dev->msi) + irq_flag = 0; + if (dev->msi == 2) { + stat = request_irq(dev->pdev->irq, ddb_irq_handler0, + irq_flag, "ddbridge", (void *) dev); + if (stat < 0) + return stat; + stat = request_irq(dev->pdev->irq + 1, ddb_irq_handler1, + irq_flag, "ddbridge", (void *) dev); + if (stat < 0) { + free_irq(dev->pdev->irq, dev); + return stat; + } + } else +#endif + { + stat = request_irq(dev->pdev->irq, ddb_irq_handler, + irq_flag, "ddbridge", (void *) dev); + if (stat < 0) + return stat; + } + if (dev->msi == 2) { + ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE); + ddbwritel(dev, 0x0000000f, MSI1_ENABLE); + } else { + ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); + ddbwritel(dev, 0x00000000, MSI1_ENABLE); + } + return stat; +} + +static int ddb_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { struct ddb *dev; int stat = 0; - int irq_flag = IRQF_SHARED; if (pci_enable_device(pdev) < 0) return -ENODEV; + pci_set_master(pdev); + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) + return -ENODEV; + dev = vzalloc(sizeof(struct ddb)); if (dev == NULL) return -ENOMEM; + mutex_init(&dev->mutex); + dev->has_dma = 1; dev->pdev = pdev; + dev->dev = &pdev->dev; pci_set_drvdata(pdev, dev); - dev->info = (struct ddb_info *) id->driver_data; - dev_info(&pdev->dev, "Detected %s\n", dev->info->name); + dev->link[0].ids.vendor = id->vendor; + dev->link[0].ids.device = id->device; + dev->link[0].ids.subvendor = id->subvendor; + dev->link[0].ids.subdevice = id->subdevice; + + dev->link[0].dev = dev; + dev->link[0].info = (struct ddb_info *) id->driver_data; + dev_info(&pdev->dev, "detected %s\n", dev->link[0].info->name); + + dev->regs_len = pci_resource_len(dev->pdev, 0); dev->regs = ioremap(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); + if (!dev->regs) { + dev_err(&pdev->dev, "not enough memory for register map\n"); stat = -ENOMEM; goto fail; } - dev_info(&pdev->dev, "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); - -#ifdef CONFIG_PCI_MSI - if (pci_msi_enabled()) - stat = pci_enable_msi(dev->pdev); - if (stat) { - dev_info(&pdev->dev, "MSI not available.\n"); - } else { - irq_flag = 0; - dev->msi = 1; + if (ddbreadl(dev, 0) == 0xffffffff) { + dev_err(&pdev->dev, "cannot read registers\n"); + stat = -ENODEV; + goto fail; } -#endif - stat = request_irq(dev->pdev->irq, irq_handler, - irq_flag, "DDBridge", (void *) dev); + + dev->link[0].ids.hwid = ddbreadl(dev, 0); + dev->link[0].ids.regmapid = ddbreadl(dev, 4); + + dev_info(&pdev->dev, "HW %08x REGMAP %08x\n", + dev->link[0].ids.hwid, dev->link[0].ids.regmapid); + + ddbwritel(dev, 0, DMA_BASE_READ); + ddbwritel(dev, 0, DMA_BASE_WRITE); + + stat = ddb_irq_init(dev); if (stat < 0) - goto fail1; - ddbwritel(0, DMA_BASE_WRITE); - ddbwritel(0, DMA_BASE_READ); - ddbwritel(0xffffffff, INTERRUPT_ACK); - ddbwritel(0xfff0f, INTERRUPT_ENABLE); - ddbwritel(0, MSI1_ENABLE); - - /* board control */ - if (dev->info->board_control) { - ddbwritel(0, DDB_LINK_TAG(0) | BOARD_CONTROL); - msleep(100); - ddbwritel(dev->info->board_control_2, - DDB_LINK_TAG(0) | BOARD_CONTROL); - usleep_range(2000, 3000); - ddbwritel(dev->info->board_control_2 - | dev->info->board_control, - DDB_LINK_TAG(0) | BOARD_CONTROL); - usleep_range(2000, 3000); - } + goto fail0; - if (ddb_i2c_init(dev) < 0) - goto fail1; - ddb_ports_init(dev); - if (ddb_buffers_alloc(dev) < 0) { - dev_err(&pdev->dev, "Could not allocate buffer memory\n"); - goto fail2; - } - if (ddb_ports_attach(dev) < 0) - goto fail3; - ddb_device_create(dev); - return 0; + if (ddb_init(dev) == 0) + return 0; -fail3: - ddb_ports_detach(dev); - dev_err(&pdev->dev, "fail3\n"); - ddb_ports_release(dev); -fail2: - dev_err(&pdev->dev, "fail2\n"); - ddb_buffers_free(dev); -fail1: - dev_err(&pdev->dev, "fail1\n"); + ddb_irq_exit(dev); +fail0: + dev_err(&pdev->dev, "fail0\n"); if (dev->msi) pci_disable_msi(dev->pdev); - if (stat == 0) - free_irq(dev->pdev->irq, dev); fail: dev_err(&pdev->dev, "fail\n"); + ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); return -1; } -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ static const struct ddb_info ddb_none = { .type = DDB_NONE, - .name = "Digital Devices PCIe bridge", + .name = "unknown Digital Devices PCIe card, install newer driver", + .regmap = &octopus_map, }; static const struct ddb_info ddb_octopus = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, +}; + +static const struct ddb_info ddb_octopusv3 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus V3 DVB adapter", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, }; static const struct ddb_info ddb_octopus_le = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus LE DVB adapter", + .regmap = &octopus_map, .port_num = 2, + .i2c_mask = 0x03, }; static const struct ddb_info ddb_octopus_oem = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus OEM", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, + .led_num = 1, + .fan_num = 1, + .temp_num = 1, + .temp_bus = 0, }; static const struct ddb_info ddb_octopus_mini = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus Mini", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, }; static const struct ddb_info ddb_v6 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V6 DVB adapter", + .regmap = &octopus_map, .port_num = 3, + .i2c_mask = 0x07, }; + static const struct ddb_info ddb_v6_5 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V6.5 DVB adapter", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, }; static const struct ddb_info ddb_v7 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V7 DVB adapter", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 2, .board_control_2 = 4, .ts_quirks = TS_QUIRK_REVERSED, @@ -226,22 +357,20 @@ static const struct ddb_info ddb_v7 = { static const struct ddb_info ddb_v7a = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 2, .board_control_2 = 4, .ts_quirks = TS_QUIRK_REVERSED, }; -static const struct ddb_info ddb_dvbct = { - .type = DDB_OCTOPUS, - .name = "Digital Devices DVBCT V6.1 DVB adapter", - .port_num = 3, -}; - static const struct ddb_info ddb_ctv7 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine CT V7 DVB adapter", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 3, .board_control_2 = 4, }; @@ -249,134 +378,217 @@ static const struct ddb_info ddb_ctv7 = { static const struct ddb_info ddb_satixS2v3 = { .type = DDB_OCTOPUS, .name = "Mystique SaTiX-S2 V3 DVB adapter", + .regmap = &octopus_map, .port_num = 3, + .i2c_mask = 0x07, }; -static const struct ddb_info ddb_octopusv3 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus V3 DVB adapter", +static const struct ddb_info ddb_ci = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x03, +}; + +static const struct ddb_info ddb_cis = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI single", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x03, }; -/*** MaxA8 adapters ***********************************************************/ +static const struct ddb_info ddb_ci_s2_pro = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI S2 Pro", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 2, + .board_control_2 = 4, +}; + +static const struct ddb_info ddb_ci_s2_pro_a = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI S2 Pro Advanced", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 2, + .board_control_2 = 4, +}; + +static const struct ddb_info ddb_dvbct = { + .type = DDB_OCTOPUS, + .name = "Digital Devices DVBCT V6.1 DVB adapter", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x07, +}; + +/****************************************************************************/ static struct ddb_info ddb_ct2_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 CT2", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, }; static struct ddb_info ddb_c2t2_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, }; static struct ddb_info ddb_isdbt_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 ISDBT", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, }; static struct ddb_info ddb_c2t2i_v0_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2I V0", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, + .tempmon_irq = 24, }; static struct ddb_info ddb_c2t2i_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2I", + .regmap = &octopus_map, .port_num = 4, + .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, }; -/******************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ #define DDVID 0xdd01 /* Digital Devices Vendor ID */ -#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ - .vendor = _vend, .device = _dev, \ - .subvendor = _subvend, .subdevice = _subdev, \ - .driver_data = (unsigned long)&_driverdata } - -static const struct pci_device_id ddb_id_tbl[] = { - DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), - DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), - DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), - DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), - DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), - DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), - DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), - DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a), - DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), - DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), - DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), - DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8), - DDB_ID(DDVID, 0x0006, DDVID, 0x0039, ddb_ctv7), +#define DDB_DEVICE(_device, _subdevice, _driver_data) { \ + PCI_DEVICE_SUB(DDVID, _device, DDVID, _subdevice), \ + .driver_data = (kernel_ulong_t) &_driver_data } + +#define DDB_DEVICE_ANY(_device) { \ + PCI_DEVICE_SUB(DDVID, _device, DDVID, PCI_ANY_ID), \ + .driver_data = (kernel_ulong_t) &ddb_none } + +static const struct pci_device_id ddb_id_table[] = { + DDB_DEVICE(0x0002, 0x0001, ddb_octopus), + DDB_DEVICE(0x0003, 0x0001, ddb_octopus), + DDB_DEVICE(0x0005, 0x0004, ddb_octopusv3), + DDB_DEVICE(0x0003, 0x0002, ddb_octopus_le), + DDB_DEVICE(0x0003, 0x0003, ddb_octopus_oem), + DDB_DEVICE(0x0003, 0x0010, ddb_octopus_mini), + DDB_DEVICE(0x0005, 0x0011, ddb_octopus_mini), + DDB_DEVICE(0x0003, 0x0020, ddb_v6), + DDB_DEVICE(0x0003, 0x0021, ddb_v6_5), + DDB_DEVICE(0x0006, 0x0022, ddb_v7), + DDB_DEVICE(0x0006, 0x0024, ddb_v7a), + DDB_DEVICE(0x0003, 0x0030, ddb_dvbct), + DDB_DEVICE(0x0003, 0xdb03, ddb_satixS2v3), + DDB_DEVICE(0x0006, 0x0031, ddb_ctv7), + DDB_DEVICE(0x0006, 0x0032, ddb_ctv7), + DDB_DEVICE(0x0006, 0x0033, ddb_ctv7), + DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8), + DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8), + DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8), + DDB_DEVICE(0x0008, 0x0037, ddb_c2t2i_v0_8), + DDB_DEVICE(0x0008, 0x0038, ddb_c2t2i_8), + DDB_DEVICE(0x0006, 0x0039, ddb_ctv7), + DDB_DEVICE(0x0011, 0x0040, ddb_ci), + DDB_DEVICE(0x0011, 0x0041, ddb_cis), + DDB_DEVICE(0x0012, 0x0042, ddb_ci), + DDB_DEVICE(0x0013, 0x0043, ddb_ci_s2_pro), + DDB_DEVICE(0x0013, 0x0044, ddb_ci_s2_pro_a), /* in case sub-ids got deleted in flash */ - DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_DEVICE_ANY(0x0003), + DDB_DEVICE_ANY(0x0005), + DDB_DEVICE_ANY(0x0006), + DDB_DEVICE_ANY(0x0007), + DDB_DEVICE_ANY(0x0008), + DDB_DEVICE_ANY(0x0011), + DDB_DEVICE_ANY(0x0012), + DDB_DEVICE_ANY(0x0013), + DDB_DEVICE_ANY(0x0201), + DDB_DEVICE_ANY(0x0203), + DDB_DEVICE_ANY(0x0210), + DDB_DEVICE_ANY(0x0220), + DDB_DEVICE_ANY(0x0320), + DDB_DEVICE_ANY(0x0321), + DDB_DEVICE_ANY(0x0322), + DDB_DEVICE_ANY(0x0323), + DDB_DEVICE_ANY(0x0328), + DDB_DEVICE_ANY(0x0329), {0} }; -MODULE_DEVICE_TABLE(pci, ddb_id_tbl); +MODULE_DEVICE_TABLE(pci, ddb_id_table); static struct pci_driver ddb_pci_driver = { - .name = "DDBridge", - .id_table = ddb_id_tbl, + .name = "ddbridge", + .id_table = ddb_id_table, .probe = ddb_probe, .remove = ddb_remove, }; static __init int module_init_ddbridge(void) { - int ret; - - pr_info("Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n"); - - ret = ddb_class_create(); - if (ret < 0) - return ret; - ret = pci_register_driver(&ddb_pci_driver); - if (ret < 0) - ddb_class_destroy(); - return ret; + int stat = -1; + + pr_info("Digital Devices PCIE bridge driver " + DDBRIDGE_VERSION + ", Copyright (C) 2010-17 Digital Devices GmbH\n"); + if (ddb_class_create() < 0) + return -1; + ddb_wq = create_workqueue("ddbridge"); + if (ddb_wq == NULL) + goto exit1; + stat = pci_register_driver(&ddb_pci_driver); + if (stat < 0) + goto exit2; + return stat; +exit2: + destroy_workqueue(ddb_wq); +exit1: + ddb_class_destroy(); + return stat; } static __exit void module_exit_ddbridge(void) { pci_unregister_driver(&ddb_pci_driver); + destroy_workqueue(ddb_wq); ddb_class_destroy(); } @@ -384,6 +596,6 @@ module_init(module_init_ddbridge); module_exit(module_exit_ddbridge); MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); -MODULE_AUTHOR("Ralph Metzler"); +MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.5"); +MODULE_VERSION(DDBRIDGE_VERSION); diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h index 98cebb97d64f..03a34e1ddadf 100644 --- a/drivers/media/pci/ddbridge/ddbridge-regs.h +++ b/drivers/media/pci/ddbridge/ddbridge-regs.h @@ -1,7 +1,7 @@ /* * ddbridge-regs.h: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2011 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,20 +17,26 @@ * http://www.gnu.org/copyleft/gpl.html */ -/* DD-DVBBridgeV1.h 273 2010-09-17 05:03:16Z manfred */ +/* ------------------------------------------------------------------------- */ +/* SPI Controller */ -/* Register Definitions */ +#define SPI_CONTROL 0x10 +#define SPI_DATA 0x14 -#define CUR_REGISTERMAP_VERSION 0x10000 +/* ------------------------------------------------------------------------- */ +/* GPIO */ -#define HARDWARE_VERSION 0x00 -#define REGISTERMAP_VERSION 0x04 +#define GPIO_OUTPUT 0x20 +#define GPIO_INPUT 0x24 +#define GPIO_DIRECTION 0x28 /* ------------------------------------------------------------------------- */ -/* SPI Controller */ +/* MDIO */ -#define SPI_CONTROL 0x10 -#define SPI_DATA 0x14 +#define MDIO_CTRL 0x20 +#define MDIO_ADR 0x24 +#define MDIO_REG 0x28 +#define MDIO_VAL 0x2C /* ------------------------------------------------------------------------- */ @@ -38,14 +44,14 @@ /* ------------------------------------------------------------------------- */ -/* Interrupt controller */ -/* How many MSI's are available depends on HW (Min 2 max 8) */ -/* How many are usable also depends on Host platform */ +/* Interrupt controller + * How many MSI's are available depends on HW (Min 2 max 8) + * How many are usable also depends on Host platform + */ #define INTERRUPT_BASE (0x40) #define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00) -#define MSI0_ENABLE (INTERRUPT_BASE + 0x00) #define MSI1_ENABLE (INTERRUPT_BASE + 0x04) #define MSI2_ENABLE (INTERRUPT_BASE + 0x08) #define MSI3_ENABLE (INTERRUPT_BASE + 0x0C) @@ -57,59 +63,31 @@ #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) #define INTERRUPT_ACK (INTERRUPT_BASE + 0x20) -#define INTMASK_I2C1 (0x00000001) -#define INTMASK_I2C2 (0x00000002) -#define INTMASK_I2C3 (0x00000004) -#define INTMASK_I2C4 (0x00000008) - -#define INTMASK_CIRQ1 (0x00000010) -#define INTMASK_CIRQ2 (0x00000020) -#define INTMASK_CIRQ3 (0x00000040) -#define INTMASK_CIRQ4 (0x00000080) - -#define INTMASK_TSINPUT1 (0x00000100) -#define INTMASK_TSINPUT2 (0x00000200) -#define INTMASK_TSINPUT3 (0x00000400) -#define INTMASK_TSINPUT4 (0x00000800) -#define INTMASK_TSINPUT5 (0x00001000) -#define INTMASK_TSINPUT6 (0x00002000) -#define INTMASK_TSINPUT7 (0x00004000) -#define INTMASK_TSINPUT8 (0x00008000) - -#define INTMASK_TSOUTPUT1 (0x00010000) -#define INTMASK_TSOUTPUT2 (0x00020000) -#define INTMASK_TSOUTPUT3 (0x00040000) -#define INTMASK_TSOUTPUT4 (0x00080000) +/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ +#define TEMPMON_BASE (0x1c0) +#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00) + +#define TEMPMON_CONTROL_AUTOSCAN (0x00000002) +#define TEMPMON_CONTROL_INTENABLE (0x00000004) +#define TEMPMON_CONTROL_OVERTEMP (0x00008000) + +/* SHORT Temperature in Celsius x 256 */ +#define TEMPMON_SENSOR0 (TEMPMON_BASE + 0x04) +#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08) + +#define TEMPMON_FANCONTROL (TEMPMON_BASE + 0x10) /* ------------------------------------------------------------------------- */ /* I2C Master Controller */ -#define I2C_BASE (0x80) /* Byte offset */ - #define I2C_COMMAND (0x00) #define I2C_TIMING (0x04) #define I2C_TASKLENGTH (0x08) /* High read, low write */ #define I2C_TASKADDRESS (0x0C) /* High read, low write */ - #define I2C_MONITOR (0x1C) -#define I2C_BASE_1 (I2C_BASE + 0x00) -#define I2C_BASE_2 (I2C_BASE + 0x20) -#define I2C_BASE_3 (I2C_BASE + 0x40) -#define I2C_BASE_4 (I2C_BASE + 0x60) - -#define I2C_BASE_N(i) (I2C_BASE + (i) * 0x20) - -#define I2C_TASKMEM_BASE (0x1000) /* Byte offset */ -#define I2C_TASKMEM_SIZE (0x1000) - #define I2C_SPEED_400 (0x04030404) -#define I2C_SPEED_200 (0x09080909) -#define I2C_SPEED_154 (0x0C0B0C0C) #define I2C_SPEED_100 (0x13121313) -#define I2C_SPEED_77 (0x19181919) -#define I2C_SPEED_50 (0x27262727) - /* ------------------------------------------------------------------------- */ /* DMA Controller */ @@ -117,35 +95,41 @@ #define DMA_BASE_WRITE (0x100) #define DMA_BASE_READ (0x140) -#define DMA_CONTROL (0x00) /* 64 */ -#define DMA_ERROR (0x04) /* 65 ( only read instance ) */ - -#define DMA_DIAG_CONTROL (0x1C) /* 71 */ -#define DMA_DIAG_PACKETCOUNTER_LOW (0x20) /* 72 */ -#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24) /* 73 */ -#define DMA_DIAG_TIMECOUNTER_LOW (0x28) /* 74 */ -#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C) /* 75 */ -#define DMA_DIAG_RECHECKCOUNTER (0x30) /* 76 ( Split completions on read ) */ -#define DMA_DIAG_WAITTIMEOUTINIT (0x34) /* 77 */ -#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38) /* 78 */ -#define DMA_DIAG_WAITCOUNTER (0x3C) /* 79 */ +#define TS_CONTROL(_io) (_io->regs + 0x00) +#define TS_CONTROL2(_io) (_io->regs + 0x04) /* ------------------------------------------------------------------------- */ /* DMA Buffer */ -#define TS_INPUT_BASE (0x200) -#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 16 + 0x00) +#define DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00) +#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04) +#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08) +#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c) + +/* ------------------------------------------------------------------------- */ +/* CI Interface (only CI-Bridge) */ + +#define CI_BASE (0x400) +#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00) + +#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04) +#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08) +#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c) +#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10) -#define TS_OUTPUT_BASE (0x280) -#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 16 + 0x00) +#define CI_RESET_CAM (0x00000001) +#define CI_POWER_ON (0x00000002) +#define CI_ENABLE (0x00000004) +#define CI_BYPASS_DISABLE (0x00000010) -#define DMA_BUFFER_BASE (0x300) +#define CI_CAM_READY (0x00010000) +#define CI_CAM_DETECT (0x00020000) +#define CI_READY (0x80000000) -#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 16 + 0x00) -#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 16 + 0x04) -#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 16 + 0x08) -#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 16 + 0x0c) +#define CI_READ_CMD (0x40000000) +#define CI_WRITE_CMD (0x80000000) -#define DMA_BASE_ADDRESS_TABLE (0x2000) -#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) +#define CI_BUFFER_BASE (0x3000) +#define CI_BUFFER_SIZE (0x0800) +#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 4290a1e28531..65b3f6b38bd7 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -1,7 +1,8 @@ /* * ddbridge.h: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2011 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,15 +21,39 @@ #ifndef _DDBRIDGE_H_ #define _DDBRIDGE_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include -#include #include #include -#include +#include +#include +#include + #include #include +#include +#include #include "dmxdev.h" #include "dvbdev.h" @@ -37,72 +62,121 @@ #include "dvb_ringbuffer.h" #include "dvb_ca_en50221.h" #include "dvb_net.h" -#include "cxd2099.h" -/* MSI had problems with lost interrupts, fixed but needs testing */ -#undef CONFIG_PCI_MSI +#define DDBRIDGE_VERSION "0.9.29-integrated" -#define DDB_MAX_I2C 4 -#define DDB_MAX_PORT 4 -#define DDB_MAX_INPUT 8 -#define DDB_MAX_OUTPUT 4 +#define DDB_MAX_I2C 32 +#define DDB_MAX_PORT 32 +#define DDB_MAX_INPUT 64 +#define DDB_MAX_OUTPUT 32 #define DDB_MAX_LINK 4 #define DDB_LINK_SHIFT 28 #define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT) -#define DDB_XO2_TYPE_NONE 0 -#define DDB_XO2_TYPE_DUOFLEX 1 -#define DDB_XO2_TYPE_CI 2 +struct ddb_regset { + u32 base; + u32 num; + u32 size; +}; + +struct ddb_regmap { + u32 irq_base_i2c; + u32 irq_base_idma; + u32 irq_base_odma; + + struct ddb_regset *i2c; + struct ddb_regset *i2c_buf; + struct ddb_regset *idma; + struct ddb_regset *idma_buf; + struct ddb_regset *odma; + struct ddb_regset *odma_buf; + + struct ddb_regset *input; + struct ddb_regset *output; + + struct ddb_regset *channel; +}; + +struct ddb_ids { + u16 vendor; + u16 device; + u16 subvendor; + u16 subdevice; + + u32 hwid; + u32 regmapid; + u32 devid; + u32 mac; +}; struct ddb_info { int type; -#define DDB_NONE 0 -#define DDB_OCTOPUS 1 -#define DDB_OCTOPUS_MAX_CT 6 +#define DDB_NONE 0 +#define DDB_OCTOPUS 1 +#define DDB_OCTOPUS_CI 2 +#define DDB_OCTOPUS_MAX_CT 6 char *name; - int port_num; - u32 port_type[DDB_MAX_PORT]; + u32 i2c_mask; + u8 port_num; + u8 led_num; + u8 fan_num; + u8 temp_num; + u8 temp_bus; u32 board_control; u32 board_control_2; + u8 mdio_num; + u8 con_clock; /* use a continuous clock */ u8 ts_quirks; #define TS_QUIRK_SERIAL 1 #define TS_QUIRK_REVERSED 2 #define TS_QUIRK_ALT_OSC 8 + u32 tempmon_irq; + struct ddb_regmap *regmap; }; -/* DMA_SIZE MUST be divisible by 188 and 128 !!! */ +/* DMA_SIZE MUST be smaller than 256k and + * MUST be divisible by 188 and 128 !!! + */ + +#define DMA_MAX_BUFS 32 /* hardware table limit */ -#define INPUT_DMA_MAX_BUFS 32 /* hardware table limit */ #define INPUT_DMA_BUFS 8 #define INPUT_DMA_SIZE (128*47*21) +#define INPUT_DMA_IRQ_DIV 1 -#define OUTPUT_DMA_MAX_BUFS 32 #define OUTPUT_DMA_BUFS 8 #define OUTPUT_DMA_SIZE (128*47*21) +#define OUTPUT_DMA_IRQ_DIV 1 struct ddb; struct ddb_port; -struct ddb_input { - struct ddb_port *port; - u32 nr; - int attached; +struct ddb_dma { + void *io; + u32 regs; + u32 bufregs; - dma_addr_t pbuf[INPUT_DMA_MAX_BUFS]; - u8 *vbuf[INPUT_DMA_MAX_BUFS]; - u32 dma_buf_num; - u32 dma_buf_size; + dma_addr_t pbuf[DMA_MAX_BUFS]; + u8 *vbuf[DMA_MAX_BUFS]; + u32 num; + u32 size; + u32 div; + u32 bufval; - struct tasklet_struct tasklet; + struct work_struct work; spinlock_t lock; wait_queue_head_t wq; int running; u32 stat; + u32 ctrl; u32 cbuf; u32 coff; +}; - struct dvb_adapter adap; +struct ddb_dvb { + struct dvb_adapter *adap; + int adap_registered; struct dvb_device *dev; struct i2c_client *i2c_client[1]; struct dvb_frontend *fe; @@ -113,131 +187,245 @@ struct ddb_input { struct dmx_frontend hw_frontend; struct dmx_frontend mem_frontend; int users; - int (*gate_ctrl)(struct dvb_frontend *, int); + u32 attached; + u8 input; + + enum fe_sec_tone_mode tone; + enum fe_sec_voltage voltage; + + int (*i2c_gate_ctrl)(struct dvb_frontend *, int); + int (*set_voltage)(struct dvb_frontend *fe, + enum fe_sec_voltage voltage); + int (*set_input)(struct dvb_frontend *fe, int input); + int (*diseqc_send_master_cmd)(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd); }; -struct ddb_output { +struct ddb_ci { + struct dvb_ca_en50221 en; struct ddb_port *port; u32 nr; - dma_addr_t pbuf[OUTPUT_DMA_MAX_BUFS]; - u8 *vbuf[OUTPUT_DMA_MAX_BUFS]; - u32 dma_buf_num; - u32 dma_buf_size; - struct tasklet_struct tasklet; - spinlock_t lock; - wait_queue_head_t wq; - int running; - u32 stat; - u32 cbuf; - u32 coff; + struct mutex lock; +}; - struct dvb_adapter adap; - struct dvb_device *dev; +struct ddb_io { + struct ddb_port *port; + u32 nr; + u32 regs; + struct ddb_dma *dma; + struct ddb_io *redo; + struct ddb_io *redi; }; +#define ddb_output ddb_io +#define ddb_input ddb_io + struct ddb_i2c { struct ddb *dev; u32 nr; - struct i2c_adapter adap; - struct i2c_adapter adap2; u32 regs; + u32 link; + struct i2c_adapter adap; u32 rbuf; u32 wbuf; - int done; - wait_queue_head_t wq; + u32 bsize; + struct completion completion; }; struct ddb_port { struct ddb *dev; u32 nr; + u32 pnr; + u32 regs; + u32 lnr; struct ddb_i2c *i2c; struct mutex i2c_gate_lock; u32 class; #define DDB_PORT_NONE 0 #define DDB_PORT_CI 1 #define DDB_PORT_TUNER 2 - u32 type; -#define DDB_TUNER_NONE 0 -#define DDB_TUNER_DVBS_ST 1 -#define DDB_TUNER_DVBS_ST_AA 2 -#define DDB_TUNER_DVBCT2_SONY_P 7 -#define DDB_TUNER_DVBC2T2_SONY_P 8 -#define DDB_TUNER_ISDBT_SONY_P 9 -#define DDB_TUNER_DVBS_STV0910_P 10 -#define DDB_TUNER_DVBS_STV0910_PR 14 -#define DDB_TUNER_DVBC2T2I_SONY_P 15 -#define DDB_TUNER_DVBCT_TR 16 -#define DDB_TUNER_DVBCT_ST 17 -#define DDB_TUNER_XO2_DVBS_STV0910 32 -#define DDB_TUNER_XO2_DVBCT2_SONY 33 -#define DDB_TUNER_XO2_ISDBT_SONY 34 -#define DDB_TUNER_XO2_DVBC2T2_SONY 35 -#define DDB_TUNER_XO2_ATSC_ST 36 -#define DDB_TUNER_XO2_DVBC2T2I_SONY 37 - - u32 adr; +#define DDB_PORT_LOOP 3 + char *name; + char *type_name; + u32 type; +#define DDB_TUNER_NONE 0 +#define DDB_TUNER_DVBS_ST 1 +#define DDB_TUNER_DVBS_ST_AA 2 +#define DDB_TUNER_DVBCT_TR 3 +#define DDB_TUNER_DVBCT_ST 4 +#define DDB_CI_INTERNAL 5 +#define DDB_CI_EXTERNAL_SONY 6 +#define DDB_TUNER_DVBCT2_SONY_P 7 +#define DDB_TUNER_DVBC2T2_SONY_P 8 +#define DDB_TUNER_ISDBT_SONY_P 9 +#define DDB_TUNER_DVBS_STV0910_P 10 +#define DDB_TUNER_MXL5XX 11 +#define DDB_CI_EXTERNAL_XO2 12 +#define DDB_CI_EXTERNAL_XO2_B 13 +#define DDB_TUNER_DVBS_STV0910_PR 14 +#define DDB_TUNER_DVBC2T2I_SONY_P 15 + +#define DDB_TUNER_XO2 32 +#define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0) +#define DDB_TUNER_DVBCT2_SONY (DDB_TUNER_XO2 + 1) +#define DDB_TUNER_ISDBT_SONY (DDB_TUNER_XO2 + 2) +#define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3) +#define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4) +#define DDB_TUNER_DVBC2T2I_SONY (DDB_TUNER_XO2 + 5) struct ddb_input *input[2]; struct ddb_output *output; struct dvb_ca_en50221 *en; + struct ddb_dvb dvb[2]; + u32 gap; + u32 obr; + u8 creg; +}; + +#define CM_STARTUP_DELAY 2 +#define CM_AVERAGE 20 +#define CM_GAIN 10 + +#define HW_LSB_SHIFT 12 +#define HW_LSB_MASK 0x1000 + +#define CM_IDLE 0 +#define CM_STARTUP 1 +#define CM_ADJUST 2 + +#define TS_CAPTURE_LEN (4096) + +struct ddb_link { + struct ddb *dev; + struct ddb_info *info; + u32 nr; + u32 regs; + spinlock_t lock; + struct mutex flash_mutex; + struct tasklet_struct tasklet; + struct ddb_ids ids; + + spinlock_t temp_lock; + int overtemperature_error; + u8 temp_tab[11]; }; struct ddb { struct pci_dev *pdev; + struct platform_device *pfdev; + struct device *dev; + + int msi; + struct workqueue_struct *wq; + u32 has_dma; + + struct ddb_link link[DDB_MAX_LINK]; unsigned char __iomem *regs; + u32 regs_len; + u32 port_num; struct ddb_port port[DDB_MAX_PORT]; + u32 i2c_num; struct ddb_i2c i2c[DDB_MAX_I2C]; struct ddb_input input[DDB_MAX_INPUT]; struct ddb_output output[DDB_MAX_OUTPUT]; + struct dvb_adapter adap[DDB_MAX_INPUT]; + struct ddb_dma idma[DDB_MAX_INPUT]; + struct ddb_dma odma[DDB_MAX_OUTPUT]; + + void (*handler[4][256])(unsigned long); + unsigned long handler_data[4][256]; struct device *ddb_dev; - int nr; + u32 ddb_dev_users; + u32 nr; u8 iobuf[1028]; - struct ddb_info *info; - int msi; + u8 leds; + u32 ts_irq; + u32 i2c_irq; + + struct mutex mutex; + + u8 tsbuf[TS_CAPTURE_LEN]; }; -/****************************************************************************/ +static inline u32 ddblreadl(struct ddb_link *link, u32 adr) +{ + return readl((char *) (link->dev->regs + (adr))); +} -#define ddbwritel(_val, _adr) writel((_val), \ - dev->regs+(_adr)) -#define ddbreadl(_adr) readl(dev->regs+(_adr)) -#define ddbcpyto(_adr, _src, _count) memcpy_toio(dev->regs+(_adr), (_src), (_count)) -#define ddbcpyfrom(_dst, _adr, _count) memcpy_fromio((_dst), dev->regs+(_adr), (_count)) +static inline void ddblwritel(struct ddb_link *link, u32 val, u32 adr) +{ + writel(val, (char *) (link->dev->regs + (adr))); +} -/****************************************************************************/ +static inline u32 ddbreadl(struct ddb *dev, u32 adr) +{ + return readl((char *) (dev->regs + (adr))); +} + +static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) +{ + writel(val, (char *) (dev->regs + (adr))); +} + +static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) +{ + return memcpy_toio((char *) (dev->regs + adr), src, count); +} + +static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) +{ + return memcpy_fromio(dst, (char *) (dev->regs + adr), count); +} static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) { - u32 val = ddbreadl(adr); + u32 val = ddbreadl(dev, adr); - /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ - if (val == ~0) { - dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); - return 0; - } + /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ + if (val == ~0) { + dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); + return 0; + } return val; } +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len); + /****************************************************************************/ /* ddbridge-main.c (modparams) */ +extern int adapter_alloc; +extern int msi; +extern int ci_bitrate; +extern int ts_loop; extern int xo2_speed; +extern int alt_dma; +extern int no_init; extern int stv0910_single; +extern struct workqueue_struct *ddb_wq; /* ddbridge-core.c */ +extern struct ddb_regmap octopus_map; void ddb_ports_detach(struct ddb *dev); void ddb_ports_release(struct ddb *dev); void ddb_buffers_free(struct ddb *dev); void ddb_device_destroy(struct ddb *dev); -irqreturn_t irq_handler(int irq, void *dev_id); +irqreturn_t ddb_irq_handler0(int irq, void *dev_id); +irqreturn_t ddb_irq_handler1(int irq, void *dev_id); +irqreturn_t ddb_irq_handler(int irq, void *dev_id); void ddb_ports_init(struct ddb *dev); int ddb_buffers_alloc(struct ddb *dev); int ddb_ports_attach(struct ddb *dev); int ddb_device_create(struct ddb *dev); int ddb_class_create(void); void ddb_class_destroy(void); +int ddb_init(struct ddb *dev); -#endif +#endif /* DDBRIDGE_H */ -- cgit v1.2.3 From 14e27a106566aeb74b09117dbc073f210f27ffde Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:53 -0400 Subject: media: ddbridge: split I/O related functions off from ddbridge.h While it seems valid that headers can carry simple oneline static inline annotated functions, move them into their own header file to have the overall code more readable. Also, keep them as header (and don't put in a separate object) and static inline to help the compiler avoid generating function calls. (Thanks to Jasmin J. for valuable input on this!) Cc: Jasmin J. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 1 + drivers/media/pci/ddbridge/ddbridge-i2c.c | 1 + drivers/media/pci/ddbridge/ddbridge-io.h | 71 ++++++++++++++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge-main.c | 1 + drivers/media/pci/ddbridge/ddbridge.h | 43 ------------------ 5 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-io.h (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 6cda798a80a4..de73b74a7afc 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -37,6 +37,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" #include "tda18271c2dd.h" #include "stv6110x.h" diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c index 376d8a7ca0b9..3d4fafb5db27 100644 --- a/drivers/media/pci/ddbridge/ddbridge-i2c.c +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -33,6 +33,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" /******************************************************************************/ diff --git a/drivers/media/pci/ddbridge/ddbridge-io.h b/drivers/media/pci/ddbridge/ddbridge-io.h new file mode 100644 index 000000000000..ce92e9484075 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-io.h @@ -0,0 +1,71 @@ +/* + * ddbridge-io.h: Digital Devices bridge I/O inline functions + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __DDBRIDGE_IO_H__ +#define __DDBRIDGE_IO_H__ + +#include + +#include "ddbridge.h" + +/******************************************************************************/ + +static inline u32 ddblreadl(struct ddb_link *link, u32 adr) +{ + return readl((char *) (link->dev->regs + (adr))); +} + +static inline void ddblwritel(struct ddb_link *link, u32 val, u32 adr) +{ + writel(val, (char *) (link->dev->regs + (adr))); +} + +static inline u32 ddbreadl(struct ddb *dev, u32 adr) +{ + return readl((char *) (dev->regs + (adr))); +} + +static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) +{ + writel(val, (char *) (dev->regs + (adr))); +} + +static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) +{ + return memcpy_toio((char *) (dev->regs + adr), src, count); +} + +static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) +{ + return memcpy_fromio(dst, (char *) (dev->regs + adr), count); +} + +static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) +{ + u32 val = ddbreadl(dev, adr); + + /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ + if (val == ~0) { + dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); + return 0; + } + + return val; +} + +#endif /* __DDBRIDGE_IO_H__ */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 73b041118bbf..d06543bbc393 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -35,6 +35,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" /****************************************************************************/ /* module parameters */ diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 65b3f6b38bd7..4b78b01cc0a8 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -349,49 +349,6 @@ struct ddb { u8 tsbuf[TS_CAPTURE_LEN]; }; -static inline u32 ddblreadl(struct ddb_link *link, u32 adr) -{ - return readl((char *) (link->dev->regs + (adr))); -} - -static inline void ddblwritel(struct ddb_link *link, u32 val, u32 adr) -{ - writel(val, (char *) (link->dev->regs + (adr))); -} - -static inline u32 ddbreadl(struct ddb *dev, u32 adr) -{ - return readl((char *) (dev->regs + (adr))); -} - -static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) -{ - writel(val, (char *) (dev->regs + (adr))); -} - -static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) -{ - return memcpy_toio((char *) (dev->regs + adr), src, count); -} - -static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) -{ - return memcpy_fromio(dst, (char *) (dev->regs + adr), count); -} - -static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) -{ - u32 val = ddbreadl(dev, adr); - - /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */ - if (val == ~0) { - dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr); - return 0; - } - - return val; -} - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ -- cgit v1.2.3 From 69716934c7c5fdaf057dcbdb75da75d067f10e60 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:54 -0400 Subject: media: ddbridge: split off hardware definitions and mappings Further cleanup of ddbridge-core and ddbridge-main, and moves all such hw definitions into one single place, making things easier to maintain. Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/Makefile | 3 +- drivers/media/pci/ddbridge/ddbridge-core.c | 68 ------- drivers/media/pci/ddbridge/ddbridge-hw.c | 299 +++++++++++++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge-hw.h | 52 +++++ drivers/media/pci/ddbridge/ddbridge-main.c | 217 +-------------------- drivers/media/pci/ddbridge/ddbridge.h | 1 - 6 files changed, 354 insertions(+), 286 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-hw.c create mode 100644 drivers/media/pci/ddbridge/ddbridge-hw.h (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index fe8ff0c681ad..3ef3048a89ac 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -2,7 +2,8 @@ # Makefile for the ddbridge device driver # -ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-i2c.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \ + ddbridge-i2c.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index de73b74a7afc..bbd8d556175b 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -67,74 +67,6 @@ static struct ddb *ddbs[DDB_MAX_ADAPTER]; /****************************************************************************/ /****************************************************************************/ -static struct ddb_regset octopus_input = { - .base = 0x200, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_output = { - .base = 0x280, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_idma = { - .base = 0x300, - .num = 0x08, - .size = 0x10, -}; - -static struct ddb_regset octopus_idma_buf = { - .base = 0x2000, - .num = 0x08, - .size = 0x100, -}; - -static struct ddb_regset octopus_odma = { - .base = 0x380, - .num = 0x04, - .size = 0x10, -}; - -static struct ddb_regset octopus_odma_buf = { - .base = 0x2800, - .num = 0x04, - .size = 0x100, -}; - -static struct ddb_regset octopus_i2c = { - .base = 0x80, - .num = 0x04, - .size = 0x20, -}; - -static struct ddb_regset octopus_i2c_buf = { - .base = 0x1000, - .num = 0x04, - .size = 0x200, -}; - -/****************************************************************************/ - -struct ddb_regmap octopus_map = { - .irq_base_i2c = 0, - .irq_base_idma = 8, - .irq_base_odma = 16, - .i2c = &octopus_i2c, - .i2c_buf = &octopus_i2c_buf, - .idma = &octopus_idma, - .idma_buf = &octopus_idma_buf, - .odma = &octopus_odma, - .odma_buf = &octopus_odma_buf, - .input = &octopus_input, - .output = &octopus_output, -}; - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - static void ddb_set_dma_table(struct ddb_io *io) { struct ddb *dev = io->port->dev; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c new file mode 100644 index 000000000000..e35b41e8d860 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -0,0 +1,299 @@ +/* + * ddbridge-hw.c: Digital Devices bridge hardware maps + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "ddbridge.h" + +/******************************************************************************/ + +static struct ddb_regset octopus_input = { + .base = 0x200, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_output = { + .base = 0x280, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_idma = { + .base = 0x300, + .num = 0x08, + .size = 0x10, +}; + +static struct ddb_regset octopus_idma_buf = { + .base = 0x2000, + .num = 0x08, + .size = 0x100, +}; + +static struct ddb_regset octopus_odma = { + .base = 0x380, + .num = 0x04, + .size = 0x10, +}; + +static struct ddb_regset octopus_odma_buf = { + .base = 0x2800, + .num = 0x04, + .size = 0x100, +}; + +static struct ddb_regset octopus_i2c = { + .base = 0x80, + .num = 0x04, + .size = 0x20, +}; + +static struct ddb_regset octopus_i2c_buf = { + .base = 0x1000, + .num = 0x04, + .size = 0x200, +}; + +/****************************************************************************/ + +static struct ddb_regmap octopus_map = { + .irq_base_i2c = 0, + .irq_base_idma = 8, + .irq_base_odma = 16, + .i2c = &octopus_i2c, + .i2c_buf = &octopus_i2c_buf, + .idma = &octopus_idma, + .idma_buf = &octopus_idma_buf, + .odma = &octopus_odma, + .odma_buf = &octopus_odma_buf, + .input = &octopus_input, + .output = &octopus_output, +}; + +/****************************************************************************/ + +const struct ddb_info ddb_none = { + .type = DDB_NONE, + .name = "unknown Digital Devices PCIe card, install newer driver", + .regmap = &octopus_map, +}; + +const struct ddb_info ddb_octopus = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, +}; + +const struct ddb_info ddb_octopusv3 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus V3 DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, +}; + +const struct ddb_info ddb_octopus_le = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus LE DVB adapter", + .regmap = &octopus_map, + .port_num = 2, + .i2c_mask = 0x03, +}; + +const struct ddb_info ddb_octopus_oem = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus OEM", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .led_num = 1, + .fan_num = 1, + .temp_num = 1, + .temp_bus = 0, +}; + +const struct ddb_info ddb_octopus_mini = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Octopus Mini", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, +}; + +const struct ddb_info ddb_v6 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V6 DVB adapter", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x07, +}; + +const struct ddb_info ddb_v6_5 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V6.5 DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, +}; + +const struct ddb_info ddb_v7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + +const struct ddb_info ddb_v7a = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + +const struct ddb_info ddb_ctv7 = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine CT V7 DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 3, + .board_control_2 = 4, +}; + +const struct ddb_info ddb_satixS2v3 = { + .type = DDB_OCTOPUS, + .name = "Mystique SaTiX-S2 V3 DVB adapter", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x07, +}; + +const struct ddb_info ddb_ci = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x03, +}; + +const struct ddb_info ddb_cis = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI single", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x03, +}; + +const struct ddb_info ddb_ci_s2_pro = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI S2 Pro", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 2, + .board_control_2 = 4, +}; + +const struct ddb_info ddb_ci_s2_pro_a = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI S2 Pro Advanced", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 2, + .board_control_2 = 4, +}; + +const struct ddb_info ddb_dvbct = { + .type = DDB_OCTOPUS, + .name = "Digital Devices DVBCT V6.1 DVB adapter", + .regmap = &octopus_map, + .port_num = 3, + .i2c_mask = 0x07, +}; + +/****************************************************************************/ + +const struct ddb_info ddb_ct2_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 CT2", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, +}; + +const struct ddb_info ddb_c2t2_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, +}; + +const struct ddb_info ddb_isdbt_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 ISDBT", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, +}; + +const struct ddb_info ddb_c2t2i_v0_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2I V0", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, + .tempmon_irq = 24, +}; + +const struct ddb_info ddb_c2t2i_8 = { + .type = DDB_OCTOPUS_MAX_CT, + .name = "Digital Devices MAX A8 C2T2I", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 0x0ff, + .board_control_2 = 0xf00, + .ts_quirks = TS_QUIRK_SERIAL, + .tempmon_irq = 24, +}; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.h b/drivers/media/pci/ddbridge/ddbridge-hw.h new file mode 100644 index 000000000000..bd52c083c4a5 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-hw.h @@ -0,0 +1,52 @@ +/* + * ddbridge-hw.h: Digital Devices bridge hardware maps + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DDBRIDGE_HW_H_ +#define _DDBRIDGE_HW_H_ + +#include "ddbridge.h" + +/******************************************************************************/ + +extern const struct ddb_info ddb_none; +extern const struct ddb_info ddb_octopus; +extern const struct ddb_info ddb_octopusv3; +extern const struct ddb_info ddb_octopus_le; +extern const struct ddb_info ddb_octopus_oem; +extern const struct ddb_info ddb_octopus_mini; +extern const struct ddb_info ddb_v6; +extern const struct ddb_info ddb_v6_5; +extern const struct ddb_info ddb_v7; +extern const struct ddb_info ddb_v7a; +extern const struct ddb_info ddb_ctv7; +extern const struct ddb_info ddb_satixS2v3; +extern const struct ddb_info ddb_ci; +extern const struct ddb_info ddb_cis; +extern const struct ddb_info ddb_ci_s2_pro; +extern const struct ddb_info ddb_ci_s2_pro_a; +extern const struct ddb_info ddb_dvbct; + +/****************************************************************************/ + +extern const struct ddb_info ddb_ct2_8; +extern const struct ddb_info ddb_c2t2_8; +extern const struct ddb_info ddb_isdbt_8; +extern const struct ddb_info ddb_c2t2i_v0_8; +extern const struct ddb_info ddb_c2t2i_8; + +#endif /* _DDBRIDGE_HW_H */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index d06543bbc393..420335f4b7bf 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -35,6 +35,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-hw.h" #include "ddbridge-io.h" /****************************************************************************/ @@ -278,222 +279,6 @@ fail: /****************************************************************************/ /****************************************************************************/ -static const struct ddb_info ddb_none = { - .type = DDB_NONE, - .name = "unknown Digital Devices PCIe card, install newer driver", - .regmap = &octopus_map, -}; - -static const struct ddb_info ddb_octopus = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, -}; - -static const struct ddb_info ddb_octopusv3 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus V3 DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, -}; - -static const struct ddb_info ddb_octopus_le = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus LE DVB adapter", - .regmap = &octopus_map, - .port_num = 2, - .i2c_mask = 0x03, -}; - -static const struct ddb_info ddb_octopus_oem = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus OEM", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .led_num = 1, - .fan_num = 1, - .temp_num = 1, - .temp_bus = 0, -}; - -static const struct ddb_info ddb_octopus_mini = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Octopus Mini", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, -}; - -static const struct ddb_info ddb_v6 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V6 DVB adapter", - .regmap = &octopus_map, - .port_num = 3, - .i2c_mask = 0x07, -}; - -static const struct ddb_info ddb_v6_5 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V6.5 DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, -}; - -static const struct ddb_info ddb_v7 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V7 DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 2, - .board_control_2 = 4, - .ts_quirks = TS_QUIRK_REVERSED, -}; - -static const struct ddb_info ddb_v7a = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 2, - .board_control_2 = 4, - .ts_quirks = TS_QUIRK_REVERSED, -}; - -static const struct ddb_info ddb_ctv7 = { - .type = DDB_OCTOPUS, - .name = "Digital Devices Cine CT V7 DVB adapter", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 3, - .board_control_2 = 4, -}; - -static const struct ddb_info ddb_satixS2v3 = { - .type = DDB_OCTOPUS, - .name = "Mystique SaTiX-S2 V3 DVB adapter", - .regmap = &octopus_map, - .port_num = 3, - .i2c_mask = 0x07, -}; - -static const struct ddb_info ddb_ci = { - .type = DDB_OCTOPUS_CI, - .name = "Digital Devices Octopus CI", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x03, -}; - -static const struct ddb_info ddb_cis = { - .type = DDB_OCTOPUS_CI, - .name = "Digital Devices Octopus CI single", - .regmap = &octopus_map, - .port_num = 3, - .i2c_mask = 0x03, -}; - -static const struct ddb_info ddb_ci_s2_pro = { - .type = DDB_OCTOPUS_CI, - .name = "Digital Devices Octopus CI S2 Pro", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x01, - .board_control = 2, - .board_control_2 = 4, -}; - -static const struct ddb_info ddb_ci_s2_pro_a = { - .type = DDB_OCTOPUS_CI, - .name = "Digital Devices Octopus CI S2 Pro Advanced", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x01, - .board_control = 2, - .board_control_2 = 4, -}; - -static const struct ddb_info ddb_dvbct = { - .type = DDB_OCTOPUS, - .name = "Digital Devices DVBCT V6.1 DVB adapter", - .regmap = &octopus_map, - .port_num = 3, - .i2c_mask = 0x07, -}; - -/****************************************************************************/ - -static struct ddb_info ddb_ct2_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 CT2", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, - .tempmon_irq = 24, -}; - -static struct ddb_info ddb_c2t2_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, - .tempmon_irq = 24, -}; - -static struct ddb_info ddb_isdbt_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 ISDBT", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, - .tempmon_irq = 24, -}; - -static struct ddb_info ddb_c2t2i_v0_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2I V0", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, - .tempmon_irq = 24, -}; - -static struct ddb_info ddb_c2t2i_8 = { - .type = DDB_OCTOPUS_MAX_CT, - .name = "Digital Devices MAX A8 C2T2I", - .regmap = &octopus_map, - .port_num = 4, - .i2c_mask = 0x0f, - .board_control = 0x0ff, - .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, - .tempmon_irq = 24, -}; - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - #define DDVID 0xdd01 /* Digital Devices Vendor ID */ #define DDB_DEVICE(_device, _subdevice, _driver_data) { \ diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 4b78b01cc0a8..6deff529e0ba 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -369,7 +369,6 @@ extern int stv0910_single; extern struct workqueue_struct *ddb_wq; /* ddbridge-core.c */ -extern struct ddb_regmap octopus_map; void ddb_ports_detach(struct ddb *dev); void ddb_ports_release(struct ddb *dev); void ddb_buffers_free(struct ddb *dev); -- cgit v1.2.3 From e89e02a8654f3510114c72394753ab4977b754b3 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:55 -0400 Subject: media: ddbridge: check pointers before dereferencing Fixes two warnings reported by smatch: drivers/media/pci/ddbridge/ddbridge-core.c:240 ddb_redirect() warn: variable dereferenced before check 'idev' (see line 238) drivers/media/pci/ddbridge/ddbridge-core.c:240 ddb_redirect() warn: variable dereferenced before check 'pdev' (see line 238) Fixed by moving the existing checks up before accessing members. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index bbd8d556175b..d7bf01f38d98 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -170,10 +170,10 @@ static int ddb_redirect(u32 i, u32 p) struct ddb *pdev = ddbs[(p >> 4) & 0x3f]; struct ddb_port *port; - if (!idev->has_dma || !pdev->has_dma) - return -EINVAL; if (!idev || !pdev) return -EINVAL; + if (!idev->has_dma || !pdev->has_dma) + return -EINVAL; port = &pdev->port[p & 0x0f]; if (!port->output) -- cgit v1.2.3 From f597f2a8fce27b067ed5ad58314bdfbb219d2ffe Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:56 -0400 Subject: media: ddbridge: only register frontends in fe2 if fe is not NULL Smatch reported: drivers/media/pci/ddbridge/ddbridge-core.c:1602 dvb_input_attach() error: we previously assumed 'dvb->fe' could be null (see line 1595) dvb->fe2 will ever only be populated when dvb->fe is set. So only handle registration of dvb->fe2 when dvb->fe got set beforehand by moving the registration into the "if (dvb->fe)" conditional. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index d7bf01f38d98..759a53e82252 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1506,23 +1506,25 @@ static int dvb_input_attach(struct ddb_input *input) return 0; } dvb->attached = 0x30; + if (dvb->fe) { if (dvb_register_frontend(adap, dvb->fe) < 0) return -ENODEV; + + if (dvb->fe2) { + if (dvb_register_frontend(adap, dvb->fe2) < 0) + return -ENODEV; + dvb->fe2->tuner_priv = dvb->fe->tuner_priv; + memcpy(&dvb->fe2->ops.tuner_ops, + &dvb->fe->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } } - if (dvb->fe2) { - if (dvb_register_frontend(adap, dvb->fe2) < 0) - return -ENODEV; - dvb->fe2->tuner_priv = dvb->fe->tuner_priv; - memcpy(&dvb->fe2->ops.tuner_ops, - &dvb->fe->ops.tuner_ops, - sizeof(struct dvb_tuner_ops)); - } + dvb->attached = 0x31; return 0; } - static int port_has_encti(struct ddb_port *port) { struct device *dev = port->dev->dev; -- cgit v1.2.3 From 8ac9fd4348677cb2ead6776b9f8042c952a3f67c Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:57 -0400 Subject: media: ddbridge: fix possible buffer overflow in ddb_ports_init() Report from smatch: drivers/media/pci/ddbridge/ddbridge-core.c:2659 ddb_ports_init() error: buffer overflow 'dev->port' 32 <= u32max Fix by making sure "p" is greater than zero before checking for "dev->port[].type == DDB_CI_EXTERNAL_XO2". Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 759a53e82252..5df942f4e388 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2551,7 +2551,7 @@ void ddb_ports_init(struct ddb *dev) port->dvb[0].adap = &dev->adap[2 * p]; port->dvb[1].adap = &dev->adap[2 * p + 1]; - if ((port->class == DDB_PORT_NONE) && i && + if ((port->class == DDB_PORT_NONE) && i && p && dev->port[p - 1].type == DDB_CI_EXTERNAL_XO2) { port->class = DDB_PORT_CI; port->type = DDB_CI_EXTERNAL_XO2_B; -- cgit v1.2.3 From 1bdafdf02711c18b54e4d981b96dc0abe9503668 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:58 -0400 Subject: media: ddbridge: remove unreachable code >From smatch: drivers/media/pci/ddbridge/ddbridge-core.c:3490 snr_store() info: ignoring unreachable code. In fact, the function immediately returns zero, so remove it and update ddb_attrs_snr[] to not reference it anymore. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 5df942f4e388..747f3b317fb9 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -3092,25 +3092,6 @@ static ssize_t snr_show(struct device *device, return sprintf(buf, "%s\n", snr); } - -static ssize_t snr_store(struct device *device, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ddb *dev = dev_get_drvdata(device); - int num = attr->attr.name[3] - 0x30; - u8 snr[34] = { 0x01, 0x00 }; - - return 0; /* NOE: remove completely? */ - if (count > 31) - return -EINVAL; - if (dev->port[num].type >= DDB_TUNER_XO2) - return -EINVAL; - memcpy(snr + 2, buf, count); - i2c_write(&dev->i2c[num].adap, 0x57, snr, 34); - i2c_write(&dev->i2c[num].adap, 0x50, snr, 34); - return count; -} - static ssize_t bsnr_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -3250,10 +3231,10 @@ static struct device_attribute ddb_attrs_fan[] = { }; static struct device_attribute ddb_attrs_snr[] = { - __ATTR(snr0, 0664, snr_show, snr_store), - __ATTR(snr1, 0664, snr_show, snr_store), - __ATTR(snr2, 0664, snr_show, snr_store), - __ATTR(snr3, 0664, snr_show, snr_store), + __ATTR_MRO(snr0, snr_show), + __ATTR_MRO(snr1, snr_show), + __ATTR_MRO(snr2, snr_show), + __ATTR_MRO(snr3, snr_show), }; static struct device_attribute ddb_attrs_ctemp[] = { -- cgit v1.2.3 From adb57f60ace633f1ac78cd4e90b7381a9b5abd12 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:55:59 -0400 Subject: media: ddbridge: fix impossible condition warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Smatch and gcc complained: drivers/media/pci/ddbridge/ddbridge-core.c:3491 bpsnr_show() warn: impossible condition '(snr[0] == 255) => ((-128)-127 == 255)' drivers/media/pci/ddbridge/ddbridge-core.c: In function ‘bpsnr_show’: drivers/media/pci/ddbridge/ddbridge-core.c:3491:13: warning: comparison is always false due to limited range of data type [-Wtype-limits] Fix this by changing the type of snr to unsigned char. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 747f3b317fb9..66b520d131a0 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -3107,7 +3107,7 @@ static ssize_t bpsnr_show(struct device *device, struct device_attribute *attr, char *buf) { struct ddb *dev = dev_get_drvdata(device); - char snr[32]; + unsigned char snr[32]; if (!dev->i2c_num) return 0; -- cgit v1.2.3 From fc3fb43e41a15a3508f919a825c186c6e5a22404 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:56:00 -0400 Subject: media: ddbridge: fix dereference before check Both ts_release() and ts_open() can use "output" before check (smatch): drivers/media/pci/ddbridge/ddbridge-core.c:816 ts_release() warn: variable dereferenced before check 'output' (see line 809) drivers/media/pci/ddbridge/ddbridge-core.c:836 ts_open() warn: variable dereferenced before check 'output' (see line 828) Fix by performing checks on those pointers. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 66b520d131a0..e051a691eb42 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -738,8 +738,13 @@ static unsigned int ts_poll(struct file *file, poll_table *wait) static int ts_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; + struct ddb_output *output = NULL; + struct ddb_input *input = NULL; + + if (dvbdev) { + output = dvbdev->priv; + input = output->port->input[0]; + } if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (!input) @@ -757,8 +762,13 @@ static int ts_open(struct inode *inode, struct file *file) { int err; struct dvb_device *dvbdev = file->private_data; - struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; + struct ddb_output *output = NULL; + struct ddb_input *input = NULL; + + if (dvbdev) { + output = dvbdev->priv; + input = output->port->input[0]; + } if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (!input) -- cgit v1.2.3 From adaf4df70521e656c38ace740f1d98096825a430 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sat, 12 Aug 2017 07:56:01 -0400 Subject: media: ddbridge: Kconfig option to control the MSI modparam default It is known that MSI interrupts - while working quite well so far - can still cause issues on some hardware platforms (causing I2C timeouts due to unhandled interrupts). The msi variable/option is set to 1 by default. So, add a Kconfig option prefixed with "EXPERIMENTAL" that will control the default value of that modparam, defaulting to off for a better user experience and (guaranteed) stable operation "per default". Cc: Ralph Metzler Signed-off-by: Daniel Scheller Tested-by: Richard Scobie Tested-by: Jasmin Jessich Tested-by: Dietmar Spingler Tested-by: Manfred Knick Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/Kconfig | 15 +++++++++++++++ drivers/media/pci/ddbridge/ddbridge-main.c | 11 +++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index c79a58fa5fc3..1330b2ecc72a 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -26,3 +26,18 @@ config DVB_DDBRIDGE - CineS2 V7/V7A and DuoFlex S2 V4 (ST STV0910-based) Say Y if you own such a card and want to use it. + +config DVB_DDBRIDGE_MSIENABLE + bool "Enable Message Signaled Interrupts (MSI) per default (EXPERIMENTAL)" + depends on DVB_DDBRIDGE + depends on PCI_MSI + default n + ---help--- + Use PCI MSI (Message Signaled Interrupts) per default. Enabling this + might lead to I2C errors originating from the bridge in conjunction + with certain SATA controllers, requiring a reload of the ddbridge + module. MSI can still be disabled by passing msi=0 as option, as + this will just change the msi option default value. + + If you're unsure, concerned about stability and don't want to pass + module options in case of troubles, say N. diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 420335f4b7bf..181d5f17fe91 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -47,10 +47,17 @@ MODULE_PARM_DESC(adapter_alloc, "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); #ifdef CONFIG_PCI_MSI +#ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE int msi = 1; +#else +int msi; +#endif module_param(msi, int, 0444); -MODULE_PARM_DESC(msi, - " Control MSI interrupts: 0-disable, 1-enable (default)"); +#ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE +MODULE_PARM_DESC(msi, "Control MSI interrupts: 0-disable, 1-enable (default)"); +#else +MODULE_PARM_DESC(msi, "Control MSI interrupts: 0-disable (default), 1-enable"); +#endif #endif int ci_bitrate = 70000; -- cgit v1.2.3 From 399196ed0643c1067e19bb116e05608d3d5ecff3 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:09 -0400 Subject: media: dvb-frontends/stv0910: fix STR assignment, remove unneeded var According to the documentation, FE_SCALE_DECIBEL values should be assigned to .svalue and not .uvalue, so let's do this. While at it, remove the unneeded strength var from read_signal_strength(). Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 7e8a460449c5..b596ec5f309f 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1321,7 +1321,6 @@ static void read_signal_strength(struct dvb_frontend *fe) { struct stv *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; - s64 strength; u8 reg[2]; u16 agc; s32 padc, power = 0; @@ -1341,10 +1340,8 @@ static void read_signal_strength(struct dvb_frontend *fe) padc = table_lookup(padc_lookup, ARRAY_SIZE(padc_lookup), power) + 352; - strength = (padc - agc); - p->strength.stat[0].scale = FE_SCALE_DECIBEL; - p->strength.stat[0].uvalue = strength; + p->strength.stat[0].svalue = (padc - agc); } static int read_status(struct dvb_frontend *fe, enum fe_status *status) -- cgit v1.2.3 From 448461af0e19ca2cc91694f41735c87854df4dd9 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:10 -0400 Subject: media: dvb-frontends/stv0910: implement diseqc_send_burst This implements the diseqc_send_burst frontend op to support sending mini-DISEQC bursts. Picked up from dddvb's driver package where this specific block was disabled via #if 0/#endif, but is still working according to feedback from upstream, so add it. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index b596ec5f309f..17c7170d9db9 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1638,6 +1638,27 @@ static int send_master_cmd(struct dvb_frontend *fe, return 0; } +static int send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) +{ + struct stv *state = fe->demodulator_priv; + u16 offs = state->nr ? 0x40 : 0; + u8 value; + + if (burst == SEC_MINI_A) { + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3F); + value = 0x00; + } else { + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); + value = 0xFF; + } + wait_dis(state, 0x40, 0x00); + write_reg(state, RSTV0910_P1_DISTXFIFO + offs, value); + write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); + wait_dis(state, 0x20, 0x20); + + return 0; +} + static int sleep(struct dvb_frontend *fe) { struct stv *state = fe->demodulator_priv; @@ -1673,6 +1694,7 @@ static struct dvb_frontend_ops stv0910_ops = { .set_tone = set_tone, .diseqc_send_master_cmd = send_master_cmd, + .diseqc_send_burst = send_burst, }; static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) -- cgit v1.2.3 From ddb6a90dcd008c35b2c9a71a97eab69dc4c04b10 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:11 -0400 Subject: media: dvb-frontends/stv0910: further coding style cleanup Fixes up all remainders reported by "checkpatch.pl --strict" Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 93 +++++++++++++++++------------------ drivers/media/dvb-frontends/stv0910.h | 4 +- 2 files changed, 48 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 17c7170d9db9..a0eb4374fe85 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -71,7 +71,7 @@ static inline u32 muldiv32(u32 a, u32 b, u32 c) tmp64 = (u64)a * (u64)b; do_div(tmp64, c); - return (u32) tmp64; + return (u32)tmp64; } struct stv_base { @@ -79,8 +79,8 @@ struct stv_base { u8 adr; struct i2c_adapter *i2c; - struct mutex i2c_lock; - struct mutex reg_lock; + struct mutex i2c_lock; /* shared I2C access protect */ + struct mutex reg_lock; /* shared register write protect */ int count; u32 extclk; @@ -146,8 +146,8 @@ static inline int i2c_write(struct i2c_adapter *adap, u8 adr, if (i2c_transfer(adap, &msg, 1) != 1) { dev_warn(&adap->dev, "i2c write error ([%02x] %04x: %02x)\n", - adr, (data[0] << 8) | data[1], - (len > 2 ? data[2] : 0)); + adr, (data[0] << 8) | data[1], + (len > 2 ? data[2] : 0)); return -EREMOTEIO; } return 0; @@ -166,7 +166,7 @@ static int write_reg(struct stv *state, u16 reg, u8 val) } static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, - u16 reg, u8 *val, int count) + u16 reg, u8 *val, int count) { u8 msg[2] = {reg >> 8, reg & 0xff}; struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, @@ -176,7 +176,7 @@ static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, if (i2c_transfer(adapter, msgs, 2) != 2) { dev_warn(&adapter->dev, "i2c read error ([%02x] %04x)\n", - adr, reg); + adr, reg); return -EREMOTEIO; } return 0; @@ -185,7 +185,7 @@ static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr, static int read_reg(struct stv *state, u16 reg, u8 *val) { return i2c_read_regs16(state->base->i2c, state->base->adr, - reg, val, 1); + reg, val, 1); } static int read_regs(struct stv *state, u16 reg, u8 *val, int len) @@ -473,16 +473,16 @@ static int get_cur_symbol_rate(struct stv *state, u32 *p_symbol_rate) read_reg(state, RSTV0910_P2_TMGREG1 + state->regoff, &tim_offs1); read_reg(state, RSTV0910_P2_TMGREG0 + state->regoff, &tim_offs0); - symbol_rate = ((u32) symb_freq3 << 24) | ((u32) symb_freq2 << 16) | - ((u32) symb_freq1 << 8) | (u32) symb_freq0; - timing_offset = ((u32) tim_offs2 << 16) | ((u32) tim_offs1 << 8) | - (u32) tim_offs0; + symbol_rate = ((u32)symb_freq3 << 24) | ((u32)symb_freq2 << 16) | + ((u32)symb_freq1 << 8) | (u32)symb_freq0; + timing_offset = ((u32)tim_offs2 << 16) | ((u32)tim_offs1 << 8) | + (u32)tim_offs0; - if ((timing_offset & (1<<23)) != 0) + if ((timing_offset & (1 << 23)) != 0) timing_offset |= 0xFF000000; /* Sign extent */ - symbol_rate = (u32) (((u64) symbol_rate * state->base->mclk) >> 32); - timing_offset = (s32) (((s64) symbol_rate * (s64) timing_offset) >> 29); + symbol_rate = (u32)(((u64)symbol_rate * state->base->mclk) >> 32); + timing_offset = (s32)(((s64)symbol_rate * (s64)timing_offset) >> 29); *p_symbol_rate = symbol_rate + timing_offset; @@ -498,9 +498,9 @@ static int get_signal_parameters(struct stv *state) if (state->receive_mode == RCVMODE_DVBS2) { read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); - state->mod_cod = (enum fe_stv0910_mod_cod) ((tmp & 0x7c) >> 2); + state->mod_cod = (enum fe_stv0910_mod_cod)((tmp & 0x7c) >> 2); state->pilots = (tmp & 0x01) != 0; - state->fectype = (enum dvbs2_fectype) ((tmp & 0x02) >> 1); + state->fectype = (enum dvbs2_fectype)((tmp & 0x02) >> 1); } else if (state->receive_mode == RCVMODE_DVBS) { read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); @@ -586,7 +586,7 @@ static int tracking_optimization(struct stv *state) } static s32 table_lookup(struct slookup *table, - int table_size, u32 reg_value) + int table_size, u32 reg_value) { s32 value; int imin = 0; @@ -595,15 +595,15 @@ static s32 table_lookup(struct slookup *table, s32 reg_diff; /* Assumes Table[0].RegValue > Table[imax].RegValue */ - if (reg_value >= table[0].reg_value) + if (reg_value >= table[0].reg_value) { value = table[0].value; - else if (reg_value <= table[imax].reg_value) + } else if (reg_value <= table[imax].reg_value) { value = table[imax].value; - else { - while (imax-imin > 1) { + } else { + while ((imax - imin) > 1) { i = (imax + imin) / 2; if ((table[imin].reg_value >= reg_value) && - (reg_value >= table[i].reg_value)) + (reg_value >= table[i].reg_value)) imax = i; else imin = i; @@ -649,13 +649,13 @@ static int get_signal_to_noise(struct stv *state, s32 *signal_to_noise) n_lookup = ARRAY_SIZE(s1_sn_lookup); lookup = s1_sn_lookup; } - data = (((u16)data1) << 8) | (u16) data0; + data = (((u16)data1) << 8) | (u16)data0; *signal_to_noise = table_lookup(lookup, n_lookup, data); return 0; } static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, - u32 *berdenominator) + u32 *berdenominator) { u8 regs[3]; @@ -669,8 +669,8 @@ static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, if ((regs[0] & 0x80) == 0) { state->last_berdenominator = 1 << ((state->berscale * 2) + 10 + 3); - state->last_bernumerator = ((u32) (regs[0] & 0x7F) << 16) | - ((u32) regs[1] << 8) | regs[2]; + state->last_bernumerator = ((u32)(regs[0] & 0x7F) << 16) | + ((u32)regs[1] << 8) | regs[2]; if (state->last_bernumerator < 256 && state->berscale < 6) { state->berscale += 1; status = write_reg(state, RSTV0910_P2_ERRCTRL1 + @@ -730,7 +730,7 @@ static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) } static int get_bit_error_rate_s2(struct stv *state, u32 *bernumerator, - u32 *berdenominator) + u32 *berdenominator) { u8 regs[3]; @@ -742,11 +742,11 @@ static int get_bit_error_rate_s2(struct stv *state, u32 *bernumerator, if ((regs[0] & 0x80) == 0) { state->last_berdenominator = - dvbs2_nbch((enum dvbs2_mod_cod) state->mod_cod, + dvbs2_nbch((enum dvbs2_mod_cod)state->mod_cod, state->fectype) << (state->berscale * 2); - state->last_bernumerator = (((u32) regs[0] & 0x7F) << 16) | - ((u32) regs[1] << 8) | regs[2]; + state->last_bernumerator = (((u32)regs[0] & 0x7F) << 16) | + ((u32)regs[1] << 8) | regs[2]; if (state->last_bernumerator < 256 && state->berscale < 6) { state->berscale += 1; write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, @@ -764,7 +764,7 @@ static int get_bit_error_rate_s2(struct stv *state, u32 *bernumerator, } static int get_bit_error_rate(struct stv *state, u32 *bernumerator, - u32 *berdenominator) + u32 *berdenominator) { *bernumerator = 0; *berdenominator = 1; @@ -1211,7 +1211,6 @@ static int probe(struct stv *state) return 0; } - static int gate_ctrl(struct dvb_frontend *fe, int enable) { struct stv *state = fe->demodulator_priv; @@ -1273,9 +1272,9 @@ static int manage_matype_info(struct stv *state) u8 bbheader[2]; read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff, - bbheader, 2); + bbheader, 2); state->feroll_off = - (enum fe_stv0910_roll_off) (bbheader[0] & 0x03); + (enum fe_stv0910_roll_off)(bbheader[0] & 0x03); state->is_vcm = (bbheader[0] & 0x10) == 0; state->is_standard_broadcast = (bbheader[0] & 0xFC) == 0xF0; } else if (state->receive_mode == RCVMODE_DVBS) { @@ -1295,8 +1294,9 @@ static int read_snr(struct dvb_frontend *fe) if (!get_signal_to_noise(state, &snrval)) { p->cnr.stat[0].scale = FE_SCALE_DECIBEL; p->cnr.stat[0].uvalue = 100 * snrval; /* fix scale */ - } else + } else { p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } return 0; } @@ -1328,12 +1328,12 @@ static void read_signal_strength(struct dvb_frontend *fe) read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, reg, 2); - agc = (((u32) reg[0]) << 8) | reg[1]; + agc = (((u32)reg[0]) << 8) | reg[1]; for (i = 0; i < 5; i += 1) { read_regs(state, RSTV0910_P2_POWERI + state->regoff, reg, 2); - power += (u32) reg[0] * (u32) reg[0] - + (u32) reg[1] * (u32) reg[1]; + power += (u32)reg[0] * (u32)reg[0] + + (u32)reg[1] * (u32)reg[1]; usleep_range(3000, 4000); } power /= 5; @@ -1490,9 +1490,9 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; /* read ber */ - if (*status & FE_HAS_VITERBI) + if (*status & FE_HAS_VITERBI) { read_ber(fe); - else { + } else { p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } @@ -1584,7 +1584,6 @@ static int tune(struct dvb_frontend *fe, bool re_tune, return 0; } - static int get_algo(struct dvb_frontend *fe) { return DVBFE_ALGO_HW; @@ -1697,7 +1696,7 @@ static struct dvb_frontend_ops stv0910_ops = { .diseqc_send_burst = send_burst, }; -static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) +static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) { struct stv_base *p; @@ -1728,7 +1727,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, struct stv *state; struct stv_base *base; - state = kzalloc(sizeof(struct stv), GFP_KERNEL); + state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; @@ -1749,7 +1748,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, base->count++; state->base = base; } else { - base = kzalloc(sizeof(struct stv_base), GFP_KERNEL); + base = kzalloc(sizeof(*base), GFP_KERNEL); if (!base) goto fail; base->i2c = i2c; @@ -1762,7 +1761,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->base = base; if (probe(state) < 0) { dev_info(&i2c->dev, "No demod found at adr %02X on %s\n", - cfg->adr, dev_name(&i2c->dev)); + cfg->adr, dev_name(&i2c->dev)); kfree(base); goto fail; } @@ -1773,7 +1772,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->nr = nr; dev_info(&i2c->dev, "%s demod found at adr %02X on %s\n", - state->fe.ops.info.name, cfg->adr, dev_name(&i2c->dev)); + state->fe.ops.info.name, cfg->adr, dev_name(&i2c->dev)); stv0910_init_stats(state); diff --git a/drivers/media/dvb-frontends/stv0910.h b/drivers/media/dvb-frontends/stv0910.h index e1ab6df7c805..fccd8d9b665f 100644 --- a/drivers/media/dvb-frontends/stv0910.h +++ b/drivers/media/dvb-frontends/stv0910.h @@ -14,8 +14,8 @@ struct stv0910_cfg { #if IS_REACHABLE(CONFIG_DVB_STV0910) -extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, - struct stv0910_cfg *cfg, int nr); +struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, + struct stv0910_cfg *cfg, int nr); #else -- cgit v1.2.3 From 4f979d5cf0a5a5f1c4257e22034dabaf6227f4e7 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:12 -0400 Subject: media: dvb-frontends/stv0910: cosmetics: fixup comments, misc Fix up block comment style, whitespaces, c++ style comments et al. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 407 +++--- drivers/media/dvb-frontends/stv0910_regs.h | 1953 ++++++++++++++-------------- 2 files changed, 1184 insertions(+), 1176 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index a0eb4374fe85..08a5a3ec5391 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -207,136 +207,136 @@ static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val) return status; } -struct slookup s1_sn_lookup[] = { - { 0, 9242 }, /*C/N= 0dB*/ - { 5, 9105 }, /*C/N=0.5dB*/ - { 10, 8950 }, /*C/N=1.0dB*/ - { 15, 8780 }, /*C/N=1.5dB*/ - { 20, 8566 }, /*C/N=2.0dB*/ - { 25, 8366 }, /*C/N=2.5dB*/ - { 30, 8146 }, /*C/N=3.0dB*/ - { 35, 7908 }, /*C/N=3.5dB*/ - { 40, 7666 }, /*C/N=4.0dB*/ - { 45, 7405 }, /*C/N=4.5dB*/ - { 50, 7136 }, /*C/N=5.0dB*/ - { 55, 6861 }, /*C/N=5.5dB*/ - { 60, 6576 }, /*C/N=6.0dB*/ - { 65, 6330 }, /*C/N=6.5dB*/ - { 70, 6048 }, /*C/N=7.0dB*/ - { 75, 5768 }, /*C/N=7.5dB*/ - { 80, 5492 }, /*C/N=8.0dB*/ - { 85, 5224 }, /*C/N=8.5dB*/ - { 90, 4959 }, /*C/N=9.0dB*/ - { 95, 4709 }, /*C/N=9.5dB*/ - { 100, 4467 }, /*C/N=10.0dB*/ - { 105, 4236 }, /*C/N=10.5dB*/ - { 110, 4013 }, /*C/N=11.0dB*/ - { 115, 3800 }, /*C/N=11.5dB*/ - { 120, 3598 }, /*C/N=12.0dB*/ - { 125, 3406 }, /*C/N=12.5dB*/ - { 130, 3225 }, /*C/N=13.0dB*/ - { 135, 3052 }, /*C/N=13.5dB*/ - { 140, 2889 }, /*C/N=14.0dB*/ - { 145, 2733 }, /*C/N=14.5dB*/ - { 150, 2587 }, /*C/N=15.0dB*/ - { 160, 2318 }, /*C/N=16.0dB*/ - { 170, 2077 }, /*C/N=17.0dB*/ - { 180, 1862 }, /*C/N=18.0dB*/ - { 190, 1670 }, /*C/N=19.0dB*/ - { 200, 1499 }, /*C/N=20.0dB*/ - { 210, 1347 }, /*C/N=21.0dB*/ - { 220, 1213 }, /*C/N=22.0dB*/ - { 230, 1095 }, /*C/N=23.0dB*/ - { 240, 992 }, /*C/N=24.0dB*/ - { 250, 900 }, /*C/N=25.0dB*/ - { 260, 826 }, /*C/N=26.0dB*/ - { 270, 758 }, /*C/N=27.0dB*/ - { 280, 702 }, /*C/N=28.0dB*/ - { 290, 653 }, /*C/N=29.0dB*/ - { 300, 613 }, /*C/N=30.0dB*/ - { 310, 579 }, /*C/N=31.0dB*/ - { 320, 550 }, /*C/N=32.0dB*/ - { 330, 526 }, /*C/N=33.0dB*/ - { 350, 490 }, /*C/N=33.0dB*/ - { 400, 445 }, /*C/N=40.0dB*/ - { 450, 430 }, /*C/N=45.0dB*/ - { 500, 426 }, /*C/N=50.0dB*/ - { 510, 425 } /*C/N=51.0dB*/ +static struct slookup s1_sn_lookup[] = { + { 0, 9242 }, /* C/N= 0dB */ + { 5, 9105 }, /* C/N= 0.5dB */ + { 10, 8950 }, /* C/N= 1.0dB */ + { 15, 8780 }, /* C/N= 1.5dB */ + { 20, 8566 }, /* C/N= 2.0dB */ + { 25, 8366 }, /* C/N= 2.5dB */ + { 30, 8146 }, /* C/N= 3.0dB */ + { 35, 7908 }, /* C/N= 3.5dB */ + { 40, 7666 }, /* C/N= 4.0dB */ + { 45, 7405 }, /* C/N= 4.5dB */ + { 50, 7136 }, /* C/N= 5.0dB */ + { 55, 6861 }, /* C/N= 5.5dB */ + { 60, 6576 }, /* C/N= 6.0dB */ + { 65, 6330 }, /* C/N= 6.5dB */ + { 70, 6048 }, /* C/N= 7.0dB */ + { 75, 5768 }, /* C/N= 7.5dB */ + { 80, 5492 }, /* C/N= 8.0dB */ + { 85, 5224 }, /* C/N= 8.5dB */ + { 90, 4959 }, /* C/N= 9.0dB */ + { 95, 4709 }, /* C/N= 9.5dB */ + { 100, 4467 }, /* C/N=10.0dB */ + { 105, 4236 }, /* C/N=10.5dB */ + { 110, 4013 }, /* C/N=11.0dB */ + { 115, 3800 }, /* C/N=11.5dB */ + { 120, 3598 }, /* C/N=12.0dB */ + { 125, 3406 }, /* C/N=12.5dB */ + { 130, 3225 }, /* C/N=13.0dB */ + { 135, 3052 }, /* C/N=13.5dB */ + { 140, 2889 }, /* C/N=14.0dB */ + { 145, 2733 }, /* C/N=14.5dB */ + { 150, 2587 }, /* C/N=15.0dB */ + { 160, 2318 }, /* C/N=16.0dB */ + { 170, 2077 }, /* C/N=17.0dB */ + { 180, 1862 }, /* C/N=18.0dB */ + { 190, 1670 }, /* C/N=19.0dB */ + { 200, 1499 }, /* C/N=20.0dB */ + { 210, 1347 }, /* C/N=21.0dB */ + { 220, 1213 }, /* C/N=22.0dB */ + { 230, 1095 }, /* C/N=23.0dB */ + { 240, 992 }, /* C/N=24.0dB */ + { 250, 900 }, /* C/N=25.0dB */ + { 260, 826 }, /* C/N=26.0dB */ + { 270, 758 }, /* C/N=27.0dB */ + { 280, 702 }, /* C/N=28.0dB */ + { 290, 653 }, /* C/N=29.0dB */ + { 300, 613 }, /* C/N=30.0dB */ + { 310, 579 }, /* C/N=31.0dB */ + { 320, 550 }, /* C/N=32.0dB */ + { 330, 526 }, /* C/N=33.0dB */ + { 350, 490 }, /* C/N=33.0dB */ + { 400, 445 }, /* C/N=40.0dB */ + { 450, 430 }, /* C/N=45.0dB */ + { 500, 426 }, /* C/N=50.0dB */ + { 510, 425 } /* C/N=51.0dB */ }; -struct slookup s2_sn_lookup[] = { - { -30, 13950 }, /*C/N=-2.5dB*/ - { -25, 13580 }, /*C/N=-2.5dB*/ - { -20, 13150 }, /*C/N=-2.0dB*/ - { -15, 12760 }, /*C/N=-1.5dB*/ - { -10, 12345 }, /*C/N=-1.0dB*/ - { -5, 11900 }, /*C/N=-0.5dB*/ - { 0, 11520 }, /*C/N= 0dB*/ - { 5, 11080 }, /*C/N= 0.5dB*/ - { 10, 10630 }, /*C/N= 1.0dB*/ - { 15, 10210 }, /*C/N= 1.5dB*/ - { 20, 9790 }, /*C/N= 2.0dB*/ - { 25, 9390 }, /*C/N= 2.5dB*/ - { 30, 8970 }, /*C/N= 3.0dB*/ - { 35, 8575 }, /*C/N= 3.5dB*/ - { 40, 8180 }, /*C/N= 4.0dB*/ - { 45, 7800 }, /*C/N= 4.5dB*/ - { 50, 7430 }, /*C/N= 5.0dB*/ - { 55, 7080 }, /*C/N= 5.5dB*/ - { 60, 6720 }, /*C/N= 6.0dB*/ - { 65, 6320 }, /*C/N= 6.5dB*/ - { 70, 6060 }, /*C/N= 7.0dB*/ - { 75, 5760 }, /*C/N= 7.5dB*/ - { 80, 5480 }, /*C/N= 8.0dB*/ - { 85, 5200 }, /*C/N= 8.5dB*/ - { 90, 4930 }, /*C/N= 9.0dB*/ - { 95, 4680 }, /*C/N= 9.5dB*/ - { 100, 4425 }, /*C/N=10.0dB*/ - { 105, 4210 }, /*C/N=10.5dB*/ - { 110, 3980 }, /*C/N=11.0dB*/ - { 115, 3765 }, /*C/N=11.5dB*/ - { 120, 3570 }, /*C/N=12.0dB*/ - { 125, 3315 }, /*C/N=12.5dB*/ - { 130, 3140 }, /*C/N=13.0dB*/ - { 135, 2980 }, /*C/N=13.5dB*/ - { 140, 2820 }, /*C/N=14.0dB*/ - { 145, 2670 }, /*C/N=14.5dB*/ - { 150, 2535 }, /*C/N=15.0dB*/ - { 160, 2270 }, /*C/N=16.0dB*/ - { 170, 2035 }, /*C/N=17.0dB*/ - { 180, 1825 }, /*C/N=18.0dB*/ - { 190, 1650 }, /*C/N=19.0dB*/ - { 200, 1485 }, /*C/N=20.0dB*/ - { 210, 1340 }, /*C/N=21.0dB*/ - { 220, 1212 }, /*C/N=22.0dB*/ - { 230, 1100 }, /*C/N=23.0dB*/ - { 240, 1000 }, /*C/N=24.0dB*/ - { 250, 910 }, /*C/N=25.0dB*/ - { 260, 836 }, /*C/N=26.0dB*/ - { 270, 772 }, /*C/N=27.0dB*/ - { 280, 718 }, /*C/N=28.0dB*/ - { 290, 671 }, /*C/N=29.0dB*/ - { 300, 635 }, /*C/N=30.0dB*/ - { 310, 602 }, /*C/N=31.0dB*/ - { 320, 575 }, /*C/N=32.0dB*/ - { 330, 550 }, /*C/N=33.0dB*/ - { 350, 517 }, /*C/N=35.0dB*/ - { 400, 480 }, /*C/N=40.0dB*/ - { 450, 466 }, /*C/N=45.0dB*/ - { 500, 464 }, /*C/N=50.0dB*/ - { 510, 463 }, /*C/N=51.0dB*/ +static struct slookup s2_sn_lookup[] = { + { -30, 13950 }, /* C/N=-2.5dB */ + { -25, 13580 }, /* C/N=-2.5dB */ + { -20, 13150 }, /* C/N=-2.0dB */ + { -15, 12760 }, /* C/N=-1.5dB */ + { -10, 12345 }, /* C/N=-1.0dB */ + { -5, 11900 }, /* C/N=-0.5dB */ + { 0, 11520 }, /* C/N= 0dB */ + { 5, 11080 }, /* C/N= 0.5dB */ + { 10, 10630 }, /* C/N= 1.0dB */ + { 15, 10210 }, /* C/N= 1.5dB */ + { 20, 9790 }, /* C/N= 2.0dB */ + { 25, 9390 }, /* C/N= 2.5dB */ + { 30, 8970 }, /* C/N= 3.0dB */ + { 35, 8575 }, /* C/N= 3.5dB */ + { 40, 8180 }, /* C/N= 4.0dB */ + { 45, 7800 }, /* C/N= 4.5dB */ + { 50, 7430 }, /* C/N= 5.0dB */ + { 55, 7080 }, /* C/N= 5.5dB */ + { 60, 6720 }, /* C/N= 6.0dB */ + { 65, 6320 }, /* C/N= 6.5dB */ + { 70, 6060 }, /* C/N= 7.0dB */ + { 75, 5760 }, /* C/N= 7.5dB */ + { 80, 5480 }, /* C/N= 8.0dB */ + { 85, 5200 }, /* C/N= 8.5dB */ + { 90, 4930 }, /* C/N= 9.0dB */ + { 95, 4680 }, /* C/N= 9.5dB */ + { 100, 4425 }, /* C/N=10.0dB */ + { 105, 4210 }, /* C/N=10.5dB */ + { 110, 3980 }, /* C/N=11.0dB */ + { 115, 3765 }, /* C/N=11.5dB */ + { 120, 3570 }, /* C/N=12.0dB */ + { 125, 3315 }, /* C/N=12.5dB */ + { 130, 3140 }, /* C/N=13.0dB */ + { 135, 2980 }, /* C/N=13.5dB */ + { 140, 2820 }, /* C/N=14.0dB */ + { 145, 2670 }, /* C/N=14.5dB */ + { 150, 2535 }, /* C/N=15.0dB */ + { 160, 2270 }, /* C/N=16.0dB */ + { 170, 2035 }, /* C/N=17.0dB */ + { 180, 1825 }, /* C/N=18.0dB */ + { 190, 1650 }, /* C/N=19.0dB */ + { 200, 1485 }, /* C/N=20.0dB */ + { 210, 1340 }, /* C/N=21.0dB */ + { 220, 1212 }, /* C/N=22.0dB */ + { 230, 1100 }, /* C/N=23.0dB */ + { 240, 1000 }, /* C/N=24.0dB */ + { 250, 910 }, /* C/N=25.0dB */ + { 260, 836 }, /* C/N=26.0dB */ + { 270, 772 }, /* C/N=27.0dB */ + { 280, 718 }, /* C/N=28.0dB */ + { 290, 671 }, /* C/N=29.0dB */ + { 300, 635 }, /* C/N=30.0dB */ + { 310, 602 }, /* C/N=31.0dB */ + { 320, 575 }, /* C/N=32.0dB */ + { 330, 550 }, /* C/N=33.0dB */ + { 350, 517 }, /* C/N=35.0dB */ + { 400, 480 }, /* C/N=40.0dB */ + { 450, 466 }, /* C/N=45.0dB */ + { 500, 464 }, /* C/N=50.0dB */ + { 510, 463 }, /* C/N=51.0dB */ }; -struct slookup padc_lookup[] = { - { 0, 118000 }, /* PADC=+0dBm */ - { -100, 93600 }, /* PADC=-1dBm */ - { -200, 74500 }, /* PADC=-2dBm */ - { -300, 59100 }, /* PADC=-3dBm */ - { -400, 47000 }, /* PADC=-4dBm */ - { -500, 37300 }, /* PADC=-5dBm */ - { -600, 29650 }, /* PADC=-6dBm */ - { -700, 23520 }, /* PADC=-7dBm */ - { -900, 14850 }, /* PADC=-9dBm */ +static struct slookup padc_lookup[] = { + { 0, 118000 }, /* PADC= +0dBm */ + { -100, 93600 }, /* PADC= -1dBm */ + { -200, 74500 }, /* PADC= -2dBm */ + { -300, 59100 }, /* PADC= -3dBm */ + { -400, 47000 }, /* PADC= -4dBm */ + { -500, 37300 }, /* PADC= -5dBm */ + { -600, 29650 }, /* PADC= -6dBm */ + { -700, 23520 }, /* PADC= -7dBm */ + { -900, 14850 }, /* PADC= -9dBm */ { -1100, 9380 }, /* PADC=-11dBm */ { -1300, 5910 }, /* PADC=-13dBm */ { -1500, 3730 }, /* PADC=-15dBm */ @@ -350,7 +350,8 @@ struct slookup padc_lookup[] = { * Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame *********************************************************************/ static u8 s2car_loop[] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff + /* + * Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff * 20MPon 20MPoff 30MPon 30MPoff */ @@ -393,7 +394,8 @@ static u8 s2car_loop[] = { * Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame **********************************************************************/ - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon + /* + * Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon * 20MPoff 30MPon 30MPoff */ @@ -692,24 +694,24 @@ static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) { static u32 nbch[][2] = { - { 0, 0}, /* DUMMY_PLF */ - {16200, 3240}, /* QPSK_1_4, */ - {21600, 5400}, /* QPSK_1_3, */ - {25920, 6480}, /* QPSK_2_5, */ - {32400, 7200}, /* QPSK_1_2, */ - {38880, 9720}, /* QPSK_3_5, */ - {43200, 10800}, /* QPSK_2_3, */ - {48600, 11880}, /* QPSK_3_4, */ - {51840, 12600}, /* QPSK_4_5, */ - {54000, 13320}, /* QPSK_5_6, */ - {57600, 14400}, /* QPSK_8_9, */ - {58320, 16000}, /* QPSK_9_10, */ - {43200, 9720}, /* 8PSK_3_5, */ - {48600, 10800}, /* 8PSK_2_3, */ - {51840, 11880}, /* 8PSK_3_4, */ - {54000, 13320}, /* 8PSK_5_6, */ - {57600, 14400}, /* 8PSK_8_9, */ - {58320, 16000}, /* 8PSK_9_10, */ + { 0, 0}, /* DUMMY_PLF */ + {16200, 3240}, /* QPSK_1_4, */ + {21600, 5400}, /* QPSK_1_3, */ + {25920, 6480}, /* QPSK_2_5, */ + {32400, 7200}, /* QPSK_1_2, */ + {38880, 9720}, /* QPSK_3_5, */ + {43200, 10800}, /* QPSK_2_3, */ + {48600, 11880}, /* QPSK_3_4, */ + {51840, 12600}, /* QPSK_4_5, */ + {54000, 13320}, /* QPSK_5_6, */ + {57600, 14400}, /* QPSK_8_9, */ + {58320, 16000}, /* QPSK_9_10, */ + {43200, 9720}, /* 8PSK_3_5, */ + {48600, 10800}, /* 8PSK_2_3, */ + {51840, 11880}, /* 8PSK_3_4, */ + {54000, 13320}, /* 8PSK_5_6, */ + {57600, 14400}, /* 8PSK_8_9, */ + {58320, 16000}, /* 8PSK_9_10, */ {43200, 10800}, /* 16APSK_2_3, */ {48600, 11880}, /* 16APSK_3_4, */ {51840, 12600}, /* 16APSK_4_5, */ @@ -853,7 +855,7 @@ static int stop(struct stv *state) write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, state->tscfgh | 0x01); read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); - tmp &= ~0x01; /*release reset DVBS2 packet delin*/ + tmp &= ~0x01; /* release reset DVBS2 packet delin */ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); /* Blind optim*/ write_reg(state, RSTV0910_P2_AGC2O + state->regoff, 0x5B); @@ -870,38 +872,38 @@ static int init_search_param(struct stv *state) u8 tmp; read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); - tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS + tmp |= 0x20; /* Filter_en (no effect if SIS=non-MIS */ write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp); - tmp &= ~0x02; // frame mode = 0 + tmp &= ~0x02; /* frame mode = 0 */ write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp); write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0); write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00); read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp); - tmp &= ~0x01; // nosync = 0, in case next signal is standard TS + tmp &= ~0x01; /* nosync = 0, in case next signal is standard TS */ write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp); read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp); - tmp &= ~0x04; // embindvb = 0 + tmp &= ~0x04; /* embindvb = 0 */ write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp); read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp); - tmp &= ~0x80; // syncbyte = 0 + tmp &= ~0x80; /* syncbyte = 0 */ write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp); read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp); - tmp &= ~0x08; // token = 0 + tmp &= ~0x08; /* token = 0 */ write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp); read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp); - tmp &= ~0x30; // hysteresis threshold = 0 + tmp &= ~0x30; /* hysteresis threshold = 0 */ write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp); read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp); - tmp = (tmp & ~0x30) | 0x10; // isi obs mode = 1, observe min ISI + tmp = (tmp & ~0x30) | 0x10; /* isi obs mode = 1, observe min ISI */ write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp); return 0; @@ -952,11 +954,11 @@ static int set_vth_default(struct stv *state) static int set_vth(struct stv *state) { static struct slookup vthlookup_table[] = { - {250, 8780}, /*C/N=1.5dB*/ - {100, 7405}, /*C/N=4.5dB*/ - {40, 6330}, /*C/N=6.5dB*/ - {12, 5224}, /*C/N=8.5dB*/ - {5, 4236} /*C/N=10.5dB*/ + {250, 8780}, /* C/N= 1.5dB */ + {100, 7405}, /* C/N= 4.5dB */ + {40, 6330}, /* C/N= 6.5dB */ + {12, 5224}, /* C/N= 8.5dB */ + {5, 4236} /* C/N=10.5dB */ }; int i; @@ -1001,7 +1003,8 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) init_search_param(state); if (p->stream_id != NO_STREAM_ID_FILTER) { - /* Backwards compatibility to "crazy" API. + /* + * Backwards compatibility to "crazy" API. * PRBS X root cannot be 0, so this should always work. */ if (p->stream_id & 0xffffff00) @@ -1022,22 +1025,22 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) state->cur_scrambling_code = scrambling_code; } - if (p->symbol_rate <= 1000000) { /* SR <=1Msps */ + if (p->symbol_rate <= 1000000) { /* SR <=1Msps */ state->demod_timeout = 3000; state->fec_timeout = 2000; - } else if (p->symbol_rate <= 2000000) { /* 1Msps < SR <=2Msps */ + } else if (p->symbol_rate <= 2000000) { /* 1Msps < SR <=2Msps */ state->demod_timeout = 2500; state->fec_timeout = 1300; - } else if (p->symbol_rate <= 5000000) { /* 2Msps< SR <=5Msps */ + } else if (p->symbol_rate <= 5000000) { /* 2Msps< SR <=5Msps */ state->demod_timeout = 1000; state->fec_timeout = 650; - } else if (p->symbol_rate <= 10000000) { /* 5Msps< SR <=10Msps */ + } else if (p->symbol_rate <= 10000000) { /* 5Msps< SR <=10Msps */ state->demod_timeout = 700; state->fec_timeout = 350; - } else if (p->symbol_rate < 20000000) { /* 10Msps< SR <=20Msps */ + } else if (p->symbol_rate < 20000000) { /* 10Msps< SR <=20Msps */ state->demod_timeout = 400; state->fec_timeout = 200; - } else { /* SR >=20Msps */ + } else { /* SR >=20Msps */ state->demod_timeout = 300; state->fec_timeout = 200; } @@ -1065,7 +1068,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) enable_puncture_rate(state, FEC_NONE); - /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ + /* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA */ write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); @@ -1078,8 +1081,10 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84); write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84); - /* Reset CAR3, bug DVBS2->DVBS1 lock*/ - /* Note: The bit is only pulsed -> no lock on shared register needed */ + /* + * Reset CAR3, bug DVBS2->DVBS1 lock + * Note: The bit is only pulsed -> no lock on shared register needed + */ write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08); write_reg(state, RSTV0910_TSTRES0, 0); @@ -1098,7 +1103,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, (freq >> 8) & 0xff); write_reg(state, RSTV0910_P2_CFRUP0 + state->regoff, (freq & 0xff)); - /*CFR Low Setting*/ + /* CFR Low Setting */ freq = -freq; write_reg(state, RSTV0910_P2_CFRLOW1 + state->regoff, (freq >> 8) & 0xff); @@ -1120,7 +1125,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) static int init_diseqc(struct stv *state) { - u16 offs = state->nr ? 0x40 : 0; /* Address offset */ + u16 offs = state->nr ? 0x40 : 0; /* Address offset */ u8 freq = ((state->base->mclk + 11000 * 32) / (22000 * 32)); /* Disable receiver */ @@ -1144,26 +1149,26 @@ static int probe(struct stv *state) if (id != 0x51) return -EINVAL; - /* Configure the I2C repeater to off */ + /* Configure the I2C repeater to off */ write_reg(state, RSTV0910_P1_I2CRPT, 0x24); /* Configure the I2C repeater to off */ write_reg(state, RSTV0910_P2_I2CRPT, 0x24); /* Set the I2C to oversampling ratio */ write_reg(state, RSTV0910_I2CCFG, 0x88); /* state->i2ccfg */ - write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ - write_reg(state, RSTV0910_PADCFG, 0x05); /* RFAGC Pads Dev = 05 */ - write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ - write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */ - write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ + write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */ + write_reg(state, RSTV0910_PADCFG, 0x05); /* RFAGC Pads Dev = 05 */ + write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ + write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */ + write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ if (state->single) - write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */ + write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */ else - write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ + write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ - write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */ - write_reg(state, RSTV0910_P2_TNRCFG2, 0x82); /* IQSWAP = 1 */ + write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */ + write_reg(state, RSTV0910_P2_TNRCFG2, 0x82); /* IQSWAP = 1 */ write_reg(state, RSTV0910_P1_CAR3CFG, 0x02); write_reg(state, RSTV0910_P2_CAR3CFG, 0x02); @@ -1184,7 +1189,7 @@ static int probe(struct stv *state) /* TS output */ write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh | 0x01); write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh); - write_reg(state, RSTV0910_P1_TSCFGM, 0xC0); /* Manual speed */ + write_reg(state, RSTV0910_P1_TSCFGM, 0xC0); /* Manual speed */ write_reg(state, RSTV0910_P1_TSCFGL, 0x20); /* Speed = 67.5 MHz */ @@ -1192,7 +1197,7 @@ static int probe(struct stv *state) write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh | 0x01); write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh); - write_reg(state, RSTV0910_P2_TSCFGM, 0xC0); /* Manual speed */ + write_reg(state, RSTV0910_P2_TSCFGM, 0xC0); /* Manual speed */ write_reg(state, RSTV0910_P2_TSCFGL, 0x20); /* Speed = 67.5 MHz */ @@ -1425,7 +1430,8 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) manage_matype_info(state); if (state->receive_mode == RCVMODE_DVBS2) { - /* FSTV0910_P2_MANUALSX_ROLLOFF, + /* + * FSTV0910_P2_MANUALSX_ROLLOFF, * FSTV0910_P2_MANUALS2_ROLLOFF = 0 */ state->demod_bits &= ~0x84; @@ -1435,12 +1441,12 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp); - /*reset DVBS2 packet delinator error counter */ + /* reset DVBS2 packet delinator error counter */ tmp |= 0x40; write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp); - /*reset DVBS2 packet delinator error counter */ + /* reset DVBS2 packet delinator error counter */ tmp &= ~0x40; write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, @@ -1462,11 +1468,12 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) RSTV0910_P2_ERRCTRL1 + state->regoff, BER_SRC_S | state->berscale); } - /*Reset the Total packet counter */ + /* Reset the Total packet counter */ write_reg(state, RSTV0910_P2_FBERCPT4 + state->regoff, 0x00); - /* Reset the packet Error counter2 (and Set it to - * infinit error count mode ) + /* + * Reset the packet Error counter2 (and Set it to + * infinit error count mode) */ write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); @@ -1683,17 +1690,17 @@ static struct dvb_frontend_ops stv0910_ops = { FE_CAN_MULTISTREAM }, .sleep = sleep, - .release = release, - .i2c_gate_ctrl = gate_ctrl, + .release = release, + .i2c_gate_ctrl = gate_ctrl, .set_frontend = set_parameters, - .get_frontend_algo = get_algo, - .get_frontend = get_frontend, - .tune = tune, + .get_frontend_algo = get_algo, + .get_frontend = get_frontend, + .tune = tune, .read_status = read_status, .set_tone = set_tone, .diseqc_send_master_cmd = send_master_cmd, - .diseqc_send_burst = send_burst, + .diseqc_send_burst = send_burst, }; static struct stv_base *match_base(struct i2c_adapter *i2c, u8 adr) @@ -1738,8 +1745,8 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->nr = nr; state->regoff = state->nr ? 0 : 0x200; state->search_range = 16000000; - state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ - state->receive_mode = RCVMODE_NONE; + state->demod_bits = 0x10; /* Inversion : Auto with reset to 0 */ + state->receive_mode = RCVMODE_NONE; state->cur_scrambling_code = (~0U); state->single = cfg->single ? 1 : 0; @@ -1767,8 +1774,8 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, } list_add(&base->stvlist, &stvlist); } - state->fe.ops = stv0910_ops; - state->fe.demodulator_priv = state; + state->fe.ops = stv0910_ops; + state->fe.demodulator_priv = state; state->nr = nr; dev_info(&i2c->dev, "%s demod found at adr %02X on %s\n", diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h index 17c9a51e2e34..32ced4eaf296 100644 --- a/drivers/media/dvb-frontends/stv0910_regs.h +++ b/drivers/media/dvb-frontends/stv0910_regs.h @@ -1,4 +1,5 @@ -/* @DVB-S/DVB-S2 STMicroelectronics STV0900 register definitions +/* + * @DVB-S/DVB-S2 STMicroelectronics STV0900 register definitions * Author Manfred Voelkel, August 2013 * (c) 2013 Digital Devices GmbH Germany. All rights reserved * @@ -12,32 +13,32 @@ * ====================================================================== */ -/*MID*/ +/* MID */ #define RSTV0910_MID 0xf100 #define FSTV0910_MCHIP_IDENT 0xf10000f0 #define FSTV0910_MRELEASE 0xf100000f -/*DID*/ +/* DID */ #define RSTV0910_DID 0xf101 #define FSTV0910_DEVICE_ID 0xf10100ff -/*DACR1*/ +/* DACR1 */ #define RSTV0910_DACR1 0xf113 #define FSTV0910_DAC_MODE 0xf11300e0 #define FSTV0910_DAC_VALUE1 0xf113000f -/*DACR2*/ +/* DACR2 */ #define RSTV0910_DACR2 0xf114 #define FSTV0910_DAC_VALUE0 0xf11400ff -/*PADCFG*/ +/* PADCFG */ #define RSTV0910_PADCFG 0xf11a #define FSTV0910_AGCRF2_OPD 0xf11a0008 #define FSTV0910_AGCRF2_XOR 0xf11a0004 #define FSTV0910_AGCRF1_OPD 0xf11a0002 #define FSTV0910_AGCRF1_XOR 0xf11a0001 -/*OUTCFG2*/ +/* OUTCFG2 */ #define RSTV0910_OUTCFG2 0xf11b #define FSTV0910_TS2_ERROR_XOR 0xf11b0080 #define FSTV0910_TS2_DPN_XOR 0xf11b0040 @@ -48,7 +49,7 @@ #define FSTV0910_TS1_STROUT_XOR 0xf11b0002 #define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001 -/*OUTCFG*/ +/* OUTCFG */ #define RSTV0910_OUTCFG 0xf11c #define FSTV0910_TS2_OUTSER_HZ 0xf11c0020 #define FSTV0910_TS1_OUTSER_HZ 0xf11c0010 @@ -56,7 +57,7 @@ #define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004 #define FSTV0910_TS_SERDATA0 0xf11c0002 -/*IRQSTATUS3*/ +/* IRQSTATUS3 */ #define RSTV0910_IRQSTATUS3 0xf120 #define FSTV0910_SPLL_LOCK 0xf1200020 #define FSTV0910_SSTREAM_LCK_1 0xf1200010 @@ -64,7 +65,7 @@ #define FSTV0910_SDVBS1_PRF_2 0xf1200002 #define FSTV0910_SDVBS1_PRF_1 0xf1200001 -/*IRQSTATUS2*/ +/* IRQSTATUS2 */ #define RSTV0910_IRQSTATUS2 0xf121 #define FSTV0910_SSPY_ENDSIM_1 0xf1210080 #define FSTV0910_SSPY_ENDSIM_2 0xf1210040 @@ -74,7 +75,7 @@ #define FSTV0910_SPKTDEL_ERROR_1 0xf1210002 #define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001 -/*IRQSTATUS1*/ +/* IRQSTATUS1 */ #define RSTV0910_IRQSTATUS1 0xf122 #define FSTV0910_SPKTDEL_LOCK_1 0xf1220080 #define FSTV0910_SFEC_LOCKB_2 0xf1220040 @@ -85,7 +86,7 @@ #define FSTV0910_SDEMOD_LOCK_2 0xf1220002 #define FSTV0910_SDEMOD_IRQ_2 0xf1220001 -/*IRQSTATUS0*/ +/* IRQSTATUS0 */ #define RSTV0910_IRQSTATUS0 0xf123 #define FSTV0910_SDEMOD_LOCKB_1 0xf1230080 #define FSTV0910_SDEMOD_LOCK_1 0xf1230040 @@ -94,7 +95,7 @@ #define FSTV0910_SDISEQC2_IRQ 0xf1230004 #define FSTV0910_SDISEQC1_IRQ 0xf1230001 -/*IRQMASK3*/ +/* IRQMASK3 */ #define RSTV0910_IRQMASK3 0xf124 #define FSTV0910_MPLL_LOCK 0xf1240020 #define FSTV0910_MSTREAM_LCK_1 0xf1240010 @@ -102,7 +103,7 @@ #define FSTV0910_MDVBS1_PRF_2 0xf1240002 #define FSTV0910_MDVBS1_PRF_1 0xf1240001 -/*IRQMASK2*/ +/* IRQMASK2 */ #define RSTV0910_IRQMASK2 0xf125 #define FSTV0910_MSPY_ENDSIM_1 0xf1250080 #define FSTV0910_MSPY_ENDSIM_2 0xf1250040 @@ -112,7 +113,7 @@ #define FSTV0910_MPKTDEL_ERROR_1 0xf1250002 #define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001 -/*IRQMASK1*/ +/* IRQMASK1 */ #define RSTV0910_IRQMASK1 0xf126 #define FSTV0910_MPKTDEL_LOCK_1 0xf1260080 #define FSTV0910_MFEC_LOCKB_2 0xf1260040 @@ -123,7 +124,7 @@ #define FSTV0910_MDEMOD_LOCK_2 0xf1260002 #define FSTV0910_MDEMOD_IRQ_2 0xf1260001 -/*IRQMASK0*/ +/* IRQMASK0 */ #define RSTV0910_IRQMASK0 0xf127 #define FSTV0910_MDEMOD_LOCKB_1 0xf1270080 #define FSTV0910_MDEMOD_LOCK_1 0xf1270040 @@ -132,12 +133,12 @@ #define FSTV0910_MDISEQC2_IRQ 0xf1270004 #define FSTV0910_MDISEQC1_IRQ 0xf1270001 -/*I2CCFG*/ +/* I2CCFG */ #define RSTV0910_I2CCFG 0xf129 #define FSTV0910_I2C_FASTMODE 0xf1290008 #define FSTV0910_I2CADDR_INC 0xf1290003 -/*P1_I2CRPT*/ +/* P1_I2CRPT */ #define RSTV0910_P1_I2CRPT 0xf12a #define FSTV0910_P1_I2CT_ON 0xf12a0080 #define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070 @@ -145,7 +146,7 @@ #define FSTV0910_P1_STOP_ENABLE 0xf12a0004 #define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002 -/*P2_I2CRPT*/ +/* P2_I2CRPT */ #define RSTV0910_P2_I2CRPT 0xf12b #define FSTV0910_P2_I2CT_ON 0xf12b0080 #define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070 @@ -153,181 +154,181 @@ #define FSTV0910_P2_STOP_ENABLE 0xf12b0004 #define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002 -/*GPIO0CFG*/ +/* GPIO0CFG */ #define RSTV0910_GPIO0CFG 0xf140 #define FSTV0910_GPIO0_OPD 0xf1400080 #define FSTV0910_GPIO0_CONFIG 0xf140007e #define FSTV0910_GPIO0_XOR 0xf1400001 -/*GPIO1CFG*/ +/* GPIO1CFG */ #define RSTV0910_GPIO1CFG 0xf141 #define FSTV0910_GPIO1_OPD 0xf1410080 #define FSTV0910_GPIO1_CONFIG 0xf141007e #define FSTV0910_GPIO1_XOR 0xf1410001 -/*GPIO2CFG*/ +/* GPIO2CFG */ #define RSTV0910_GPIO2CFG 0xf142 #define FSTV0910_GPIO2_OPD 0xf1420080 #define FSTV0910_GPIO2_CONFIG 0xf142007e #define FSTV0910_GPIO2_XOR 0xf1420001 -/*GPIO3CFG*/ +/* GPIO3CFG */ #define RSTV0910_GPIO3CFG 0xf143 #define FSTV0910_GPIO3_OPD 0xf1430080 #define FSTV0910_GPIO3_CONFIG 0xf143007e #define FSTV0910_GPIO3_XOR 0xf1430001 -/*GPIO4CFG*/ +/* GPIO4CFG */ #define RSTV0910_GPIO4CFG 0xf144 #define FSTV0910_GPIO4_OPD 0xf1440080 #define FSTV0910_GPIO4_CONFIG 0xf144007e #define FSTV0910_GPIO4_XOR 0xf1440001 -/*GPIO5CFG*/ +/* GPIO5CFG */ #define RSTV0910_GPIO5CFG 0xf145 #define FSTV0910_GPIO5_OPD 0xf1450080 #define FSTV0910_GPIO5_CONFIG 0xf145007e #define FSTV0910_GPIO5_XOR 0xf1450001 -/*GPIO6CFG*/ +/* GPIO6CFG */ #define RSTV0910_GPIO6CFG 0xf146 #define FSTV0910_GPIO6_OPD 0xf1460080 #define FSTV0910_GPIO6_CONFIG 0xf146007e #define FSTV0910_GPIO6_XOR 0xf1460001 -/*GPIO7CFG*/ +/* GPIO7CFG */ #define RSTV0910_GPIO7CFG 0xf147 #define FSTV0910_GPIO7_OPD 0xf1470080 #define FSTV0910_GPIO7_CONFIG 0xf147007e #define FSTV0910_GPIO7_XOR 0xf1470001 -/*GPIO8CFG*/ +/* GPIO8CFG */ #define RSTV0910_GPIO8CFG 0xf148 #define FSTV0910_GPIO8_OPD 0xf1480080 #define FSTV0910_GPIO8_CONFIG 0xf148007e #define FSTV0910_GPIO8_XOR 0xf1480001 -/*GPIO9CFG*/ +/* GPIO9CFG */ #define RSTV0910_GPIO9CFG 0xf149 #define FSTV0910_GPIO9_OPD 0xf1490080 #define FSTV0910_GPIO9_CONFIG 0xf149007e #define FSTV0910_GPIO9_XOR 0xf1490001 -/*GPIO10CFG*/ +/* GPIO10CFG */ #define RSTV0910_GPIO10CFG 0xf14a #define FSTV0910_GPIO10_OPD 0xf14a0080 #define FSTV0910_GPIO10_CONFIG 0xf14a007e #define FSTV0910_GPIO10_XOR 0xf14a0001 -/*GPIO11CFG*/ +/* GPIO11CFG */ #define RSTV0910_GPIO11CFG 0xf14b #define FSTV0910_GPIO11_OPD 0xf14b0080 #define FSTV0910_GPIO11_CONFIG 0xf14b007e #define FSTV0910_GPIO11_XOR 0xf14b0001 -/*GPIO12CFG*/ +/* GPIO12CFG */ #define RSTV0910_GPIO12CFG 0xf14c #define FSTV0910_GPIO12_OPD 0xf14c0080 #define FSTV0910_GPIO12_CONFIG 0xf14c007e #define FSTV0910_GPIO12_XOR 0xf14c0001 -/*GPIO13CFG*/ +/* GPIO13CFG */ #define RSTV0910_GPIO13CFG 0xf14d #define FSTV0910_GPIO13_OPD 0xf14d0080 #define FSTV0910_GPIO13_CONFIG 0xf14d007e #define FSTV0910_GPIO13_XOR 0xf14d0001 -/*GPIO14CFG*/ +/* GPIO14CFG */ #define RSTV0910_GPIO14CFG 0xf14e #define FSTV0910_GPIO14_OPD 0xf14e0080 #define FSTV0910_GPIO14_CONFIG 0xf14e007e #define FSTV0910_GPIO14_XOR 0xf14e0001 -/*GPIO15CFG*/ +/* GPIO15CFG */ #define RSTV0910_GPIO15CFG 0xf14f #define FSTV0910_GPIO15_OPD 0xf14f0080 #define FSTV0910_GPIO15_CONFIG 0xf14f007e #define FSTV0910_GPIO15_XOR 0xf14f0001 -/*GPIO16CFG*/ +/* GPIO16CFG */ #define RSTV0910_GPIO16CFG 0xf150 #define FSTV0910_GPIO16_OPD 0xf1500080 #define FSTV0910_GPIO16_CONFIG 0xf150007e #define FSTV0910_GPIO16_XOR 0xf1500001 -/*GPIO17CFG*/ +/* GPIO17CFG */ #define RSTV0910_GPIO17CFG 0xf151 #define FSTV0910_GPIO17_OPD 0xf1510080 #define FSTV0910_GPIO17_CONFIG 0xf151007e #define FSTV0910_GPIO17_XOR 0xf1510001 -/*GPIO18CFG*/ +/* GPIO18CFG */ #define RSTV0910_GPIO18CFG 0xf152 #define FSTV0910_GPIO18_OPD 0xf1520080 #define FSTV0910_GPIO18_CONFIG 0xf152007e #define FSTV0910_GPIO18_XOR 0xf1520001 -/*GPIO19CFG*/ +/* GPIO19CFG */ #define RSTV0910_GPIO19CFG 0xf153 #define FSTV0910_GPIO19_OPD 0xf1530080 #define FSTV0910_GPIO19_CONFIG 0xf153007e #define FSTV0910_GPIO19_XOR 0xf1530001 -/*GPIO20CFG*/ +/* GPIO20CFG */ #define RSTV0910_GPIO20CFG 0xf154 #define FSTV0910_GPIO20_OPD 0xf1540080 #define FSTV0910_GPIO20_CONFIG 0xf154007e #define FSTV0910_GPIO20_XOR 0xf1540001 -/*GPIO21CFG*/ +/* GPIO21CFG */ #define RSTV0910_GPIO21CFG 0xf155 #define FSTV0910_GPIO21_OPD 0xf1550080 #define FSTV0910_GPIO21_CONFIG 0xf155007e #define FSTV0910_GPIO21_XOR 0xf1550001 -/*GPIO22CFG*/ +/* GPIO22CFG */ #define RSTV0910_GPIO22CFG 0xf156 #define FSTV0910_GPIO22_OPD 0xf1560080 #define FSTV0910_GPIO22_CONFIG 0xf156007e #define FSTV0910_GPIO22_XOR 0xf1560001 -/*STRSTATUS1*/ +/* STRSTATUS1 */ #define RSTV0910_STRSTATUS1 0xf16a #define FSTV0910_STRSTATUS_SEL2 0xf16a00f0 #define FSTV0910_STRSTATUS_SEL1 0xf16a000f -/*STRSTATUS2*/ +/* STRSTATUS2 */ #define RSTV0910_STRSTATUS2 0xf16b #define FSTV0910_STRSTATUS_SEL4 0xf16b00f0 #define FSTV0910_STRSTATUS_SEL3 0xf16b000f -/*STRSTATUS3*/ +/* STRSTATUS3 */ #define RSTV0910_STRSTATUS3 0xf16c #define FSTV0910_STRSTATUS_SEL6 0xf16c00f0 #define FSTV0910_STRSTATUS_SEL5 0xf16c000f -/*FSKTFC2*/ +/* FSKTFC2 */ #define RSTV0910_FSKTFC2 0xf170 #define FSTV0910_FSKT_KMOD 0xf17000fc #define FSTV0910_FSKT_CAR2 0xf1700003 -/*FSKTFC1*/ +/* FSKTFC1 */ #define RSTV0910_FSKTFC1 0xf171 #define FSTV0910_FSKT_CAR1 0xf17100ff -/*FSKTFC0*/ +/* FSKTFC0 */ #define RSTV0910_FSKTFC0 0xf172 #define FSTV0910_FSKT_CAR0 0xf17200ff -/*FSKTDELTAF1*/ +/* FSKTDELTAF1 */ #define RSTV0910_FSKTDELTAF1 0xf173 #define FSTV0910_FSKT_DELTAF1 0xf173000f -/*FSKTDELTAF0*/ +/* FSKTDELTAF0 */ #define RSTV0910_FSKTDELTAF0 0xf174 #define FSTV0910_FSKT_DELTAF0 0xf17400ff -/*FSKTCTRL*/ +/* FSKTCTRL */ #define RSTV0910_FSKTCTRL 0xf175 #define FSTV0910_FSKT_PINSEL 0xf1750080 #define FSTV0910_FSKT_EN_SGN 0xf1750040 @@ -335,129 +336,129 @@ #define FSTV0910_FSKT_MOD_EN 0xf175001c #define FSTV0910_FSKT_DACMODE 0xf1750003 -/*FSKRFC2*/ +/* FSKRFC2 */ #define RSTV0910_FSKRFC2 0xf176 #define FSTV0910_FSKR_DETSGN 0xf1760040 #define FSTV0910_FSKR_OUTSGN 0xf1760020 #define FSTV0910_FSKR_KAGC 0xf176001c #define FSTV0910_FSKR_CAR2 0xf1760003 -/*FSKRFC1*/ +/* FSKRFC1 */ #define RSTV0910_FSKRFC1 0xf177 #define FSTV0910_FSKR_CAR1 0xf17700ff -/*FSKRFC0*/ +/* FSKRFC0 */ #define RSTV0910_FSKRFC0 0xf178 #define FSTV0910_FSKR_CAR0 0xf17800ff -/*FSKRK1*/ +/* FSKRK1 */ #define RSTV0910_FSKRK1 0xf179 #define FSTV0910_FSKR_K1_EXP 0xf17900e0 #define FSTV0910_FSKR_K1_MANT 0xf179001f -/*FSKRK2*/ +/* FSKRK2 */ #define RSTV0910_FSKRK2 0xf17a #define FSTV0910_FSKR_K2_EXP 0xf17a00e0 #define FSTV0910_FSKR_K2_MANT 0xf17a001f -/*FSKRAGCR*/ +/* FSKRAGCR */ #define RSTV0910_FSKRAGCR 0xf17b #define FSTV0910_FSKR_OUTCTL 0xf17b00c0 #define FSTV0910_FSKR_AGC_REF 0xf17b003f -/*FSKRAGC*/ +/* FSKRAGC */ #define RSTV0910_FSKRAGC 0xf17c #define FSTV0910_FSKR_AGC_ACCU 0xf17c00ff -/*FSKRALPHA*/ +/* FSKRALPHA */ #define RSTV0910_FSKRALPHA 0xf17d #define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c #define FSTV0910_FSKR_ALPHA_M 0xf17d0003 -/*FSKRPLTH1*/ +/* FSKRPLTH1 */ #define RSTV0910_FSKRPLTH1 0xf17e #define FSTV0910_FSKR_BETA 0xf17e00f0 #define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f -/*FSKRPLTH0*/ +/* FSKRPLTH0 */ #define RSTV0910_FSKRPLTH0 0xf17f #define FSTV0910_FSKR_PLL_TRESH0 0xf17f00ff -/*FSKRDF1*/ +/* FSKRDF1 */ #define RSTV0910_FSKRDF1 0xf180 #define FSTV0910_FSKR_OUT 0xf1800080 #define FSTV0910_FSKR_STATE 0xf1800060 #define FSTV0910_FSKR_DELTAF1 0xf180001f -/*FSKRDF0*/ +/* FSKRDF0 */ #define RSTV0910_FSKRDF0 0xf181 #define FSTV0910_FSKR_DELTAF0 0xf18100ff -/*FSKRSTEPP*/ +/* FSKRSTEPP */ #define RSTV0910_FSKRSTEPP 0xf182 #define FSTV0910_FSKR_STEP_PLUS 0xf18200ff -/*FSKRSTEPM*/ +/* FSKRSTEPM */ #define RSTV0910_FSKRSTEPM 0xf183 #define FSTV0910_FSKR_STEP_MINUS 0xf18300ff -/*FSKRDET1*/ +/* FSKRDET1 */ #define RSTV0910_FSKRDET1 0xf184 #define FSTV0910_FSKR_DETECT 0xf1840080 #define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f -/*FSKRDET0*/ +/* FSKRDET0 */ #define RSTV0910_FSKRDET0 0xf185 #define FSTV0910_FSKR_CARDET_ACCU0 0xf18500ff -/*FSKRDTH1*/ +/* FSKRDTH1 */ #define RSTV0910_FSKRDTH1 0xf186 #define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0 #define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f -/*FSKRDTH0*/ +/* FSKRDTH0 */ #define RSTV0910_FSKRDTH0 0xf187 #define FSTV0910_FSKR_CARDET_THRESH0 0xf18700ff -/*FSKRLOSS*/ +/* FSKRLOSS */ #define RSTV0910_FSKRLOSS 0xf188 #define FSTV0910_FSKR_CARLOSS_THRESH0 0xf18800ff -/*NCOARSE*/ +/* NCOARSE */ #define RSTV0910_NCOARSE 0xf1b3 #define FSTV0910_CP 0xf1b300f8 #define FSTV0910_IDF 0xf1b30007 -/*NCOARSE1*/ +/* NCOARSE1 */ #define RSTV0910_NCOARSE1 0xf1b4 #define FSTV0910_N_DIV 0xf1b400ff -/*NCOARSE2*/ +/* NCOARSE2 */ #define RSTV0910_NCOARSE2 0xf1b5 #define FSTV0910_ODF 0xf1b5003f -/*SYNTCTRL*/ +/* SYNTCTRL */ #define RSTV0910_SYNTCTRL 0xf1b6 #define FSTV0910_STANDBY 0xf1b60080 #define FSTV0910_BYPASSPLLCORE 0xf1b60040 #define FSTV0910_STOP_PLL 0xf1b60008 #define FSTV0910_OSCI_E 0xf1b60002 -/*FILTCTRL*/ +/* FILTCTRL */ #define RSTV0910_FILTCTRL 0xf1b7 #define FSTV0910_INV_CLKFSK 0xf1b70002 #define FSTV0910_BYPASS_APPLI 0xf1b70001 -/*PLLSTAT*/ +/* PLLSTAT */ #define RSTV0910_PLLSTAT 0xf1b8 #define FSTV0910_PLLLOCK 0xf1b80001 -/*STOPCLK1*/ +/* STOPCLK1 */ #define RSTV0910_STOPCLK1 0xf1c2 #define FSTV0910_INV_CLKADCI2 0xf1c20004 #define FSTV0910_INV_CLKADCI1 0xf1c20001 -/*STOPCLK2*/ +/* STOPCLK2 */ #define RSTV0910_STOPCLK2 0xf1c3 #define FSTV0910_STOP_DVBS2FEC2 0xf1c30020 #define FSTV0910_STOP_DVBS2FEC 0xf1c30010 @@ -466,47 +467,47 @@ #define FSTV0910_STOP_DEMOD2 0xf1c30002 #define FSTV0910_STOP_DEMOD 0xf1c30001 -/*PREGCTL*/ +/* PREGCTL */ #define RSTV0910_PREGCTL 0xf1c8 #define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080 -/*TSTTNR0*/ +/* TSTTNR0 */ #define RSTV0910_TSTTNR0 0xf1df #define FSTV0910_FSK_PON 0xf1df0004 -/*TSTTNR1*/ +/* TSTTNR1 */ #define RSTV0910_TSTTNR1 0xf1e0 #define FSTV0910_ADC1_PON 0xf1e00002 -/*TSTTNR2*/ +/* TSTTNR2 */ #define RSTV0910_TSTTNR2 0xf1e1 #define FSTV0910_I2C_DISEQC_PON 0xf1e10020 #define FSTV0910_DISEQC_CLKDIV 0xf1e1000f -/*TSTTNR3*/ +/* TSTTNR3 */ #define RSTV0910_TSTTNR3 0xf1e2 #define FSTV0910_ADC2_PON 0xf1e20002 -/*P2_IQCONST*/ +/* P2_IQCONST */ #define RSTV0910_P2_IQCONST 0xf200 #define FSTV0910_P2_CONSTEL_SELECT 0xf2000060 #define FSTV0910_P2_IQSYMB_SEL 0xf200001f -/*P2_NOSCFG*/ +/* P2_NOSCFG */ #define RSTV0910_P2_NOSCFG 0xf201 #define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020 #define FSTV0910_P2_NOSPLH_BETA 0xf2010018 #define FSTV0910_P2_NOSDATA_BETA 0xf2010007 -/*P2_ISYMB*/ +/* P2_ISYMB */ #define RSTV0910_P2_ISYMB 0xf202 #define FSTV0910_P2_I_SYMBOL 0xf20201ff -/*P2_QSYMB*/ +/* P2_QSYMB */ #define RSTV0910_P2_QSYMB 0xf203 #define FSTV0910_P2_Q_SYMBOL 0xf20301ff -/*P2_AGC1CFG*/ +/* P2_AGC1CFG */ #define RSTV0910_P2_AGC1CFG 0xf204 #define FSTV0910_P2_DC_FROZEN 0xf2040080 #define FSTV0910_P2_DC_CORRECT 0xf2040040 @@ -515,70 +516,70 @@ #define FSTV0910_P2_QUAD_FROZEN 0xf2040008 #define FSTV0910_P2_QUAD_CORRECT 0xf2040004 -/*P2_AGC1CN*/ +/* P2_AGC1CN */ #define RSTV0910_P2_AGC1CN 0xf206 #define FSTV0910_P2_AGC1_LOCKED 0xf2060080 #define FSTV0910_P2_AGC1_MINPOWER 0xf2060010 #define FSTV0910_P2_AGCOUT_FAST 0xf2060008 #define FSTV0910_P2_AGCIQ_BETA 0xf2060007 -/*P2_AGC1REF*/ +/* P2_AGC1REF */ #define RSTV0910_P2_AGC1REF 0xf207 #define FSTV0910_P2_AGCIQ_REF 0xf20700ff -/*P2_IDCCOMP*/ +/* P2_IDCCOMP */ #define RSTV0910_P2_IDCCOMP 0xf208 #define FSTV0910_P2_IAVERAGE_ADJ 0xf20801ff -/*P2_QDCCOMP*/ +/* P2_QDCCOMP */ #define RSTV0910_P2_QDCCOMP 0xf209 #define FSTV0910_P2_QAVERAGE_ADJ 0xf20901ff -/*P2_POWERI*/ +/* P2_POWERI */ #define RSTV0910_P2_POWERI 0xf20a #define FSTV0910_P2_POWER_I 0xf20a00ff -/*P2_POWERQ*/ +/* P2_POWERQ */ #define RSTV0910_P2_POWERQ 0xf20b #define FSTV0910_P2_POWER_Q 0xf20b00ff -/*P2_AGC1AMM*/ +/* P2_AGC1AMM */ #define RSTV0910_P2_AGC1AMM 0xf20c #define FSTV0910_P2_AMM_VALUE 0xf20c00ff -/*P2_AGC1QUAD*/ +/* P2_AGC1QUAD */ #define RSTV0910_P2_AGC1QUAD 0xf20d #define FSTV0910_P2_QUAD_VALUE 0xf20d01ff -/*P2_AGCIQIN1*/ +/* P2_AGCIQIN1 */ #define RSTV0910_P2_AGCIQIN1 0xf20e #define FSTV0910_P2_AGCIQ_VALUE1 0xf20e00ff -/*P2_AGCIQIN0*/ +/* P2_AGCIQIN0 */ #define RSTV0910_P2_AGCIQIN0 0xf20f #define FSTV0910_P2_AGCIQ_VALUE0 0xf20f00ff -/*P2_DEMOD*/ +/* P2_DEMOD */ #define RSTV0910_P2_DEMOD 0xf210 #define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080 #define FSTV0910_P2_SPECINV_CONTROL 0xf2100030 #define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004 #define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003 -/*P2_DMDMODCOD*/ +/* P2_DMDMODCOD */ #define RSTV0910_P2_DMDMODCOD 0xf211 #define FSTV0910_P2_MANUAL_MODCOD 0xf2110080 #define FSTV0910_P2_DEMOD_MODCOD 0xf211007c #define FSTV0910_P2_DEMOD_TYPE 0xf2110003 -/*P2_DSTATUS*/ +/* P2_DSTATUS */ #define RSTV0910_P2_DSTATUS 0xf212 #define FSTV0910_P2_CAR_LOCK 0xf2120080 #define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060 #define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008 #define FSTV0910_P2_OVADC_DETECT 0xf2120001 -/*P2_DSTATUS2*/ +/* P2_DSTATUS2 */ #define RSTV0910_P2_DSTATUS2 0xf213 #define FSTV0910_P2_DEMOD_DELOCK 0xf2130080 #define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020 @@ -588,7 +589,7 @@ #define FSTV0910_P2_CFR_OVERFLOW 0xf2130002 #define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001 -/*P2_DMDCFGMD*/ +/* P2_DMDCFGMD */ #define RSTV0910_P2_DMDCFGMD 0xf214 #define FSTV0910_P2_DVBS2_ENABLE 0xf2140080 #define FSTV0910_P2_DVBS1_ENABLE 0xf2140040 @@ -596,503 +597,503 @@ #define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008 #define FSTV0910_P2_TUN_RNG 0xf2140003 -/*P2_DMDCFG2*/ +/* P2_DMDCFG2 */ #define RSTV0910_P2_DMDCFG2 0xf215 #define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040 #define FSTV0910_P2_INFINITE_RELOCK 0xf2150010 -/*P2_DMDISTATE*/ +/* P2_DMDISTATE */ #define RSTV0910_P2_DMDISTATE 0xf216 #define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080 #define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f -/*P2_DMDT0M*/ +/* P2_DMDT0M */ #define RSTV0910_P2_DMDT0M 0xf217 #define FSTV0910_P2_DMDT0_MIN 0xf21700ff -/*P2_DMDSTATE*/ +/* P2_DMDSTATE */ #define RSTV0910_P2_DMDSTATE 0xf21b #define FSTV0910_P2_HEADER_MODE 0xf21b0060 -/*P2_DMDFLYW*/ +/* P2_DMDFLYW */ #define RSTV0910_P2_DMDFLYW 0xf21c #define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0 #define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f -/*P2_DSTATUS3*/ +/* P2_DSTATUS3 */ #define RSTV0910_P2_DSTATUS3 0xf21d #define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080 #define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060 #define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010 -/*P2_DMDCFG3*/ +/* P2_DMDCFG3 */ #define RSTV0910_P2_DMDCFG3 0xf21e #define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008 -/*P2_DMDCFG4*/ +/* P2_DMDCFG4 */ #define RSTV0910_P2_DMDCFG4 0xf21f #define FSTV0910_P2_DIS_VITLOCK 0xf21f0080 #define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004 -/*P2_CORRELMANT*/ +/* P2_CORRELMANT */ #define RSTV0910_P2_CORRELMANT 0xf220 #define FSTV0910_P2_CORREL_MANT 0xf22000ff -/*P2_CORRELABS*/ +/* P2_CORRELABS */ #define RSTV0910_P2_CORRELABS 0xf221 #define FSTV0910_P2_CORREL_ABS 0xf22100ff -/*P2_CORRELEXP*/ +/* P2_CORRELEXP */ #define RSTV0910_P2_CORRELEXP 0xf222 #define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0 #define FSTV0910_P2_CORREL_EXP 0xf222000f -/*P2_PLHMODCOD*/ +/* P2_PLHMODCOD */ #define RSTV0910_P2_PLHMODCOD 0xf224 #define FSTV0910_P2_SPECINV_DEMOD 0xf2240080 #define FSTV0910_P2_PLH_MODCOD 0xf224007c #define FSTV0910_P2_PLH_TYPE 0xf2240003 -/*P2_DMDREG*/ +/* P2_DMDREG */ #define RSTV0910_P2_DMDREG 0xf225 #define FSTV0910_P2_DECIM_PLFRAMES 0xf2250001 -/*P2_AGCNADJ*/ +/* P2_AGCNADJ */ #define RSTV0910_P2_AGCNADJ 0xf226 #define FSTV0910_P2_RADJOFF_AGC2 0xf2260080 #define FSTV0910_P2_RADJOFF_AGC1 0xf2260040 #define FSTV0910_P2_AGC_NADJ 0xf226013f -/*P2_AGCKS*/ +/* P2_AGCKS */ #define RSTV0910_P2_AGCKS 0xf227 #define FSTV0910_P2_RSADJ_MANUALCFG 0xf2270080 #define FSTV0910_P2_RSADJ_CCMMODE 0xf2270040 #define FSTV0910_P2_RADJ_SPSK 0xf227013f -/*P2_AGCKQ*/ +/* P2_AGCKQ */ #define RSTV0910_P2_AGCKQ 0xf228 #define FSTV0910_P2_RADJON_DVBS1 0xf2280040 #define FSTV0910_P2_RADJ_QPSK 0xf228013f -/*P2_AGCK8*/ +/* P2_AGCK8 */ #define RSTV0910_P2_AGCK8 0xf229 #define FSTV0910_P2_RADJ_8PSK 0xf229013f -/*P2_AGCK16*/ +/* P2_AGCK16 */ #define RSTV0910_P2_AGCK16 0xf22a #define FSTV0910_P2_R2ADJOFF_16APSK 0xf22a0040 #define FSTV0910_P2_R1ADJOFF_16APSK 0xf22a0020 #define FSTV0910_P2_RADJ_16APSK 0xf22a011f -/*P2_AGCK32*/ +/* P2_AGCK32 */ #define RSTV0910_P2_AGCK32 0xf22b #define FSTV0910_P2_R3ADJOFF_32APSK 0xf22b0080 #define FSTV0910_P2_R2ADJOFF_32APSK 0xf22b0040 #define FSTV0910_P2_R1ADJOFF_32APSK 0xf22b0020 #define FSTV0910_P2_RADJ_32APSK 0xf22b011f -/*P2_AGC2O*/ +/* P2_AGC2O */ #define RSTV0910_P2_AGC2O 0xf22c #define FSTV0910_P2_CSTENV_MODE 0xf22c00c0 #define FSTV0910_P2_AGC2_COEF 0xf22c0007 -/*P2_AGC2REF*/ +/* P2_AGC2REF */ #define RSTV0910_P2_AGC2REF 0xf22d #define FSTV0910_P2_AGC2_REF 0xf22d00ff -/*P2_AGC1ADJ*/ +/* P2_AGC1ADJ */ #define RSTV0910_P2_AGC1ADJ 0xf22e #define FSTV0910_P2_AGC1_ADJUSTED 0xf22e007f -/*P2_AGCRSADJ*/ +/* P2_AGCRSADJ */ #define RSTV0910_P2_AGCRSADJ 0xf22f #define FSTV0910_P2_RS_ADJUSTED 0xf22f007f -/*P2_AGCRQADJ*/ +/* P2_AGCRQADJ */ #define RSTV0910_P2_AGCRQADJ 0xf230 #define FSTV0910_P2_RQ_ADJUSTED 0xf230007f -/*P2_AGCR8ADJ*/ +/* P2_AGCR8ADJ */ #define RSTV0910_P2_AGCR8ADJ 0xf231 #define FSTV0910_P2_R8_ADJUSTED 0xf231007f -/*P2_AGCR1ADJ*/ +/* P2_AGCR1ADJ */ #define RSTV0910_P2_AGCR1ADJ 0xf232 #define FSTV0910_P2_R1_ADJUSTED 0xf232007f -/*P2_AGCR2ADJ*/ +/* P2_AGCR2ADJ */ #define RSTV0910_P2_AGCR2ADJ 0xf233 #define FSTV0910_P2_R2_ADJUSTED 0xf233007f -/*P2_AGCR3ADJ*/ +/* P2_AGCR3ADJ */ #define RSTV0910_P2_AGCR3ADJ 0xf234 #define FSTV0910_P2_R3_ADJUSTED 0xf234007f -/*P2_AGCREFADJ*/ +/* P2_AGCREFADJ */ #define RSTV0910_P2_AGCREFADJ 0xf235 #define FSTV0910_P2_AGC2REF_ADJUSTED 0xf235007f -/*P2_AGC2I1*/ +/* P2_AGC2I1 */ #define RSTV0910_P2_AGC2I1 0xf236 #define FSTV0910_P2_AGC2_INTEGRATOR1 0xf23600ff -/*P2_AGC2I0*/ +/* P2_AGC2I0 */ #define RSTV0910_P2_AGC2I0 0xf237 #define FSTV0910_P2_AGC2_INTEGRATOR0 0xf23700ff -/*P2_CARCFG*/ +/* P2_CARCFG */ #define RSTV0910_P2_CARCFG 0xf238 #define FSTV0910_P2_ROTAON 0xf2380004 #define FSTV0910_P2_PH_DET_ALGO 0xf2380003 -/*P2_ACLC*/ +/* P2_ACLC */ #define RSTV0910_P2_ACLC 0xf239 #define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030 #define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f -/*P2_BCLC*/ +/* P2_BCLC */ #define RSTV0910_P2_BCLC 0xf23a #define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030 #define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f -/*P2_ACLCS2*/ +/* P2_ACLCS2 */ #define RSTV0910_P2_ACLCS2 0xf23b #define FSTV0910_P2_CARS2_APLHA_MANTISSE 0xf23b0030 #define FSTV0910_P2_CARS2_ALPHA_EXP 0xf23b000f -/*P2_BCLCS2*/ +/* P2_BCLCS2 */ #define RSTV0910_P2_BCLCS2 0xf23c #define FSTV0910_P2_CARS2_BETA_MANTISSE 0xf23c0030 #define FSTV0910_P2_CARS2_BETA_EXP 0xf23c000f -/*P2_CARFREQ*/ +/* P2_CARFREQ */ #define RSTV0910_P2_CARFREQ 0xf23d #define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0 #define FSTV0910_P2_BETA_FREQ 0xf23d000f -/*P2_CARHDR*/ +/* P2_CARHDR */ #define RSTV0910_P2_CARHDR 0xf23e #define FSTV0910_P2_K_FREQ_HDR 0xf23e00ff -/*P2_LDT*/ +/* P2_LDT */ #define RSTV0910_P2_LDT 0xf23f #define FSTV0910_P2_CARLOCK_THRES 0xf23f01ff -/*P2_LDT2*/ +/* P2_LDT2 */ #define RSTV0910_P2_LDT2 0xf240 #define FSTV0910_P2_CARLOCK_THRES2 0xf24001ff -/*P2_CFRICFG*/ +/* P2_CFRICFG */ #define RSTV0910_P2_CFRICFG 0xf241 #define FSTV0910_P2_NEG_CFRSTEP 0xf2410001 -/*P2_CFRUP1*/ +/* P2_CFRUP1 */ #define RSTV0910_P2_CFRUP1 0xf242 #define FSTV0910_P2_CFR_UP1 0xf24201ff -/*P2_CFRUP0*/ +/* P2_CFRUP0 */ #define RSTV0910_P2_CFRUP0 0xf243 #define FSTV0910_P2_CFR_UP0 0xf24300ff -/*P2_CFRIBASE1*/ +/* P2_CFRIBASE1 */ #define RSTV0910_P2_CFRIBASE1 0xf244 #define FSTV0910_P2_CFRINIT_BASE1 0xf24400ff -/*P2_CFRIBASE0*/ +/* P2_CFRIBASE0 */ #define RSTV0910_P2_CFRIBASE0 0xf245 #define FSTV0910_P2_CFRINIT_BASE0 0xf24500ff -/*P2_CFRLOW1*/ +/* P2_CFRLOW1 */ #define RSTV0910_P2_CFRLOW1 0xf246 #define FSTV0910_P2_CFR_LOW1 0xf24601ff -/*P2_CFRLOW0*/ +/* P2_CFRLOW0 */ #define RSTV0910_P2_CFRLOW0 0xf247 #define FSTV0910_P2_CFR_LOW0 0xf24700ff -/*P2_CFRINIT1*/ +/* P2_CFRINIT1 */ #define RSTV0910_P2_CFRINIT1 0xf248 #define FSTV0910_P2_CFR_INIT1 0xf24801ff -/*P2_CFRINIT0*/ +/* P2_CFRINIT0 */ #define RSTV0910_P2_CFRINIT0 0xf249 #define FSTV0910_P2_CFR_INIT0 0xf24900ff -/*P2_CFRINC1*/ +/* P2_CFRINC1 */ #define RSTV0910_P2_CFRINC1 0xf24a #define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080 #define FSTV0910_P2_CFR_INC1 0xf24a003f -/*P2_CFRINC0*/ +/* P2_CFRINC0 */ #define RSTV0910_P2_CFRINC0 0xf24b #define FSTV0910_P2_CFR_INC0 0xf24b00ff -/*P2_CFR2*/ +/* P2_CFR2 */ #define RSTV0910_P2_CFR2 0xf24c #define FSTV0910_P2_CAR_FREQ2 0xf24c01ff -/*P2_CFR1*/ +/* P2_CFR1 */ #define RSTV0910_P2_CFR1 0xf24d #define FSTV0910_P2_CAR_FREQ1 0xf24d00ff -/*P2_CFR0*/ +/* P2_CFR0 */ #define RSTV0910_P2_CFR0 0xf24e #define FSTV0910_P2_CAR_FREQ0 0xf24e00ff -/*P2_LDI*/ +/* P2_LDI */ #define RSTV0910_P2_LDI 0xf24f #define FSTV0910_P2_LOCK_DET_INTEGR 0xf24f01ff -/*P2_TMGCFG*/ +/* P2_TMGCFG */ #define RSTV0910_P2_TMGCFG 0xf250 #define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0 #define FSTV0910_P2_DO_TIMING_CORR 0xf2500010 #define FSTV0910_P2_TMG_MINFREQ 0xf2500003 -/*P2_RTC*/ +/* P2_RTC */ #define RSTV0910_P2_RTC 0xf251 #define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0 #define FSTV0910_P2_TMGBETA_EXP 0xf251000f -/*P2_RTCS2*/ +/* P2_RTCS2 */ #define RSTV0910_P2_RTCS2 0xf252 #define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0 #define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f -/*P2_TMGTHRISE*/ +/* P2_TMGTHRISE */ #define RSTV0910_P2_TMGTHRISE 0xf253 #define FSTV0910_P2_TMGLOCK_THRISE 0xf25300ff -/*P2_TMGTHFALL*/ +/* P2_TMGTHFALL */ #define RSTV0910_P2_TMGTHFALL 0xf254 #define FSTV0910_P2_TMGLOCK_THFALL 0xf25400ff -/*P2_SFRUPRATIO*/ +/* P2_SFRUPRATIO */ #define RSTV0910_P2_SFRUPRATIO 0xf255 #define FSTV0910_P2_SFR_UPRATIO 0xf25500ff -/*P2_SFRLOWRATIO*/ +/* P2_SFRLOWRATIO */ #define RSTV0910_P2_SFRLOWRATIO 0xf256 #define FSTV0910_P2_SFR_LOWRATIO 0xf25600ff -/*P2_KTTMG*/ +/* P2_KTTMG */ #define RSTV0910_P2_KTTMG 0xf257 #define FSTV0910_P2_KT_TMG_EXP 0xf25700f0 -/*P2_KREFTMG*/ +/* P2_KREFTMG */ #define RSTV0910_P2_KREFTMG 0xf258 #define FSTV0910_P2_KREF_TMG 0xf25800ff -/*P2_SFRSTEP*/ +/* P2_SFRSTEP */ #define RSTV0910_P2_SFRSTEP 0xf259 #define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0 #define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f -/*P2_TMGCFG2*/ +/* P2_TMGCFG2 */ #define RSTV0910_P2_TMGCFG2 0xf25a #define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008 #define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001 -/*P2_KREFTMG2*/ +/* P2_KREFTMG2 */ #define RSTV0910_P2_KREFTMG2 0xf25b #define FSTV0910_P2_KREF_TMG2 0xf25b00ff -/*P2_TMGCFG3*/ +/* P2_TMGCFG3 */ #define RSTV0910_P2_TMGCFG3 0xf25d #define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008 #define FSTV0910_P2_AUTO_GUP 0xf25d0004 #define FSTV0910_P2_AUTO_GLOW 0xf25d0002 -/*P2_SFRINIT1*/ +/* P2_SFRINIT1 */ #define RSTV0910_P2_SFRINIT1 0xf25e #define FSTV0910_P2_SFR_INIT1 0xf25e00ff -/*P2_SFRINIT0*/ +/* P2_SFRINIT0 */ #define RSTV0910_P2_SFRINIT0 0xf25f #define FSTV0910_P2_SFR_INIT0 0xf25f00ff -/*P2_SFRUP1*/ +/* P2_SFRUP1 */ #define RSTV0910_P2_SFRUP1 0xf260 #define FSTV0910_P2_SYMB_FREQ_UP1 0xf26000ff -/*P2_SFRUP0*/ +/* P2_SFRUP0 */ #define RSTV0910_P2_SFRUP0 0xf261 #define FSTV0910_P2_SYMB_FREQ_UP0 0xf26100ff -/*P2_SFRLOW1*/ +/* P2_SFRLOW1 */ #define RSTV0910_P2_SFRLOW1 0xf262 #define FSTV0910_P2_SYMB_FREQ_LOW1 0xf26200ff -/*P2_SFRLOW0*/ +/* P2_SFRLOW0 */ #define RSTV0910_P2_SFRLOW0 0xf263 #define FSTV0910_P2_SYMB_FREQ_LOW0 0xf26300ff -/*P2_SFR3*/ +/* P2_SFR3 */ #define RSTV0910_P2_SFR3 0xf264 #define FSTV0910_P2_SYMB_FREQ3 0xf26400ff -/*P2_SFR2*/ +/* P2_SFR2 */ #define RSTV0910_P2_SFR2 0xf265 #define FSTV0910_P2_SYMB_FREQ2 0xf26500ff -/*P2_SFR1*/ +/* P2_SFR1 */ #define RSTV0910_P2_SFR1 0xf266 #define FSTV0910_P2_SYMB_FREQ1 0xf26600ff -/*P2_SFR0*/ +/* P2_SFR0 */ #define RSTV0910_P2_SFR0 0xf267 #define FSTV0910_P2_SYMB_FREQ0 0xf26700ff -/*P2_TMGREG2*/ +/* P2_TMGREG2 */ #define RSTV0910_P2_TMGREG2 0xf268 #define FSTV0910_P2_TMGREG2 0xf26800ff -/*P2_TMGREG1*/ +/* P2_TMGREG1 */ #define RSTV0910_P2_TMGREG1 0xf269 #define FSTV0910_P2_TMGREG1 0xf26900ff -/*P2_TMGREG0*/ +/* P2_TMGREG0 */ #define RSTV0910_P2_TMGREG0 0xf26a #define FSTV0910_P2_TMGREG0 0xf26a00ff -/*P2_TMGLOCK1*/ +/* P2_TMGLOCK1 */ #define RSTV0910_P2_TMGLOCK1 0xf26b #define FSTV0910_P2_TMGLOCK_LEVEL1 0xf26b01ff -/*P2_TMGLOCK0*/ +/* P2_TMGLOCK0 */ #define RSTV0910_P2_TMGLOCK0 0xf26c #define FSTV0910_P2_TMGLOCK_LEVEL0 0xf26c00ff -/*P2_TMGOBS*/ +/* P2_TMGOBS */ #define RSTV0910_P2_TMGOBS 0xf26d #define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0 -/*P2_EQUALCFG*/ +/* P2_EQUALCFG */ #define RSTV0910_P2_EQUALCFG 0xf26f #define FSTV0910_P2_EQUAL_ON 0xf26f0040 #define FSTV0910_P2_MU_EQUALDFE 0xf26f0007 -/*P2_EQUAI1*/ +/* P2_EQUAI1 */ #define RSTV0910_P2_EQUAI1 0xf270 #define FSTV0910_P2_EQUA_ACCI1 0xf27001ff -/*P2_EQUAQ1*/ +/* P2_EQUAQ1 */ #define RSTV0910_P2_EQUAQ1 0xf271 #define FSTV0910_P2_EQUA_ACCQ1 0xf27101ff -/*P2_EQUAI2*/ +/* P2_EQUAI2 */ #define RSTV0910_P2_EQUAI2 0xf272 #define FSTV0910_P2_EQUA_ACCI2 0xf27201ff -/*P2_EQUAQ2*/ +/* P2_EQUAQ2 */ #define RSTV0910_P2_EQUAQ2 0xf273 #define FSTV0910_P2_EQUA_ACCQ2 0xf27301ff -/*P2_EQUAI3*/ +/* P2_EQUAI3 */ #define RSTV0910_P2_EQUAI3 0xf274 #define FSTV0910_P2_EQUA_ACCI3 0xf27401ff -/*P2_EQUAQ3*/ +/* P2_EQUAQ3 */ #define RSTV0910_P2_EQUAQ3 0xf275 #define FSTV0910_P2_EQUA_ACCQ3 0xf27501ff -/*P2_EQUAI4*/ +/* P2_EQUAI4 */ #define RSTV0910_P2_EQUAI4 0xf276 #define FSTV0910_P2_EQUA_ACCI4 0xf27601ff -/*P2_EQUAQ4*/ +/* P2_EQUAQ4 */ #define RSTV0910_P2_EQUAQ4 0xf277 #define FSTV0910_P2_EQUA_ACCQ4 0xf27701ff -/*P2_EQUAI5*/ +/* P2_EQUAI5 */ #define RSTV0910_P2_EQUAI5 0xf278 #define FSTV0910_P2_EQUA_ACCI5 0xf27801ff -/*P2_EQUAQ5*/ +/* P2_EQUAQ5 */ #define RSTV0910_P2_EQUAQ5 0xf279 #define FSTV0910_P2_EQUA_ACCQ5 0xf27901ff -/*P2_EQUAI6*/ +/* P2_EQUAI6 */ #define RSTV0910_P2_EQUAI6 0xf27a #define FSTV0910_P2_EQUA_ACCI6 0xf27a01ff -/*P2_EQUAQ6*/ +/* P2_EQUAQ6 */ #define RSTV0910_P2_EQUAQ6 0xf27b #define FSTV0910_P2_EQUA_ACCQ6 0xf27b01ff -/*P2_EQUAI7*/ +/* P2_EQUAI7 */ #define RSTV0910_P2_EQUAI7 0xf27c #define FSTV0910_P2_EQUA_ACCI7 0xf27c01ff -/*P2_EQUAQ7*/ +/* P2_EQUAQ7 */ #define RSTV0910_P2_EQUAQ7 0xf27d #define FSTV0910_P2_EQUA_ACCQ7 0xf27d01ff -/*P2_EQUAI8*/ +/* P2_EQUAI8 */ #define RSTV0910_P2_EQUAI8 0xf27e #define FSTV0910_P2_EQUA_ACCI8 0xf27e01ff -/*P2_EQUAQ8*/ +/* P2_EQUAQ8 */ #define RSTV0910_P2_EQUAQ8 0xf27f #define FSTV0910_P2_EQUA_ACCQ8 0xf27f01ff -/*P2_NNOSDATAT1*/ +/* P2_NNOSDATAT1 */ #define RSTV0910_P2_NNOSDATAT1 0xf280 #define FSTV0910_P2_NOSDATAT_NORMED1 0xf28000ff -/*P2_NNOSDATAT0*/ +/* P2_NNOSDATAT0 */ #define RSTV0910_P2_NNOSDATAT0 0xf281 #define FSTV0910_P2_NOSDATAT_NORMED0 0xf28100ff -/*P2_NNOSDATA1*/ +/* P2_NNOSDATA1 */ #define RSTV0910_P2_NNOSDATA1 0xf282 #define FSTV0910_P2_NOSDATA_NORMED1 0xf28200ff -/*P2_NNOSDATA0*/ +/* P2_NNOSDATA0 */ #define RSTV0910_P2_NNOSDATA0 0xf283 #define FSTV0910_P2_NOSDATA_NORMED0 0xf28300ff -/*P2_NNOSPLHT1*/ +/* P2_NNOSPLHT1 */ #define RSTV0910_P2_NNOSPLHT1 0xf284 #define FSTV0910_P2_NOSPLHT_NORMED1 0xf28400ff -/*P2_NNOSPLHT0*/ +/* P2_NNOSPLHT0 */ #define RSTV0910_P2_NNOSPLHT0 0xf285 #define FSTV0910_P2_NOSPLHT_NORMED0 0xf28500ff -/*P2_NNOSPLH1*/ +/* P2_NNOSPLH1 */ #define RSTV0910_P2_NNOSPLH1 0xf286 #define FSTV0910_P2_NOSPLH_NORMED1 0xf28600ff -/*P2_NNOSPLH0*/ +/* P2_NNOSPLH0 */ #define RSTV0910_P2_NNOSPLH0 0xf287 #define FSTV0910_P2_NOSPLH_NORMED0 0xf28700ff -/*P2_NOSDATAT1*/ +/* P2_NOSDATAT1 */ #define RSTV0910_P2_NOSDATAT1 0xf288 #define FSTV0910_P2_NOSDATAT_UNNORMED1 0xf28800ff -/*P2_NOSDATAT0*/ +/* P2_NOSDATAT0 */ #define RSTV0910_P2_NOSDATAT0 0xf289 #define FSTV0910_P2_NOSDATAT_UNNORMED0 0xf28900ff -/*P2_NNOSFRAME1*/ +/* P2_NNOSFRAME1 */ #define RSTV0910_P2_NNOSFRAME1 0xf28a #define FSTV0910_P2_NOSFRAME_NORMED1 0xf28a00ff -/*P2_NNOSFRAME0*/ +/* P2_NNOSFRAME0 */ #define RSTV0910_P2_NNOSFRAME0 0xf28b #define FSTV0910_P2_NOSFRAME_NORMED0 0xf28b00ff -/*P2_NNOSRAD1*/ +/* P2_NNOSRAD1 */ #define RSTV0910_P2_NNOSRAD1 0xf28c #define FSTV0910_P2_NOSRADIAL_NORMED1 0xf28c00ff -/*P2_NNOSRAD0*/ +/* P2_NNOSRAD0 */ #define RSTV0910_P2_NNOSRAD0 0xf28d #define FSTV0910_P2_NOSRADIAL_NORMED0 0xf28d00ff -/*P2_NOSCFGF1*/ +/* P2_NOSCFGF1 */ #define RSTV0910_P2_NOSCFGF1 0xf28e #define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080 #define FSTV0910_P2_NOS_DELFRAME 0xf28e0040 @@ -1100,177 +1101,177 @@ #define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c #define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003 -/*P2_NOSCFGF2*/ +/* P2_NOSCFGF2 */ #define RSTV0910_P2_NOSCFGF2 0xf28f #define FSTV0910_P2_DIS_NOSPILOTS 0xf28f0080 #define FSTV0910_P2_FRAMESEL_MODCODSEL 0xf28f0060 #define FSTV0910_P2_FRAMESEL_MODCOD 0xf28f001f -/*P2_CAR2CFG*/ +/* P2_CAR2CFG */ #define RSTV0910_P2_CAR2CFG 0xf290 #define FSTV0910_P2_ROTA2ON 0xf2900004 #define FSTV0910_P2_PH_DET_ALGO2 0xf2900003 -/*P2_CFR2CFR1*/ +/* P2_CFR2CFR1 */ #define RSTV0910_P2_CFR2CFR1 0xf291 #define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020 #define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007 -/*P2_CAR3CFG*/ +/* P2_CAR3CFG */ #define RSTV0910_P2_CAR3CFG 0xf292 #define FSTV0910_P2_CARRIER23_MODE 0xf29200c0 #define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020 #define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018 #define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007 -/*P2_CFR22*/ +/* P2_CFR22 */ #define RSTV0910_P2_CFR22 0xf293 #define FSTV0910_P2_CAR2_FREQ2 0xf29301ff -/*P2_CFR21*/ +/* P2_CFR21 */ #define RSTV0910_P2_CFR21 0xf294 #define FSTV0910_P2_CAR2_FREQ1 0xf29400ff -/*P2_CFR20*/ +/* P2_CFR20 */ #define RSTV0910_P2_CFR20 0xf295 #define FSTV0910_P2_CAR2_FREQ0 0xf29500ff -/*P2_ACLC2S2Q*/ +/* P2_ACLC2S2Q */ #define RSTV0910_P2_ACLC2S2Q 0xf297 #define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080 #define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030 #define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f -/*P2_ACLC2S28*/ +/* P2_ACLC2S28 */ #define RSTV0910_P2_ACLC2S28 0xf298 #define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030 #define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f -/*P2_ACLC2S216A*/ +/* P2_ACLC2S216A */ #define RSTV0910_P2_ACLC2S216A 0xf299 #define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030 #define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f -/*P2_ACLC2S232A*/ +/* P2_ACLC2S232A */ #define RSTV0910_P2_ACLC2S232A 0xf29a #define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030 #define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f -/*P2_BCLC2S2Q*/ +/* P2_BCLC2S2Q */ #define RSTV0910_P2_BCLC2S2Q 0xf29c #define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030 #define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f -/*P2_BCLC2S28*/ +/* P2_BCLC2S28 */ #define RSTV0910_P2_BCLC2S28 0xf29d #define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030 #define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f -/*P2_BCLC2S216A*/ +/* P2_BCLC2S216A */ #define RSTV0910_P2_BCLC2S216A 0xf29e #define FSTV0910_P2_DVBS2S216A_NIP 0xf29e0080 #define FSTV0910_P2_CAR2S2_16A_BETA_M 0xf29e0030 #define FSTV0910_P2_CAR2S2_16A_BETA_E 0xf29e000f -/*P2_BCLC2S232A*/ +/* P2_BCLC2S232A */ #define RSTV0910_P2_BCLC2S232A 0xf29f #define FSTV0910_P2_DVBS2S232A_NIP 0xf29f0080 #define FSTV0910_P2_CAR2S2_32A_BETA_M 0xf29f0030 #define FSTV0910_P2_CAR2S2_32A_BETA_E 0xf29f000f -/*P2_PLROOT2*/ +/* P2_PLROOT2 */ #define RSTV0910_P2_PLROOT2 0xf2ac #define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c #define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003 -/*P2_PLROOT1*/ +/* P2_PLROOT1 */ #define RSTV0910_P2_PLROOT1 0xf2ad #define FSTV0910_P2_PLSCRAMB_ROOT1 0xf2ad00ff -/*P2_PLROOT0*/ +/* P2_PLROOT0 */ #define RSTV0910_P2_PLROOT0 0xf2ae #define FSTV0910_P2_PLSCRAMB_ROOT0 0xf2ae00ff -/*P2_MODCODLST0*/ +/* P2_MODCODLST0 */ #define RSTV0910_P2_MODCODLST0 0xf2b0 #define FSTV0910_P2_NACCES_MODCODCH 0xf2b00001 -/*P2_MODCODLST1*/ +/* P2_MODCODLST1 */ #define RSTV0910_P2_MODCODLST1 0xf2b1 #define FSTV0910_P2_SYMBRATE_FILTER 0xf2b10008 #define FSTV0910_P2_NRESET_MODCODLST 0xf2b10004 #define FSTV0910_P2_DIS_32PSK_9_10 0xf2b10003 -/*P2_MODCODLST2*/ +/* P2_MODCODLST2 */ #define RSTV0910_P2_MODCODLST2 0xf2b2 #define FSTV0910_P2_DIS_32PSK_8_9 0xf2b200f0 #define FSTV0910_P2_DIS_32PSK_5_6 0xf2b2000f -/*P2_MODCODLST3*/ +/* P2_MODCODLST3 */ #define RSTV0910_P2_MODCODLST3 0xf2b3 #define FSTV0910_P2_DIS_32PSK_4_5 0xf2b300f0 #define FSTV0910_P2_DIS_32PSK_3_4 0xf2b3000f -/*P2_MODCODLST4*/ +/* P2_MODCODLST4 */ #define RSTV0910_P2_MODCODLST4 0xf2b4 #define FSTV0910_P2_DUMMYPL_PILOT 0xf2b40080 #define FSTV0910_P2_DUMMYPL_NOPILOT 0xf2b40040 #define FSTV0910_P2_DIS_16PSK_9_10 0xf2b40030 #define FSTV0910_P2_DIS_16PSK_8_9 0xf2b4000f -/*P2_MODCODLST5*/ +/* P2_MODCODLST5 */ #define RSTV0910_P2_MODCODLST5 0xf2b5 #define FSTV0910_P2_DIS_16PSK_5_6 0xf2b500f0 #define FSTV0910_P2_DIS_16PSK_4_5 0xf2b5000f -/*P2_MODCODLST6*/ +/* P2_MODCODLST6 */ #define RSTV0910_P2_MODCODLST6 0xf2b6 #define FSTV0910_P2_DIS_16PSK_3_4 0xf2b600f0 #define FSTV0910_P2_DIS_16PSK_2_3 0xf2b6000f -/*P2_MODCODLST7*/ +/* P2_MODCODLST7 */ #define RSTV0910_P2_MODCODLST7 0xf2b7 #define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080 #define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030 #define FSTV0910_P2_DIS_8PSK_8_9 0xf2b7000f -/*P2_MODCODLST8*/ +/* P2_MODCODLST8 */ #define RSTV0910_P2_MODCODLST8 0xf2b8 #define FSTV0910_P2_DIS_8PSK_5_6 0xf2b800f0 #define FSTV0910_P2_DIS_8PSK_3_4 0xf2b8000f -/*P2_MODCODLST9*/ +/* P2_MODCODLST9 */ #define RSTV0910_P2_MODCODLST9 0xf2b9 #define FSTV0910_P2_DIS_8PSK_2_3 0xf2b900f0 #define FSTV0910_P2_DIS_8PSK_3_5 0xf2b9000f -/*P2_MODCODLSTA*/ +/* P2_MODCODLSTA */ #define RSTV0910_P2_MODCODLSTA 0xf2ba #define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080 #define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030 #define FSTV0910_P2_DIS_QPSK_8_9 0xf2ba000f -/*P2_MODCODLSTB*/ +/* P2_MODCODLSTB */ #define RSTV0910_P2_MODCODLSTB 0xf2bb #define FSTV0910_P2_DIS_QPSK_5_6 0xf2bb00f0 #define FSTV0910_P2_DIS_QPSK_4_5 0xf2bb000f -/*P2_MODCODLSTC*/ +/* P2_MODCODLSTC */ #define RSTV0910_P2_MODCODLSTC 0xf2bc #define FSTV0910_P2_DIS_QPSK_3_4 0xf2bc00f0 #define FSTV0910_P2_DIS_QPSK_2_3 0xf2bc000f -/*P2_MODCODLSTD*/ +/* P2_MODCODLSTD */ #define RSTV0910_P2_MODCODLSTD 0xf2bd #define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0 #define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f -/*P2_MODCODLSTE*/ +/* P2_MODCODLSTE */ #define RSTV0910_P2_MODCODLSTE 0xf2be #define FSTV0910_P2_DIS_QPSK_2_5 0xf2be00f0 #define FSTV0910_P2_DIS_QPSK_1_3 0xf2be000f -/*P2_MODCODLSTF*/ +/* P2_MODCODLSTF */ #define RSTV0910_P2_MODCODLSTF 0xf2bf #define FSTV0910_P2_DIS_QPSK_1_4 0xf2bf00f0 #define FSTV0910_P2_DEMOD_INVMODLST 0xf2bf0008 @@ -1278,30 +1279,30 @@ #define FSTV0910_P2_DDEMOD_NSET 0xf2bf0002 #define FSTV0910_P2_MODCOD_NSTOCK 0xf2bf0001 -/*P2_GAUSSR0*/ +/* P2_GAUSSR0 */ #define RSTV0910_P2_GAUSSR0 0xf2c0 #define FSTV0910_P2_EN_CCIMODE 0xf2c00080 #define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f -/*P2_CCIR0*/ +/* P2_CCIR0 */ #define RSTV0910_P2_CCIR0 0xf2c1 #define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080 #define FSTV0910_P2_R0_CCI 0xf2c1007f -/*P2_CCIQUANT*/ +/* P2_CCIQUANT */ #define RSTV0910_P2_CCIQUANT 0xf2c2 #define FSTV0910_P2_CCI_BETA 0xf2c200e0 #define FSTV0910_P2_CCI_QUANT 0xf2c2001f -/*P2_CCITHRES*/ +/* P2_CCITHRES */ #define RSTV0910_P2_CCITHRES 0xf2c3 #define FSTV0910_P2_CCI_THRESHOLD 0xf2c300ff -/*P2_CCIACC*/ +/* P2_CCIACC */ #define RSTV0910_P2_CCIACC 0xf2c4 #define FSTV0910_P2_CCI_VALUE 0xf2c400ff -/*P2_DSTATUS4*/ +/* P2_DSTATUS4 */ #define RSTV0910_P2_DSTATUS4 0xf2c5 #define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080 #define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040 @@ -1310,234 +1311,234 @@ #define FSTV0910_P2_CSTENV_DETECT 0xf2c50002 #define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001 -/*P2_DMDRESCFG*/ +/* P2_DMDRESCFG */ #define RSTV0910_P2_DMDRESCFG 0xf2c6 #define FSTV0910_P2_DMDRES_RESET 0xf2c60080 #define FSTV0910_P2_DMDRES_STRALL 0xf2c60008 #define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004 #define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002 -/*P2_DMDRESADR*/ +/* P2_DMDRESADR */ #define RSTV0910_P2_DMDRESADR 0xf2c7 #define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040 #define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030 #define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f -/*P2_DMDRESDATA7*/ +/* P2_DMDRESDATA7 */ #define RSTV0910_P2_DMDRESDATA7 0xf2c8 #define FSTV0910_P2_DMDRES_DATA7 0xf2c800ff -/*P2_DMDRESDATA6*/ +/* P2_DMDRESDATA6 */ #define RSTV0910_P2_DMDRESDATA6 0xf2c9 #define FSTV0910_P2_DMDRES_DATA6 0xf2c900ff -/*P2_DMDRESDATA5*/ +/* P2_DMDRESDATA5 */ #define RSTV0910_P2_DMDRESDATA5 0xf2ca #define FSTV0910_P2_DMDRES_DATA5 0xf2ca00ff -/*P2_DMDRESDATA4*/ +/* P2_DMDRESDATA4 */ #define RSTV0910_P2_DMDRESDATA4 0xf2cb #define FSTV0910_P2_DMDRES_DATA4 0xf2cb00ff -/*P2_DMDRESDATA3*/ +/* P2_DMDRESDATA3 */ #define RSTV0910_P2_DMDRESDATA3 0xf2cc #define FSTV0910_P2_DMDRES_DATA3 0xf2cc00ff -/*P2_DMDRESDATA2*/ +/* P2_DMDRESDATA2 */ #define RSTV0910_P2_DMDRESDATA2 0xf2cd #define FSTV0910_P2_DMDRES_DATA2 0xf2cd00ff -/*P2_DMDRESDATA1*/ +/* P2_DMDRESDATA1 */ #define RSTV0910_P2_DMDRESDATA1 0xf2ce #define FSTV0910_P2_DMDRES_DATA1 0xf2ce00ff -/*P2_DMDRESDATA0*/ +/* P2_DMDRESDATA0 */ #define RSTV0910_P2_DMDRESDATA0 0xf2cf #define FSTV0910_P2_DMDRES_DATA0 0xf2cf00ff -/*P2_FFEI1*/ +/* P2_FFEI1 */ #define RSTV0910_P2_FFEI1 0xf2d0 #define FSTV0910_P2_FFE_ACCI1 0xf2d001ff -/*P2_FFEQ1*/ +/* P2_FFEQ1 */ #define RSTV0910_P2_FFEQ1 0xf2d1 #define FSTV0910_P2_FFE_ACCQ1 0xf2d101ff -/*P2_FFEI2*/ +/* P2_FFEI2 */ #define RSTV0910_P2_FFEI2 0xf2d2 #define FSTV0910_P2_FFE_ACCI2 0xf2d201ff -/*P2_FFEQ2*/ +/* P2_FFEQ2 */ #define RSTV0910_P2_FFEQ2 0xf2d3 #define FSTV0910_P2_FFE_ACCQ2 0xf2d301ff -/*P2_FFEI3*/ +/* P2_FFEI3 */ #define RSTV0910_P2_FFEI3 0xf2d4 #define FSTV0910_P2_FFE_ACCI3 0xf2d401ff -/*P2_FFEQ3*/ +/* P2_FFEQ3 */ #define RSTV0910_P2_FFEQ3 0xf2d5 #define FSTV0910_P2_FFE_ACCQ3 0xf2d501ff -/*P2_FFEI4*/ +/* P2_FFEI4 */ #define RSTV0910_P2_FFEI4 0xf2d6 #define FSTV0910_P2_FFE_ACCI4 0xf2d601ff -/*P2_FFEQ4*/ +/* P2_FFEQ4 */ #define RSTV0910_P2_FFEQ4 0xf2d7 #define FSTV0910_P2_FFE_ACCQ4 0xf2d701ff -/*P2_FFECFG*/ +/* P2_FFECFG */ #define RSTV0910_P2_FFECFG 0xf2d8 #define FSTV0910_P2_EQUALFFE_ON 0xf2d80040 #define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030 #define FSTV0910_P2_MU_EQUALFFE 0xf2d80007 -/*P2_TNRCFG2*/ +/* P2_TNRCFG2 */ #define RSTV0910_P2_TNRCFG2 0xf2e1 #define FSTV0910_P2_TUN_IQSWAP 0xf2e10080 -/*P2_SMAPCOEF7*/ +/* P2_SMAPCOEF7 */ #define RSTV0910_P2_SMAPCOEF7 0xf300 #define FSTV0910_P2_DIS_QSCALE 0xf3000080 #define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f -/*P2_SMAPCOEF6*/ +/* P2_SMAPCOEF6 */ #define RSTV0910_P2_SMAPCOEF6 0xf301 #define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080 #define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004 #define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002 #define FSTV0910_P2_DIS_AB8PSK 0xf3010001 -/*P2_SMAPCOEF5*/ +/* P2_SMAPCOEF5 */ #define RSTV0910_P2_SMAPCOEF5 0xf302 #define FSTV0910_P2_DIS_8SCALE 0xf3020080 #define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f -/*P2_SMAPCOEF4*/ +/* P2_SMAPCOEF4 */ #define RSTV0910_P2_SMAPCOEF4 0xf303 #define FSTV0910_P2_SMAPCOEF_16APSK_LLR12 0xf303017f -/*P2_SMAPCOEF3*/ +/* P2_SMAPCOEF3 */ #define RSTV0910_P2_SMAPCOEF3 0xf304 #define FSTV0910_P2_SMAPCOEF_16APSK_LLR34 0xf304017f -/*P2_SMAPCOEF2*/ +/* P2_SMAPCOEF2 */ #define RSTV0910_P2_SMAPCOEF2 0xf305 #define FSTV0910_P2_SMAPCOEF_32APSK_R2R3 0xf30501f0 #define FSTV0910_P2_SMAPCOEF_32APSK_LLR2 0xf305010f -/*P2_SMAPCOEF1*/ +/* P2_SMAPCOEF1 */ #define RSTV0910_P2_SMAPCOEF1 0xf306 #define FSTV0910_P2_DIS_16SCALE 0xf3060080 #define FSTV0910_P2_SMAPCOEF_32_LLR34 0xf306017f -/*P2_SMAPCOEF0*/ +/* P2_SMAPCOEF0 */ #define RSTV0910_P2_SMAPCOEF0 0xf307 #define FSTV0910_P2_DIS_32SCALE 0xf3070080 #define FSTV0910_P2_SMAPCOEF_32_LLR15 0xf307017f -/*P2_NOSTHRES1*/ +/* P2_NOSTHRES1 */ #define RSTV0910_P2_NOSTHRES1 0xf309 #define FSTV0910_P2_NOS_THRESHOLD1 0xf30900ff -/*P2_NOSTHRES2*/ +/* P2_NOSTHRES2 */ #define RSTV0910_P2_NOSTHRES2 0xf30a #define FSTV0910_P2_NOS_THRESHOLD2 0xf30a00ff -/*P2_NOSDIFF1*/ +/* P2_NOSDIFF1 */ #define RSTV0910_P2_NOSDIFF1 0xf30b #define FSTV0910_P2_NOSTHRES1_DIFF 0xf30b00ff -/*P2_RAINFADE*/ +/* P2_RAINFADE */ #define RSTV0910_P2_RAINFADE 0xf30c #define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080 #define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070 #define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007 -/*P2_NOSRAMCFG*/ +/* P2_NOSRAMCFG */ #define RSTV0910_P2_NOSRAMCFG 0xf30d #define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030 #define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008 #define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007 -/*P2_NOSRAMPOS*/ +/* P2_NOSRAMPOS */ #define RSTV0910_P2_NOSRAMPOS 0xf30e #define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0 #define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004 #define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003 -/*P2_NOSRAMVAL*/ +/* P2_NOSRAMVAL */ #define RSTV0910_P2_NOSRAMVAL 0xf30f #define FSTV0910_P2_NOSRAM_CNRVAL0 0xf30f00ff -/*P2_DMDPLHSTAT*/ +/* P2_DMDPLHSTAT */ #define RSTV0910_P2_DMDPLHSTAT 0xf320 #define FSTV0910_P2_PLH_STATISTIC 0xf32000ff -/*P2_LOCKTIME3*/ +/* P2_LOCKTIME3 */ #define RSTV0910_P2_LOCKTIME3 0xf322 #define FSTV0910_P2_DEMOD_LOCKTIME3 0xf32200ff -/*P2_LOCKTIME2*/ +/* P2_LOCKTIME2 */ #define RSTV0910_P2_LOCKTIME2 0xf323 #define FSTV0910_P2_DEMOD_LOCKTIME2 0xf32300ff -/*P2_LOCKTIME1*/ +/* P2_LOCKTIME1 */ #define RSTV0910_P2_LOCKTIME1 0xf324 #define FSTV0910_P2_DEMOD_LOCKTIME1 0xf32400ff -/*P2_LOCKTIME0*/ +/* P2_LOCKTIME0 */ #define RSTV0910_P2_LOCKTIME0 0xf325 #define FSTV0910_P2_DEMOD_LOCKTIME0 0xf32500ff -/*P2_VITSCALE*/ +/* P2_VITSCALE */ #define RSTV0910_P2_VITSCALE 0xf332 #define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080 #define FSTV0910_P2_VERROR_MAXMODE 0xf3320040 #define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008 #define FSTV0910_P2_DIS_RSFLOCK 0xf3320002 -/*P2_FECM*/ +/* P2_FECM */ #define RSTV0910_P2_FECM 0xf333 #define FSTV0910_P2_DSS_DVB 0xf3330080 #define FSTV0910_P2_DSS_SRCH 0xf3330010 #define FSTV0910_P2_SYNCVIT 0xf3330002 #define FSTV0910_P2_IQINV 0xf3330001 -/*P2_VTH12*/ +/* P2_VTH12 */ #define RSTV0910_P2_VTH12 0xf334 #define FSTV0910_P2_VTH12 0xf33400ff -/*P2_VTH23*/ +/* P2_VTH23 */ #define RSTV0910_P2_VTH23 0xf335 #define FSTV0910_P2_VTH23 0xf33500ff -/*P2_VTH34*/ +/* P2_VTH34 */ #define RSTV0910_P2_VTH34 0xf336 #define FSTV0910_P2_VTH34 0xf33600ff -/*P2_VTH56*/ +/* P2_VTH56 */ #define RSTV0910_P2_VTH56 0xf337 #define FSTV0910_P2_VTH56 0xf33700ff -/*P2_VTH67*/ +/* P2_VTH67 */ #define RSTV0910_P2_VTH67 0xf338 #define FSTV0910_P2_VTH67 0xf33800ff -/*P2_VTH78*/ +/* P2_VTH78 */ #define RSTV0910_P2_VTH78 0xf339 #define FSTV0910_P2_VTH78 0xf33900ff -/*P2_VITCURPUN*/ +/* P2_VITCURPUN */ #define RSTV0910_P2_VITCURPUN 0xf33a #define FSTV0910_P2_VIT_CURPUN 0xf33a001f -/*P2_VERROR*/ +/* P2_VERROR */ #define RSTV0910_P2_VERROR 0xf33b #define FSTV0910_P2_REGERR_VIT 0xf33b00ff -/*P2_PRVIT*/ +/* P2_PRVIT */ #define RSTV0910_P2_PRVIT 0xf33c #define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040 #define FSTV0910_P2_E7_8VIT 0xf33c0020 @@ -1547,7 +1548,7 @@ #define FSTV0910_P2_E2_3VIT 0xf33c0002 #define FSTV0910_P2_E1_2VIT 0xf33c0001 -/*P2_VAVSRVIT*/ +/* P2_VAVSRVIT */ #define RSTV0910_P2_VAVSRVIT 0xf33d #define FSTV0910_P2_AMVIT 0xf33d0080 #define FSTV0910_P2_FROZENVIT 0xf33d0040 @@ -1555,52 +1556,52 @@ #define FSTV0910_P2_TOVVIT 0xf33d000c #define FSTV0910_P2_HYPVIT 0xf33d0003 -/*P2_VSTATUSVIT*/ +/* P2_VSTATUSVIT */ #define RSTV0910_P2_VSTATUSVIT 0xf33e #define FSTV0910_P2_PRFVIT 0xf33e0010 #define FSTV0910_P2_LOCKEDVIT 0xf33e0008 -/*P2_VTHINUSE*/ +/* P2_VTHINUSE */ #define RSTV0910_P2_VTHINUSE 0xf33f #define FSTV0910_P2_VIT_INUSE 0xf33f00ff -/*P2_KDIV12*/ +/* P2_KDIV12 */ #define RSTV0910_P2_KDIV12 0xf340 #define FSTV0910_P2_K_DIVIDER_12 0xf340007f -/*P2_KDIV23*/ +/* P2_KDIV23 */ #define RSTV0910_P2_KDIV23 0xf341 #define FSTV0910_P2_K_DIVIDER_23 0xf341007f -/*P2_KDIV34*/ +/* P2_KDIV34 */ #define RSTV0910_P2_KDIV34 0xf342 #define FSTV0910_P2_K_DIVIDER_34 0xf342007f -/*P2_KDIV56*/ +/* P2_KDIV56 */ #define RSTV0910_P2_KDIV56 0xf343 #define FSTV0910_P2_K_DIVIDER_56 0xf343007f -/*P2_KDIV67*/ +/* P2_KDIV67 */ #define RSTV0910_P2_KDIV67 0xf344 #define FSTV0910_P2_K_DIVIDER_67 0xf344007f -/*P2_KDIV78*/ +/* P2_KDIV78 */ #define RSTV0910_P2_KDIV78 0xf345 #define FSTV0910_P2_K_DIVIDER_78 0xf345007f -/*P2_TSPIDFLT1*/ +/* P2_TSPIDFLT1 */ #define RSTV0910_P2_TSPIDFLT1 0xf346 #define FSTV0910_P2_PIDFLT_ADDR 0xf34600ff -/*P2_TSPIDFLT0*/ +/* P2_TSPIDFLT0 */ #define RSTV0910_P2_TSPIDFLT0 0xf347 #define FSTV0910_P2_PIDFLT_DATA 0xf34700ff -/*P2_PDELCTRL0*/ +/* P2_PDELCTRL0 */ #define RSTV0910_P2_PDELCTRL0 0xf34f #define FSTV0910_P2_ISIOBS_MODE 0xf34f0030 -/*P2_PDELCTRL1*/ +/* P2_PDELCTRL1 */ #define RSTV0910_P2_PDELCTRL1 0xf350 #define FSTV0910_P2_INV_MISMASK 0xf3500080 #define FSTV0910_P2_FILTER_EN 0xf3500020 @@ -1609,68 +1610,68 @@ #define FSTV0910_P2_EN_MIS00 0xf3500002 #define FSTV0910_P2_ALGOSWRST 0xf3500001 -/*P2_PDELCTRL2*/ +/* P2_PDELCTRL2 */ #define RSTV0910_P2_PDELCTRL2 0xf351 #define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080 #define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040 #define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020 #define FSTV0910_P2_FRAME_MODE 0xf3510002 -/*P2_HYSTTHRESH*/ +/* P2_HYSTTHRESH */ #define RSTV0910_P2_HYSTTHRESH 0xf354 #define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0 #define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f -/*P2_UPLCCST0*/ +/* P2_UPLCCST0 */ #define RSTV0910_P2_UPLCCST0 0xf358 #define FSTV0910_P2_UPL_CST0 0xf35800f8 #define FSTV0910_P2_UPL_MODE 0xf3580007 -/*P2_ISIENTRY*/ +/* P2_ISIENTRY */ #define RSTV0910_P2_ISIENTRY 0xf35e #define FSTV0910_P2_ISI_ENTRY 0xf35e00ff -/*P2_ISIBITENA*/ +/* P2_ISIBITENA */ #define RSTV0910_P2_ISIBITENA 0xf35f #define FSTV0910_P2_ISI_BIT_EN 0xf35f00ff -/*P2_MATSTR1*/ +/* P2_MATSTR1 */ #define RSTV0910_P2_MATSTR1 0xf360 #define FSTV0910_P2_MATYPE_CURRENT1 0xf36000ff -/*P2_MATSTR0*/ +/* P2_MATSTR0 */ #define RSTV0910_P2_MATSTR0 0xf361 #define FSTV0910_P2_MATYPE_CURRENT0 0xf36100ff -/*P2_UPLSTR1*/ +/* P2_UPLSTR1 */ #define RSTV0910_P2_UPLSTR1 0xf362 #define FSTV0910_P2_UPL_CURRENT1 0xf36200ff -/*P2_UPLSTR0*/ +/* P2_UPLSTR0 */ #define RSTV0910_P2_UPLSTR0 0xf363 #define FSTV0910_P2_UPL_CURRENT0 0xf36300ff -/*P2_DFLSTR1*/ +/* P2_DFLSTR1 */ #define RSTV0910_P2_DFLSTR1 0xf364 #define FSTV0910_P2_DFL_CURRENT1 0xf36400ff -/*P2_DFLSTR0*/ +/* P2_DFLSTR0 */ #define RSTV0910_P2_DFLSTR0 0xf365 #define FSTV0910_P2_DFL_CURRENT0 0xf36500ff -/*P2_SYNCSTR*/ +/* P2_SYNCSTR */ #define RSTV0910_P2_SYNCSTR 0xf366 #define FSTV0910_P2_SYNC_CURRENT 0xf36600ff -/*P2_SYNCDSTR1*/ +/* P2_SYNCDSTR1 */ #define RSTV0910_P2_SYNCDSTR1 0xf367 #define FSTV0910_P2_SYNCD_CURRENT1 0xf36700ff -/*P2_SYNCDSTR0*/ +/* P2_SYNCDSTR0 */ #define RSTV0910_P2_SYNCDSTR0 0xf368 #define FSTV0910_P2_SYNCD_CURRENT0 0xf36800ff -/*P2_PDELSTATUS1*/ +/* P2_PDELSTATUS1 */ #define RSTV0910_P2_PDELSTATUS1 0xf369 #define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080 #define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040 @@ -1679,33 +1680,33 @@ #define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002 #define FSTV0910_P2_FIRST_LOCK 0xf3690001 -/*P2_PDELSTATUS2*/ +/* P2_PDELSTATUS2 */ #define RSTV0910_P2_PDELSTATUS2 0xf36a #define FSTV0910_P2_FRAME_MODCOD 0xf36a007c #define FSTV0910_P2_FRAME_TYPE 0xf36a0003 -/*P2_BBFCRCKO1*/ +/* P2_BBFCRCKO1 */ #define RSTV0910_P2_BBFCRCKO1 0xf36b #define FSTV0910_P2_BBHCRC_KOCNT1 0xf36b00ff -/*P2_BBFCRCKO0*/ +/* P2_BBFCRCKO0 */ #define RSTV0910_P2_BBFCRCKO0 0xf36c #define FSTV0910_P2_BBHCRC_KOCNT0 0xf36c00ff -/*P2_UPCRCKO1*/ +/* P2_UPCRCKO1 */ #define RSTV0910_P2_UPCRCKO1 0xf36d #define FSTV0910_P2_PKTCRC_KOCNT1 0xf36d00ff -/*P2_UPCRCKO0*/ +/* P2_UPCRCKO0 */ #define RSTV0910_P2_UPCRCKO0 0xf36e #define FSTV0910_P2_PKTCRC_KOCNT0 0xf36e00ff -/*P2_PDELCTRL3*/ +/* P2_PDELCTRL3 */ #define RSTV0910_P2_PDELCTRL3 0xf36f #define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020 #define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010 -/*P2_TSSTATEM*/ +/* P2_TSSTATEM */ #define RSTV0910_P2_TSSTATEM 0xf370 #define FSTV0910_P2_TSDIL_ON 0xf3700080 #define FSTV0910_P2_TSRS_ON 0xf3700020 @@ -1715,7 +1716,7 @@ #define FSTV0910_P2_TSACM_MODE 0xf3700002 #define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001 -/*P2_TSSTATEL*/ +/* P2_TSSTATEL */ #define RSTV0910_P2_TSSTATEL 0xf371 #define FSTV0910_P2_TSNOSYNCBYTE 0xf3710080 #define FSTV0910_P2_TSPARITY_ON 0xf3710040 @@ -1724,7 +1725,7 @@ #define FSTV0910_P2_TSCRC8_ON 0xf3710002 #define FSTV0910_P2_TSDSS_PACKET 0xf3710001 -/*P2_TSCFGH*/ +/* P2_TSCFGH */ #define RSTV0910_P2_TSCFGH 0xf372 #define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080 #define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040 @@ -1734,14 +1735,14 @@ #define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006 #define FSTV0910_P2_RST_HWARE 0xf3720001 -/*P2_TSCFGM*/ +/* P2_TSCFGM */ #define RSTV0910_P2_TSCFGM 0xf373 #define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0 #define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020 #define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010 #define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001 -/*P2_TSCFGL*/ +/* P2_TSCFGL */ #define RSTV0910_P2_TSCFGL 0xf374 #define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0 #define FSTV0910_P2_BCHERROR_MODE 0xf3740030 @@ -1749,11 +1750,11 @@ #define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004 #define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003 -/*P2_TSSYNC*/ +/* P2_TSSYNC */ #define RSTV0910_P2_TSSYNC 0xf375 #define FSTV0910_P2_TSFIFO_SYNCMODE 0xf3750018 -/*P2_TSINSDELH*/ +/* P2_TSINSDELH */ #define RSTV0910_P2_TSINSDELH 0xf376 #define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080 #define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040 @@ -1761,7 +1762,7 @@ #define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002 #define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001 -/*P2_TSINSDELM*/ +/* P2_TSINSDELM */ #define RSTV0910_P2_TSINSDELM 0xf377 #define FSTV0910_P2_TSINS_EMODCOD 0xf3770010 #define FSTV0910_P2_TSINS_TOKEN 0xf3770008 @@ -1769,7 +1770,7 @@ #define FSTV0910_P2_TSINS_MATYPE 0xf3770002 #define FSTV0910_P2_TSINS_UPL 0xf3770001 -/*P2_TSINSDELL*/ +/* P2_TSINSDELL */ #define RSTV0910_P2_TSINSDELL 0xf378 #define FSTV0910_P2_TSINS_DFL 0xf3780080 #define FSTV0910_P2_TSINS_SYNCD 0xf3780040 @@ -1780,20 +1781,20 @@ #define FSTV0910_P2_TSINS_TSCONFIG 0xf3780002 #define FSTV0910_P2_TSINS_LATENCY 0xf3780001 -/*P2_TSDIVN*/ +/* P2_TSDIVN */ #define RSTV0910_P2_TSDIVN 0xf379 #define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0 #define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007 -/*P2_TSCFG4*/ +/* P2_TSCFG4 */ #define RSTV0910_P2_TSCFG4 0xf37a #define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0 -/*P2_TSSPEED*/ +/* P2_TSSPEED */ #define RSTV0910_P2_TSSPEED 0xf380 #define FSTV0910_P2_TSFIFO_OUTSPEED 0xf38000ff -/*P2_TSSTATUS*/ +/* P2_TSSTATUS */ #define RSTV0910_P2_TSSTATUS 0xf381 #define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080 #define FSTV0910_P2_TSFIFO_ERROR 0xf3810040 @@ -1801,111 +1802,111 @@ #define FSTV0910_P2_TSREGUL_ERROR 0xf3810004 #define FSTV0910_P2_DIL_READY 0xf3810001 -/*P2_TSSTATUS2*/ +/* P2_TSSTATUS2 */ #define RSTV0910_P2_TSSTATUS2 0xf382 #define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080 #define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040 #define FSTV0910_P2_DILXX_RESET 0xf3820020 #define FSTV0910_P2_SCRAMBDETECT 0xf3820002 -/*P2_TSBITRATE1*/ +/* P2_TSBITRATE1 */ #define RSTV0910_P2_TSBITRATE1 0xf383 #define FSTV0910_P2_TSFIFO_BITRATE1 0xf38300ff -/*P2_TSBITRATE0*/ +/* P2_TSBITRATE0 */ #define RSTV0910_P2_TSBITRATE0 0xf384 #define FSTV0910_P2_TSFIFO_BITRATE0 0xf38400ff -/*P2_TSPACKLEN1*/ +/* P2_TSPACKLEN1 */ #define RSTV0910_P2_TSPACKLEN1 0xf385 #define FSTV0910_P2_TSFIFO_PACKCPT 0xf38500e0 -/*P2_TSDLY2*/ +/* P2_TSDLY2 */ #define RSTV0910_P2_TSDLY2 0xf389 #define FSTV0910_P2_SOFFIFO_LATENCY2 0xf389000f -/*P2_TSDLY1*/ +/* P2_TSDLY1 */ #define RSTV0910_P2_TSDLY1 0xf38a #define FSTV0910_P2_SOFFIFO_LATENCY1 0xf38a00ff -/*P2_TSDLY0*/ +/* P2_TSDLY0 */ #define RSTV0910_P2_TSDLY0 0xf38b #define FSTV0910_P2_SOFFIFO_LATENCY0 0xf38b00ff -/*P2_TSNPDAV*/ +/* P2_TSNPDAV */ #define RSTV0910_P2_TSNPDAV 0xf38c #define FSTV0910_P2_TSNPD_AVERAGE 0xf38c00ff -/*P2_TSBUFSTAT2*/ +/* P2_TSBUFSTAT2 */ #define RSTV0910_P2_TSBUFSTAT2 0xf38d #define FSTV0910_P2_TSISCR_3BYTES 0xf38d0080 #define FSTV0910_P2_TSISCR_NEWDATA 0xf38d0040 #define FSTV0910_P2_TSISCR_BUFSTAT2 0xf38d003f -/*P2_TSBUFSTAT1*/ +/* P2_TSBUFSTAT1 */ #define RSTV0910_P2_TSBUFSTAT1 0xf38e #define FSTV0910_P2_TSISCR_BUFSTAT1 0xf38e00ff -/*P2_TSBUFSTAT0*/ +/* P2_TSBUFSTAT0 */ #define RSTV0910_P2_TSBUFSTAT0 0xf38f #define FSTV0910_P2_TSISCR_BUFSTAT0 0xf38f00ff -/*P2_TSDEBUGL*/ +/* P2_TSDEBUGL */ #define RSTV0910_P2_TSDEBUGL 0xf391 #define FSTV0910_P2_TSFIFO_ERROR_EVNT 0xf3910004 #define FSTV0910_P2_TSFIFO_OVERFLOWM 0xf3910001 -/*P2_TSDLYSET2*/ +/* P2_TSDLYSET2 */ #define RSTV0910_P2_TSDLYSET2 0xf392 #define FSTV0910_P2_SOFFIFO_OFFSET 0xf39200c0 #define FSTV0910_P2_HYSTERESIS_THRESHOLD 0xf3920030 #define FSTV0910_P2_SOFFIFO_SYMBOFFS2 0xf392000f -/*P2_TSDLYSET1*/ +/* P2_TSDLYSET1 */ #define RSTV0910_P2_TSDLYSET1 0xf393 #define FSTV0910_P2_SOFFIFO_SYMBOFFS1 0xf39300ff -/*P2_TSDLYSET0*/ +/* P2_TSDLYSET0 */ #define RSTV0910_P2_TSDLYSET0 0xf394 #define FSTV0910_P2_SOFFIFO_SYMBOFFS0 0xf39400ff -/*P2_ERRCTRL1*/ +/* P2_ERRCTRL1 */ #define RSTV0910_P2_ERRCTRL1 0xf398 #define FSTV0910_P2_ERR_SOURCE1 0xf39800f0 #define FSTV0910_P2_NUM_EVENT1 0xf3980007 -/*P2_ERRCNT12*/ +/* P2_ERRCNT12 */ #define RSTV0910_P2_ERRCNT12 0xf399 #define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080 #define FSTV0910_P2_ERR_CNT12 0xf399007f -/*P2_ERRCNT11*/ +/* P2_ERRCNT11 */ #define RSTV0910_P2_ERRCNT11 0xf39a #define FSTV0910_P2_ERR_CNT11 0xf39a00ff -/*P2_ERRCNT10*/ +/* P2_ERRCNT10 */ #define RSTV0910_P2_ERRCNT10 0xf39b #define FSTV0910_P2_ERR_CNT10 0xf39b00ff -/*P2_ERRCTRL2*/ +/* P2_ERRCTRL2 */ #define RSTV0910_P2_ERRCTRL2 0xf39c #define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0 #define FSTV0910_P2_NUM_EVENT2 0xf39c0007 -/*P2_ERRCNT22*/ +/* P2_ERRCNT22 */ #define RSTV0910_P2_ERRCNT22 0xf39d #define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080 #define FSTV0910_P2_ERR_CNT22 0xf39d007f -/*P2_ERRCNT21*/ +/* P2_ERRCNT21 */ #define RSTV0910_P2_ERRCNT21 0xf39e #define FSTV0910_P2_ERR_CNT21 0xf39e00ff -/*P2_ERRCNT20*/ +/* P2_ERRCNT20 */ #define RSTV0910_P2_ERRCNT20 0xf39f #define FSTV0910_P2_ERR_CNT20 0xf39f00ff -/*P2_FECSPY*/ +/* P2_FECSPY */ #define RSTV0910_P2_FECSPY 0xf3a0 #define FSTV0910_P2_SPY_ENABLE 0xf3a00080 #define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040 @@ -1915,7 +1916,7 @@ #define FSTV0910_P2_BERMETER_LMODE 0xf3a00002 #define FSTV0910_P2_BERMETER_RESET 0xf3a00001 -/*P2_FSPYCFG*/ +/* P2_FSPYCFG */ #define RSTV0910_P2_FSPYCFG 0xf3a1 #define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0 #define FSTV0910_P2_RST_ON_ERROR 0xf3a10020 @@ -1923,18 +1924,18 @@ #define FSTV0910_P2_I2C_MODE 0xf3a1000c #define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003 -/*P2_FSPYDATA*/ +/* P2_FSPYDATA */ #define RSTV0910_P2_FSPYDATA 0xf3a2 #define FSTV0910_P2_SPY_STUFFING 0xf3a20080 #define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020 #define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f -/*P2_FSPYOUT*/ +/* P2_FSPYOUT */ #define RSTV0910_P2_FSPYOUT 0xf3a3 #define FSTV0910_P2_FSPY_DIRECT 0xf3a30080 #define FSTV0910_P2_STUFF_MODE 0xf3a30007 -/*P2_FSTATUS*/ +/* P2_FSTATUS */ #define RSTV0910_P2_FSTATUS 0xf3a4 #define FSTV0910_P2_SPY_ENDSIM 0xf3a40080 #define FSTV0910_P2_VALID_SIM 0xf3a40040 @@ -1942,49 +1943,49 @@ #define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010 #define FSTV0910_P2_RESULT_STATE 0xf3a4000f -/*P2_FBERCPT4*/ +/* P2_FBERCPT4 */ #define RSTV0910_P2_FBERCPT4 0xf3a8 #define FSTV0910_P2_FBERMETER_CPT4 0xf3a800ff -/*P2_FBERCPT3*/ +/* P2_FBERCPT3 */ #define RSTV0910_P2_FBERCPT3 0xf3a9 #define FSTV0910_P2_FBERMETER_CPT3 0xf3a900ff -/*P2_FBERCPT2*/ +/* P2_FBERCPT2 */ #define RSTV0910_P2_FBERCPT2 0xf3aa #define FSTV0910_P2_FBERMETER_CPT2 0xf3aa00ff -/*P2_FBERCPT1*/ +/* P2_FBERCPT1 */ #define RSTV0910_P2_FBERCPT1 0xf3ab #define FSTV0910_P2_FBERMETER_CPT1 0xf3ab00ff -/*P2_FBERCPT0*/ +/* P2_FBERCPT0 */ #define RSTV0910_P2_FBERCPT0 0xf3ac #define FSTV0910_P2_FBERMETER_CPT0 0xf3ac00ff -/*P2_FBERERR2*/ +/* P2_FBERERR2 */ #define RSTV0910_P2_FBERERR2 0xf3ad #define FSTV0910_P2_FBERMETER_ERR2 0xf3ad00ff -/*P2_FBERERR1*/ +/* P2_FBERERR1 */ #define RSTV0910_P2_FBERERR1 0xf3ae #define FSTV0910_P2_FBERMETER_ERR1 0xf3ae00ff -/*P2_FBERERR0*/ +/* P2_FBERERR0 */ #define RSTV0910_P2_FBERERR0 0xf3af #define FSTV0910_P2_FBERMETER_ERR0 0xf3af00ff -/*P2_FSPYBER*/ +/* P2_FSPYBER */ #define RSTV0910_P2_FSPYBER 0xf3b2 #define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010 #define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008 #define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007 -/*P2_SFERROR*/ +/* P2_SFERROR */ #define RSTV0910_P2_SFERROR 0xf3c1 #define FSTV0910_P2_SFEC_REGERR_VIT 0xf3c100ff -/*P2_SFECSTATUS*/ +/* P2_SFECSTATUS */ #define RSTV0910_P2_SFECSTATUS 0xf3c3 #define FSTV0910_P2_SFEC_ON 0xf3c30080 #define FSTV0910_P2_SFEC_OFF 0xf3c30040 @@ -1993,31 +1994,31 @@ #define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002 #define FSTV0910_P2_SFEC_OVFON 0xf3c30001 -/*P2_SFKDIV12*/ +/* P2_SFKDIV12 */ #define RSTV0910_P2_SFKDIV12 0xf3c4 #define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080 -/*P2_SFKDIV23*/ +/* P2_SFKDIV23 */ #define RSTV0910_P2_SFKDIV23 0xf3c5 #define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080 -/*P2_SFKDIV34*/ +/* P2_SFKDIV34 */ #define RSTV0910_P2_SFKDIV34 0xf3c6 #define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080 -/*P2_SFKDIV56*/ +/* P2_SFKDIV56 */ #define RSTV0910_P2_SFKDIV56 0xf3c7 #define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080 -/*P2_SFKDIV67*/ +/* P2_SFKDIV67 */ #define RSTV0910_P2_SFKDIV67 0xf3c8 #define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080 -/*P2_SFKDIV78*/ +/* P2_SFKDIV78 */ #define RSTV0910_P2_SFKDIV78 0xf3c9 #define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080 -/*P2_SFSTATUS*/ +/* P2_SFSTATUS */ #define RSTV0910_P2_SFSTATUS 0xf3cc #define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080 #define FSTV0910_P2_SFEC_ERROR 0xf3cc0040 @@ -2028,48 +2029,48 @@ #define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002 #define FSTV0910_P2_SFEC_READY 0xf3cc0001 -/*P2_SFDLYSET2*/ +/* P2_SFDLYSET2 */ #define RSTV0910_P2_SFDLYSET2 0xf3d0 #define FSTV0910_P2_SFEC_DISABLE 0xf3d00002 -/*P2_SFERRCTRL*/ +/* P2_SFERRCTRL */ #define RSTV0910_P2_SFERRCTRL 0xf3d8 #define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0 #define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007 -/*P2_SFERRCNT2*/ +/* P2_SFERRCNT2 */ #define RSTV0910_P2_SFERRCNT2 0xf3d9 #define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080 #define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f -/*P2_SFERRCNT1*/ +/* P2_SFERRCNT1 */ #define RSTV0910_P2_SFERRCNT1 0xf3da #define FSTV0910_P2_SFEC_ERR_CNT1 0xf3da00ff -/*P2_SFERRCNT0*/ +/* P2_SFERRCNT0 */ #define RSTV0910_P2_SFERRCNT0 0xf3db #define FSTV0910_P2_SFEC_ERR_CNT0 0xf3db00ff -/*P1_IQCONST*/ +/* P1_IQCONST */ #define RSTV0910_P1_IQCONST 0xf400 #define FSTV0910_P1_CONSTEL_SELECT 0xf4000060 #define FSTV0910_P1_IQSYMB_SEL 0xf400001f -/*P1_NOSCFG*/ +/* P1_NOSCFG */ #define RSTV0910_P1_NOSCFG 0xf401 #define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020 #define FSTV0910_P1_NOSPLH_BETA 0xf4010018 #define FSTV0910_P1_NOSDATA_BETA 0xf4010007 -/*P1_ISYMB*/ +/* P1_ISYMB */ #define RSTV0910_P1_ISYMB 0xf402 #define FSTV0910_P1_I_SYMBOL 0xf40201ff -/*P1_QSYMB*/ +/* P1_QSYMB */ #define RSTV0910_P1_QSYMB 0xf403 #define FSTV0910_P1_Q_SYMBOL 0xf40301ff -/*P1_AGC1CFG*/ +/* P1_AGC1CFG */ #define RSTV0910_P1_AGC1CFG 0xf404 #define FSTV0910_P1_DC_FROZEN 0xf4040080 #define FSTV0910_P1_DC_CORRECT 0xf4040040 @@ -2078,70 +2079,70 @@ #define FSTV0910_P1_QUAD_FROZEN 0xf4040008 #define FSTV0910_P1_QUAD_CORRECT 0xf4040004 -/*P1_AGC1CN*/ +/* P1_AGC1CN */ #define RSTV0910_P1_AGC1CN 0xf406 #define FSTV0910_P1_AGC1_LOCKED 0xf4060080 #define FSTV0910_P1_AGC1_MINPOWER 0xf4060010 #define FSTV0910_P1_AGCOUT_FAST 0xf4060008 #define FSTV0910_P1_AGCIQ_BETA 0xf4060007 -/*P1_AGC1REF*/ +/* P1_AGC1REF */ #define RSTV0910_P1_AGC1REF 0xf407 #define FSTV0910_P1_AGCIQ_REF 0xf40700ff -/*P1_IDCCOMP*/ +/* P1_IDCCOMP */ #define RSTV0910_P1_IDCCOMP 0xf408 #define FSTV0910_P1_IAVERAGE_ADJ 0xf40801ff -/*P1_QDCCOMP*/ +/* P1_QDCCOMP */ #define RSTV0910_P1_QDCCOMP 0xf409 #define FSTV0910_P1_QAVERAGE_ADJ 0xf40901ff -/*P1_POWERI*/ +/* P1_POWERI */ #define RSTV0910_P1_POWERI 0xf40a #define FSTV0910_P1_POWER_I 0xf40a00ff -/*P1_POWERQ*/ +/* P1_POWERQ */ #define RSTV0910_P1_POWERQ 0xf40b #define FSTV0910_P1_POWER_Q 0xf40b00ff -/*P1_AGC1AMM*/ +/* P1_AGC1AMM */ #define RSTV0910_P1_AGC1AMM 0xf40c #define FSTV0910_P1_AMM_VALUE 0xf40c00ff -/*P1_AGC1QUAD*/ +/* P1_AGC1QUAD */ #define RSTV0910_P1_AGC1QUAD 0xf40d #define FSTV0910_P1_QUAD_VALUE 0xf40d01ff -/*P1_AGCIQIN1*/ +/* P1_AGCIQIN1 */ #define RSTV0910_P1_AGCIQIN1 0xf40e #define FSTV0910_P1_AGCIQ_VALUE1 0xf40e00ff -/*P1_AGCIQIN0*/ +/* P1_AGCIQIN0 */ #define RSTV0910_P1_AGCIQIN0 0xf40f #define FSTV0910_P1_AGCIQ_VALUE0 0xf40f00ff -/*P1_DEMOD*/ +/* P1_DEMOD */ #define RSTV0910_P1_DEMOD 0xf410 #define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080 #define FSTV0910_P1_SPECINV_CONTROL 0xf4100030 #define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004 #define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003 -/*P1_DMDMODCOD*/ +/* P1_DMDMODCOD */ #define RSTV0910_P1_DMDMODCOD 0xf411 #define FSTV0910_P1_MANUAL_MODCOD 0xf4110080 #define FSTV0910_P1_DEMOD_MODCOD 0xf411007c #define FSTV0910_P1_DEMOD_TYPE 0xf4110003 -/*P1_DSTATUS*/ +/* P1_DSTATUS */ #define RSTV0910_P1_DSTATUS 0xf412 #define FSTV0910_P1_CAR_LOCK 0xf4120080 #define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060 #define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008 #define FSTV0910_P1_OVADC_DETECT 0xf4120001 -/*P1_DSTATUS2*/ +/* P1_DSTATUS2 */ #define RSTV0910_P1_DSTATUS2 0xf413 #define FSTV0910_P1_DEMOD_DELOCK 0xf4130080 #define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020 @@ -2151,7 +2152,7 @@ #define FSTV0910_P1_CFR_OVERFLOW 0xf4130002 #define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001 -/*P1_DMDCFGMD*/ +/* P1_DMDCFGMD */ #define RSTV0910_P1_DMDCFGMD 0xf414 #define FSTV0910_P1_DVBS2_ENABLE 0xf4140080 #define FSTV0910_P1_DVBS1_ENABLE 0xf4140040 @@ -2159,503 +2160,503 @@ #define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008 #define FSTV0910_P1_TUN_RNG 0xf4140003 -/*P1_DMDCFG2*/ +/* P1_DMDCFG2 */ #define RSTV0910_P1_DMDCFG2 0xf415 #define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040 #define FSTV0910_P1_INFINITE_RELOCK 0xf4150010 -/*P1_DMDISTATE*/ +/* P1_DMDISTATE */ #define RSTV0910_P1_DMDISTATE 0xf416 #define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080 #define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f -/*P1_DMDT0M*/ +/* P1_DMDT0M */ #define RSTV0910_P1_DMDT0M 0xf417 #define FSTV0910_P1_DMDT0_MIN 0xf41700ff -/*P1_DMDSTATE*/ +/* P1_DMDSTATE */ #define RSTV0910_P1_DMDSTATE 0xf41b #define FSTV0910_P1_HEADER_MODE 0xf41b0060 -/*P1_DMDFLYW*/ +/* P1_DMDFLYW */ #define RSTV0910_P1_DMDFLYW 0xf41c #define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0 #define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f -/*P1_DSTATUS3*/ +/* P1_DSTATUS3 */ #define RSTV0910_P1_DSTATUS3 0xf41d #define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080 #define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060 #define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010 -/*P1_DMDCFG3*/ +/* P1_DMDCFG3 */ #define RSTV0910_P1_DMDCFG3 0xf41e #define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008 -/*P1_DMDCFG4*/ +/* P1_DMDCFG4 */ #define RSTV0910_P1_DMDCFG4 0xf41f #define FSTV0910_P1_DIS_VITLOCK 0xf41f0080 #define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004 -/*P1_CORRELMANT*/ +/* P1_CORRELMANT */ #define RSTV0910_P1_CORRELMANT 0xf420 #define FSTV0910_P1_CORREL_MANT 0xf42000ff -/*P1_CORRELABS*/ +/* P1_CORRELABS */ #define RSTV0910_P1_CORRELABS 0xf421 #define FSTV0910_P1_CORREL_ABS 0xf42100ff -/*P1_CORRELEXP*/ +/* P1_CORRELEXP */ #define RSTV0910_P1_CORRELEXP 0xf422 #define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0 #define FSTV0910_P1_CORREL_EXP 0xf422000f -/*P1_PLHMODCOD*/ +/* P1_PLHMODCOD */ #define RSTV0910_P1_PLHMODCOD 0xf424 #define FSTV0910_P1_SPECINV_DEMOD 0xf4240080 #define FSTV0910_P1_PLH_MODCOD 0xf424007c #define FSTV0910_P1_PLH_TYPE 0xf4240003 -/*P1_DMDREG*/ +/* P1_DMDREG */ #define RSTV0910_P1_DMDREG 0xf425 #define FSTV0910_P1_DECIM_PLFRAMES 0xf4250001 -/*P1_AGCNADJ*/ +/* P1_AGCNADJ */ #define RSTV0910_P1_AGCNADJ 0xf426 #define FSTV0910_P1_RADJOFF_AGC2 0xf4260080 #define FSTV0910_P1_RADJOFF_AGC1 0xf4260040 #define FSTV0910_P1_AGC_NADJ 0xf426013f -/*P1_AGCKS*/ +/* P1_AGCKS */ #define RSTV0910_P1_AGCKS 0xf427 #define FSTV0910_P1_RSADJ_MANUALCFG 0xf4270080 #define FSTV0910_P1_RSADJ_CCMMODE 0xf4270040 #define FSTV0910_P1_RADJ_SPSK 0xf427013f -/*P1_AGCKQ*/ +/* P1_AGCKQ */ #define RSTV0910_P1_AGCKQ 0xf428 #define FSTV0910_P1_RADJON_DVBS1 0xf4280040 #define FSTV0910_P1_RADJ_QPSK 0xf428013f -/*P1_AGCK8*/ +/* P1_AGCK8 */ #define RSTV0910_P1_AGCK8 0xf429 #define FSTV0910_P1_RADJ_8PSK 0xf429013f -/*P1_AGCK16*/ +/* P1_AGCK16 */ #define RSTV0910_P1_AGCK16 0xf42a #define FSTV0910_P1_R2ADJOFF_16APSK 0xf42a0040 #define FSTV0910_P1_R1ADJOFF_16APSK 0xf42a0020 #define FSTV0910_P1_RADJ_16APSK 0xf42a011f -/*P1_AGCK32*/ +/* P1_AGCK32 */ #define RSTV0910_P1_AGCK32 0xf42b #define FSTV0910_P1_R3ADJOFF_32APSK 0xf42b0080 #define FSTV0910_P1_R2ADJOFF_32APSK 0xf42b0040 #define FSTV0910_P1_R1ADJOFF_32APSK 0xf42b0020 #define FSTV0910_P1_RADJ_32APSK 0xf42b011f -/*P1_AGC2O*/ +/* P1_AGC2O */ #define RSTV0910_P1_AGC2O 0xf42c #define FSTV0910_P1_CSTENV_MODE 0xf42c00c0 #define FSTV0910_P1_AGC2_COEF 0xf42c0007 -/*P1_AGC2REF*/ +/* P1_AGC2REF */ #define RSTV0910_P1_AGC2REF 0xf42d #define FSTV0910_P1_AGC2_REF 0xf42d00ff -/*P1_AGC1ADJ*/ +/* P1_AGC1ADJ */ #define RSTV0910_P1_AGC1ADJ 0xf42e #define FSTV0910_P1_AGC1_ADJUSTED 0xf42e007f -/*P1_AGCRSADJ*/ +/* P1_AGCRSADJ */ #define RSTV0910_P1_AGCRSADJ 0xf42f #define FSTV0910_P1_RS_ADJUSTED 0xf42f007f -/*P1_AGCRQADJ*/ +/* P1_AGCRQADJ */ #define RSTV0910_P1_AGCRQADJ 0xf430 #define FSTV0910_P1_RQ_ADJUSTED 0xf430007f -/*P1_AGCR8ADJ*/ +/* P1_AGCR8ADJ */ #define RSTV0910_P1_AGCR8ADJ 0xf431 #define FSTV0910_P1_R8_ADJUSTED 0xf431007f -/*P1_AGCR1ADJ*/ +/* P1_AGCR1ADJ */ #define RSTV0910_P1_AGCR1ADJ 0xf432 #define FSTV0910_P1_R1_ADJUSTED 0xf432007f -/*P1_AGCR2ADJ*/ +/* P1_AGCR2ADJ */ #define RSTV0910_P1_AGCR2ADJ 0xf433 #define FSTV0910_P1_R2_ADJUSTED 0xf433007f -/*P1_AGCR3ADJ*/ +/* P1_AGCR3ADJ */ #define RSTV0910_P1_AGCR3ADJ 0xf434 #define FSTV0910_P1_R3_ADJUSTED 0xf434007f -/*P1_AGCREFADJ*/ +/* P1_AGCREFADJ */ #define RSTV0910_P1_AGCREFADJ 0xf435 #define FSTV0910_P1_AGC2REF_ADJUSTED 0xf435007f -/*P1_AGC2I1*/ +/* P1_AGC2I1 */ #define RSTV0910_P1_AGC2I1 0xf436 #define FSTV0910_P1_AGC2_INTEGRATOR1 0xf43600ff -/*P1_AGC2I0*/ +/* P1_AGC2I0 */ #define RSTV0910_P1_AGC2I0 0xf437 #define FSTV0910_P1_AGC2_INTEGRATOR0 0xf43700ff -/*P1_CARCFG*/ +/* P1_CARCFG */ #define RSTV0910_P1_CARCFG 0xf438 #define FSTV0910_P1_ROTAON 0xf4380004 #define FSTV0910_P1_PH_DET_ALGO 0xf4380003 -/*P1_ACLC*/ +/* P1_ACLC */ #define RSTV0910_P1_ACLC 0xf439 #define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030 #define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f -/*P1_BCLC*/ +/* P1_BCLC */ #define RSTV0910_P1_BCLC 0xf43a #define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030 #define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f -/*P1_ACLCS2*/ +/* P1_ACLCS2 */ #define RSTV0910_P1_ACLCS2 0xf43b #define FSTV0910_P1_CARS2_APLHA_MANTISSE 0xf43b0030 #define FSTV0910_P1_CARS2_ALPHA_EXP 0xf43b000f -/*P1_BCLCS2*/ +/* P1_BCLCS2 */ #define RSTV0910_P1_BCLCS2 0xf43c #define FSTV0910_P1_CARS2_BETA_MANTISSE 0xf43c0030 #define FSTV0910_P1_CARS2_BETA_EXP 0xf43c000f -/*P1_CARFREQ*/ +/* P1_CARFREQ */ #define RSTV0910_P1_CARFREQ 0xf43d #define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0 #define FSTV0910_P1_BETA_FREQ 0xf43d000f -/*P1_CARHDR*/ +/* P1_CARHDR */ #define RSTV0910_P1_CARHDR 0xf43e #define FSTV0910_P1_K_FREQ_HDR 0xf43e00ff -/*P1_LDT*/ +/* P1_LDT */ #define RSTV0910_P1_LDT 0xf43f #define FSTV0910_P1_CARLOCK_THRES 0xf43f01ff -/*P1_LDT2*/ +/* P1_LDT2 */ #define RSTV0910_P1_LDT2 0xf440 #define FSTV0910_P1_CARLOCK_THRES2 0xf44001ff -/*P1_CFRICFG*/ +/* P1_CFRICFG */ #define RSTV0910_P1_CFRICFG 0xf441 #define FSTV0910_P1_NEG_CFRSTEP 0xf4410001 -/*P1_CFRUP1*/ +/* P1_CFRUP1 */ #define RSTV0910_P1_CFRUP1 0xf442 #define FSTV0910_P1_CFR_UP1 0xf44201ff -/*P1_CFRUP0*/ +/* P1_CFRUP0 */ #define RSTV0910_P1_CFRUP0 0xf443 #define FSTV0910_P1_CFR_UP0 0xf44300ff -/*P1_CFRIBASE1*/ +/* P1_CFRIBASE1 */ #define RSTV0910_P1_CFRIBASE1 0xf444 #define FSTV0910_P1_CFRINIT_BASE1 0xf44400ff -/*P1_CFRIBASE0*/ +/* P1_CFRIBASE0 */ #define RSTV0910_P1_CFRIBASE0 0xf445 #define FSTV0910_P1_CFRINIT_BASE0 0xf44500ff -/*P1_CFRLOW1*/ +/* P1_CFRLOW1 */ #define RSTV0910_P1_CFRLOW1 0xf446 #define FSTV0910_P1_CFR_LOW1 0xf44601ff -/*P1_CFRLOW0*/ +/* P1_CFRLOW0 */ #define RSTV0910_P1_CFRLOW0 0xf447 #define FSTV0910_P1_CFR_LOW0 0xf44700ff -/*P1_CFRINIT1*/ +/* P1_CFRINIT1 */ #define RSTV0910_P1_CFRINIT1 0xf448 #define FSTV0910_P1_CFR_INIT1 0xf44801ff -/*P1_CFRINIT0*/ +/* P1_CFRINIT0 */ #define RSTV0910_P1_CFRINIT0 0xf449 #define FSTV0910_P1_CFR_INIT0 0xf44900ff -/*P1_CFRINC1*/ +/* P1_CFRINC1 */ #define RSTV0910_P1_CFRINC1 0xf44a #define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080 #define FSTV0910_P1_CFR_INC1 0xf44a003f -/*P1_CFRINC0*/ +/* P1_CFRINC0 */ #define RSTV0910_P1_CFRINC0 0xf44b #define FSTV0910_P1_CFR_INC0 0xf44b00ff -/*P1_CFR2*/ +/* P1_CFR2 */ #define RSTV0910_P1_CFR2 0xf44c #define FSTV0910_P1_CAR_FREQ2 0xf44c01ff -/*P1_CFR1*/ +/* P1_CFR1 */ #define RSTV0910_P1_CFR1 0xf44d #define FSTV0910_P1_CAR_FREQ1 0xf44d00ff -/*P1_CFR0*/ +/* P1_CFR0 */ #define RSTV0910_P1_CFR0 0xf44e #define FSTV0910_P1_CAR_FREQ0 0xf44e00ff -/*P1_LDI*/ +/* P1_LDI */ #define RSTV0910_P1_LDI 0xf44f #define FSTV0910_P1_LOCK_DET_INTEGR 0xf44f01ff -/*P1_TMGCFG*/ +/* P1_TMGCFG */ #define RSTV0910_P1_TMGCFG 0xf450 #define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0 #define FSTV0910_P1_DO_TIMING_CORR 0xf4500010 #define FSTV0910_P1_TMG_MINFREQ 0xf4500003 -/*P1_RTC*/ +/* P1_RTC */ #define RSTV0910_P1_RTC 0xf451 #define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0 #define FSTV0910_P1_TMGBETA_EXP 0xf451000f -/*P1_RTCS2*/ +/* P1_RTCS2 */ #define RSTV0910_P1_RTCS2 0xf452 #define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0 #define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f -/*P1_TMGTHRISE*/ +/* P1_TMGTHRISE */ #define RSTV0910_P1_TMGTHRISE 0xf453 #define FSTV0910_P1_TMGLOCK_THRISE 0xf45300ff -/*P1_TMGTHFALL*/ +/* P1_TMGTHFALL */ #define RSTV0910_P1_TMGTHFALL 0xf454 #define FSTV0910_P1_TMGLOCK_THFALL 0xf45400ff -/*P1_SFRUPRATIO*/ +/* P1_SFRUPRATIO */ #define RSTV0910_P1_SFRUPRATIO 0xf455 #define FSTV0910_P1_SFR_UPRATIO 0xf45500ff -/*P1_SFRLOWRATIO*/ +/* P1_SFRLOWRATIO */ #define RSTV0910_P1_SFRLOWRATIO 0xf456 #define FSTV0910_P1_SFR_LOWRATIO 0xf45600ff -/*P1_KTTMG*/ +/* P1_KTTMG */ #define RSTV0910_P1_KTTMG 0xf457 #define FSTV0910_P1_KT_TMG_EXP 0xf45700f0 -/*P1_KREFTMG*/ +/* P1_KREFTMG */ #define RSTV0910_P1_KREFTMG 0xf458 #define FSTV0910_P1_KREF_TMG 0xf45800ff -/*P1_SFRSTEP*/ +/* P1_SFRSTEP */ #define RSTV0910_P1_SFRSTEP 0xf459 #define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0 #define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f -/*P1_TMGCFG2*/ +/* P1_TMGCFG2 */ #define RSTV0910_P1_TMGCFG2 0xf45a #define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008 #define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001 -/*P1_KREFTMG2*/ +/* P1_KREFTMG2 */ #define RSTV0910_P1_KREFTMG2 0xf45b #define FSTV0910_P1_KREF_TMG2 0xf45b00ff -/*P1_TMGCFG3*/ +/* P1_TMGCFG3 */ #define RSTV0910_P1_TMGCFG3 0xf45d #define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008 #define FSTV0910_P1_AUTO_GUP 0xf45d0004 #define FSTV0910_P1_AUTO_GLOW 0xf45d0002 -/*P1_SFRINIT1*/ +/* P1_SFRINIT1 */ #define RSTV0910_P1_SFRINIT1 0xf45e #define FSTV0910_P1_SFR_INIT1 0xf45e00ff -/*P1_SFRINIT0*/ +/* P1_SFRINIT0 */ #define RSTV0910_P1_SFRINIT0 0xf45f #define FSTV0910_P1_SFR_INIT0 0xf45f00ff -/*P1_SFRUP1*/ +/* P1_SFRUP1 */ #define RSTV0910_P1_SFRUP1 0xf460 #define FSTV0910_P1_SYMB_FREQ_UP1 0xf46000ff -/*P1_SFRUP0*/ +/* P1_SFRUP0 */ #define RSTV0910_P1_SFRUP0 0xf461 #define FSTV0910_P1_SYMB_FREQ_UP0 0xf46100ff -/*P1_SFRLOW1*/ +/* P1_SFRLOW1 */ #define RSTV0910_P1_SFRLOW1 0xf462 #define FSTV0910_P1_SYMB_FREQ_LOW1 0xf46200ff -/*P1_SFRLOW0*/ +/* P1_SFRLOW0 */ #define RSTV0910_P1_SFRLOW0 0xf463 #define FSTV0910_P1_SYMB_FREQ_LOW0 0xf46300ff -/*P1_SFR3*/ +/* P1_SFR3 */ #define RSTV0910_P1_SFR3 0xf464 #define FSTV0910_P1_SYMB_FREQ3 0xf46400ff -/*P1_SFR2*/ +/* P1_SFR2 */ #define RSTV0910_P1_SFR2 0xf465 #define FSTV0910_P1_SYMB_FREQ2 0xf46500ff -/*P1_SFR1*/ +/* P1_SFR1 */ #define RSTV0910_P1_SFR1 0xf466 #define FSTV0910_P1_SYMB_FREQ1 0xf46600ff -/*P1_SFR0*/ +/* P1_SFR0 */ #define RSTV0910_P1_SFR0 0xf467 #define FSTV0910_P1_SYMB_FREQ0 0xf46700ff -/*P1_TMGREG2*/ +/* P1_TMGREG2 */ #define RSTV0910_P1_TMGREG2 0xf468 #define FSTV0910_P1_TMGREG2 0xf46800ff -/*P1_TMGREG1*/ +/* P1_TMGREG1 */ #define RSTV0910_P1_TMGREG1 0xf469 #define FSTV0910_P1_TMGREG1 0xf46900ff -/*P1_TMGREG0*/ +/* P1_TMGREG0 */ #define RSTV0910_P1_TMGREG0 0xf46a #define FSTV0910_P1_TMGREG0 0xf46a00ff -/*P1_TMGLOCK1*/ +/* P1_TMGLOCK1 */ #define RSTV0910_P1_TMGLOCK1 0xf46b #define FSTV0910_P1_TMGLOCK_LEVEL1 0xf46b01ff -/*P1_TMGLOCK0*/ +/* P1_TMGLOCK0 */ #define RSTV0910_P1_TMGLOCK0 0xf46c #define FSTV0910_P1_TMGLOCK_LEVEL0 0xf46c00ff -/*P1_TMGOBS*/ +/* P1_TMGOBS */ #define RSTV0910_P1_TMGOBS 0xf46d #define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0 -/*P1_EQUALCFG*/ +/* P1_EQUALCFG */ #define RSTV0910_P1_EQUALCFG 0xf46f #define FSTV0910_P1_EQUAL_ON 0xf46f0040 #define FSTV0910_P1_MU_EQUALDFE 0xf46f0007 -/*P1_EQUAI1*/ +/* P1_EQUAI1 */ #define RSTV0910_P1_EQUAI1 0xf470 #define FSTV0910_P1_EQUA_ACCI1 0xf47001ff -/*P1_EQUAQ1*/ +/* P1_EQUAQ1 */ #define RSTV0910_P1_EQUAQ1 0xf471 #define FSTV0910_P1_EQUA_ACCQ1 0xf47101ff -/*P1_EQUAI2*/ +/* P1_EQUAI2 */ #define RSTV0910_P1_EQUAI2 0xf472 #define FSTV0910_P1_EQUA_ACCI2 0xf47201ff -/*P1_EQUAQ2*/ +/* P1_EQUAQ2 */ #define RSTV0910_P1_EQUAQ2 0xf473 #define FSTV0910_P1_EQUA_ACCQ2 0xf47301ff -/*P1_EQUAI3*/ +/* P1_EQUAI3 */ #define RSTV0910_P1_EQUAI3 0xf474 #define FSTV0910_P1_EQUA_ACCI3 0xf47401ff -/*P1_EQUAQ3*/ +/* P1_EQUAQ3 */ #define RSTV0910_P1_EQUAQ3 0xf475 #define FSTV0910_P1_EQUA_ACCQ3 0xf47501ff -/*P1_EQUAI4*/ +/* P1_EQUAI4 */ #define RSTV0910_P1_EQUAI4 0xf476 #define FSTV0910_P1_EQUA_ACCI4 0xf47601ff -/*P1_EQUAQ4*/ +/* P1_EQUAQ4 */ #define RSTV0910_P1_EQUAQ4 0xf477 #define FSTV0910_P1_EQUA_ACCQ4 0xf47701ff -/*P1_EQUAI5*/ +/* P1_EQUAI5 */ #define RSTV0910_P1_EQUAI5 0xf478 #define FSTV0910_P1_EQUA_ACCI5 0xf47801ff -/*P1_EQUAQ5*/ +/* P1_EQUAQ5 */ #define RSTV0910_P1_EQUAQ5 0xf479 #define FSTV0910_P1_EQUA_ACCQ5 0xf47901ff -/*P1_EQUAI6*/ +/* P1_EQUAI6 */ #define RSTV0910_P1_EQUAI6 0xf47a #define FSTV0910_P1_EQUA_ACCI6 0xf47a01ff -/*P1_EQUAQ6*/ +/* P1_EQUAQ6 */ #define RSTV0910_P1_EQUAQ6 0xf47b #define FSTV0910_P1_EQUA_ACCQ6 0xf47b01ff -/*P1_EQUAI7*/ +/* P1_EQUAI7 */ #define RSTV0910_P1_EQUAI7 0xf47c #define FSTV0910_P1_EQUA_ACCI7 0xf47c01ff -/*P1_EQUAQ7*/ +/* P1_EQUAQ7 */ #define RSTV0910_P1_EQUAQ7 0xf47d #define FSTV0910_P1_EQUA_ACCQ7 0xf47d01ff -/*P1_EQUAI8*/ +/* P1_EQUAI8 */ #define RSTV0910_P1_EQUAI8 0xf47e #define FSTV0910_P1_EQUA_ACCI8 0xf47e01ff -/*P1_EQUAQ8*/ +/* P1_EQUAQ8 */ #define RSTV0910_P1_EQUAQ8 0xf47f #define FSTV0910_P1_EQUA_ACCQ8 0xf47f01ff -/*P1_NNOSDATAT1*/ +/* P1_NNOSDATAT1 */ #define RSTV0910_P1_NNOSDATAT1 0xf480 #define FSTV0910_P1_NOSDATAT_NORMED1 0xf48000ff -/*P1_NNOSDATAT0*/ +/* P1_NNOSDATAT0 */ #define RSTV0910_P1_NNOSDATAT0 0xf481 #define FSTV0910_P1_NOSDATAT_NORMED0 0xf48100ff -/*P1_NNOSDATA1*/ +/* P1_NNOSDATA1 */ #define RSTV0910_P1_NNOSDATA1 0xf482 #define FSTV0910_P1_NOSDATA_NORMED1 0xf48200ff -/*P1_NNOSDATA0*/ +/* P1_NNOSDATA0 */ #define RSTV0910_P1_NNOSDATA0 0xf483 #define FSTV0910_P1_NOSDATA_NORMED0 0xf48300ff -/*P1_NNOSPLHT1*/ +/* P1_NNOSPLHT1 */ #define RSTV0910_P1_NNOSPLHT1 0xf484 #define FSTV0910_P1_NOSPLHT_NORMED1 0xf48400ff -/*P1_NNOSPLHT0*/ +/* P1_NNOSPLHT0 */ #define RSTV0910_P1_NNOSPLHT0 0xf485 #define FSTV0910_P1_NOSPLHT_NORMED0 0xf48500ff -/*P1_NNOSPLH1*/ +/* P1_NNOSPLH1 */ #define RSTV0910_P1_NNOSPLH1 0xf486 #define FSTV0910_P1_NOSPLH_NORMED1 0xf48600ff -/*P1_NNOSPLH0*/ +/* P1_NNOSPLH0 */ #define RSTV0910_P1_NNOSPLH0 0xf487 #define FSTV0910_P1_NOSPLH_NORMED0 0xf48700ff -/*P1_NOSDATAT1*/ +/* P1_NOSDATAT1 */ #define RSTV0910_P1_NOSDATAT1 0xf488 #define FSTV0910_P1_NOSDATAT_UNNORMED1 0xf48800ff -/*P1_NOSDATAT0*/ +/* P1_NOSDATAT0 */ #define RSTV0910_P1_NOSDATAT0 0xf489 #define FSTV0910_P1_NOSDATAT_UNNORMED0 0xf48900ff -/*P1_NNOSFRAME1*/ +/* P1_NNOSFRAME1 */ #define RSTV0910_P1_NNOSFRAME1 0xf48a #define FSTV0910_P1_NOSFRAME_NORMED1 0xf48a00ff -/*P1_NNOSFRAME0*/ +/* P1_NNOSFRAME0 */ #define RSTV0910_P1_NNOSFRAME0 0xf48b #define FSTV0910_P1_NOSFRAME_NORMED0 0xf48b00ff -/*P1_NNOSRAD1*/ +/* P1_NNOSRAD1 */ #define RSTV0910_P1_NNOSRAD1 0xf48c #define FSTV0910_P1_NOSRADIAL_NORMED1 0xf48c00ff -/*P1_NNOSRAD0*/ +/* P1_NNOSRAD0 */ #define RSTV0910_P1_NNOSRAD0 0xf48d #define FSTV0910_P1_NOSRADIAL_NORMED0 0xf48d00ff -/*P1_NOSCFGF1*/ +/* P1_NOSCFGF1 */ #define RSTV0910_P1_NOSCFGF1 0xf48e #define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080 #define FSTV0910_P1_NOS_DELFRAME 0xf48e0040 @@ -2663,177 +2664,177 @@ #define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c #define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003 -/*P1_NOSCFGF2*/ +/* P1_NOSCFGF2 */ #define RSTV0910_P1_NOSCFGF2 0xf48f #define FSTV0910_P1_DIS_NOSPILOTS 0xf48f0080 #define FSTV0910_P1_FRAMESEL_MODCODSEL 0xf48f0060 #define FSTV0910_P1_FRAMESEL_MODCOD 0xf48f001f -/*P1_CAR2CFG*/ +/* P1_CAR2CFG */ #define RSTV0910_P1_CAR2CFG 0xf490 #define FSTV0910_P1_ROTA2ON 0xf4900004 #define FSTV0910_P1_PH_DET_ALGO2 0xf4900003 -/*P1_CFR2CFR1*/ +/* P1_CFR2CFR1 */ #define RSTV0910_P1_CFR2CFR1 0xf491 #define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020 #define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007 -/*P1_CAR3CFG*/ +/* P1_CAR3CFG */ #define RSTV0910_P1_CAR3CFG 0xf492 #define FSTV0910_P1_CARRIER23_MODE 0xf49200c0 #define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020 #define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018 #define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007 -/*P1_CFR22*/ +/* P1_CFR22 */ #define RSTV0910_P1_CFR22 0xf493 #define FSTV0910_P1_CAR2_FREQ2 0xf49301ff -/*P1_CFR21*/ +/* P1_CFR21 */ #define RSTV0910_P1_CFR21 0xf494 #define FSTV0910_P1_CAR2_FREQ1 0xf49400ff -/*P1_CFR20*/ +/* P1_CFR20 */ #define RSTV0910_P1_CFR20 0xf495 #define FSTV0910_P1_CAR2_FREQ0 0xf49500ff -/*P1_ACLC2S2Q*/ +/* P1_ACLC2S2Q */ #define RSTV0910_P1_ACLC2S2Q 0xf497 #define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080 #define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030 #define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f -/*P1_ACLC2S28*/ +/* P1_ACLC2S28 */ #define RSTV0910_P1_ACLC2S28 0xf498 #define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030 #define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f -/*P1_ACLC2S216A*/ +/* P1_ACLC2S216A */ #define RSTV0910_P1_ACLC2S216A 0xf499 #define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030 #define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f -/*P1_ACLC2S232A*/ +/* P1_ACLC2S232A */ #define RSTV0910_P1_ACLC2S232A 0xf49a #define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030 #define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f -/*P1_BCLC2S2Q*/ +/* P1_BCLC2S2Q */ #define RSTV0910_P1_BCLC2S2Q 0xf49c #define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030 #define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f -/*P1_BCLC2S28*/ +/* P1_BCLC2S28 */ #define RSTV0910_P1_BCLC2S28 0xf49d #define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030 #define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f -/*P1_BCLC2S216A*/ +/* P1_BCLC2S216A */ #define RSTV0910_P1_BCLC2S216A 0xf49e #define FSTV0910_P1_DVBS2S216A_NIP 0xf49e0080 #define FSTV0910_P1_CAR2S2_16A_BETA_M 0xf49e0030 #define FSTV0910_P1_CAR2S2_16A_BETA_E 0xf49e000f -/*P1_BCLC2S232A*/ +/* P1_BCLC2S232A */ #define RSTV0910_P1_BCLC2S232A 0xf49f #define FSTV0910_P1_DVBS2S232A_NIP 0xf49f0080 #define FSTV0910_P1_CAR2S2_32A_BETA_M 0xf49f0030 #define FSTV0910_P1_CAR2S2_32A_BETA_E 0xf49f000f -/*P1_PLROOT2*/ +/* P1_PLROOT2 */ #define RSTV0910_P1_PLROOT2 0xf4ac #define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c #define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003 -/*P1_PLROOT1*/ +/* P1_PLROOT1 */ #define RSTV0910_P1_PLROOT1 0xf4ad #define FSTV0910_P1_PLSCRAMB_ROOT1 0xf4ad00ff -/*P1_PLROOT0*/ +/* P1_PLROOT0 */ #define RSTV0910_P1_PLROOT0 0xf4ae #define FSTV0910_P1_PLSCRAMB_ROOT0 0xf4ae00ff -/*P1_MODCODLST0*/ +/* P1_MODCODLST0 */ #define RSTV0910_P1_MODCODLST0 0xf4b0 #define FSTV0910_P1_NACCES_MODCODCH 0xf4b00001 -/*P1_MODCODLST1*/ +/* P1_MODCODLST1 */ #define RSTV0910_P1_MODCODLST1 0xf4b1 #define FSTV0910_P1_SYMBRATE_FILTER 0xf4b10008 #define FSTV0910_P1_NRESET_MODCODLST 0xf4b10004 #define FSTV0910_P1_DIS_32PSK_9_10 0xf4b10003 -/*P1_MODCODLST2*/ +/* P1_MODCODLST2 */ #define RSTV0910_P1_MODCODLST2 0xf4b2 #define FSTV0910_P1_DIS_32PSK_8_9 0xf4b200f0 #define FSTV0910_P1_DIS_32PSK_5_6 0xf4b2000f -/*P1_MODCODLST3*/ +/* P1_MODCODLST3 */ #define RSTV0910_P1_MODCODLST3 0xf4b3 #define FSTV0910_P1_DIS_32PSK_4_5 0xf4b300f0 #define FSTV0910_P1_DIS_32PSK_3_4 0xf4b3000f -/*P1_MODCODLST4*/ +/* P1_MODCODLST4 */ #define RSTV0910_P1_MODCODLST4 0xf4b4 #define FSTV0910_P1_DUMMYPL_PILOT 0xf4b40080 #define FSTV0910_P1_DUMMYPL_NOPILOT 0xf4b40040 #define FSTV0910_P1_DIS_16PSK_9_10 0xf4b40030 #define FSTV0910_P1_DIS_16PSK_8_9 0xf4b4000f -/*P1_MODCODLST5*/ +/* P1_MODCODLST5 */ #define RSTV0910_P1_MODCODLST5 0xf4b5 #define FSTV0910_P1_DIS_16PSK_5_6 0xf4b500f0 #define FSTV0910_P1_DIS_16PSK_4_5 0xf4b5000f -/*P1_MODCODLST6*/ +/* P1_MODCODLST6 */ #define RSTV0910_P1_MODCODLST6 0xf4b6 #define FSTV0910_P1_DIS_16PSK_3_4 0xf4b600f0 #define FSTV0910_P1_DIS_16PSK_2_3 0xf4b6000f -/*P1_MODCODLST7*/ +/* P1_MODCODLST7 */ #define RSTV0910_P1_MODCODLST7 0xf4b7 #define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080 #define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030 #define FSTV0910_P1_DIS_8PSK_8_9 0xf4b7000f -/*P1_MODCODLST8*/ +/* P1_MODCODLST8 */ #define RSTV0910_P1_MODCODLST8 0xf4b8 #define FSTV0910_P1_DIS_8PSK_5_6 0xf4b800f0 #define FSTV0910_P1_DIS_8PSK_3_4 0xf4b8000f -/*P1_MODCODLST9*/ +/* P1_MODCODLST9 */ #define RSTV0910_P1_MODCODLST9 0xf4b9 #define FSTV0910_P1_DIS_8PSK_2_3 0xf4b900f0 #define FSTV0910_P1_DIS_8PSK_3_5 0xf4b9000f -/*P1_MODCODLSTA*/ +/* P1_MODCODLSTA */ #define RSTV0910_P1_MODCODLSTA 0xf4ba #define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080 #define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030 #define FSTV0910_P1_DIS_QPSK_8_9 0xf4ba000f -/*P1_MODCODLSTB*/ +/* P1_MODCODLSTB */ #define RSTV0910_P1_MODCODLSTB 0xf4bb #define FSTV0910_P1_DIS_QPSK_5_6 0xf4bb00f0 #define FSTV0910_P1_DIS_QPSK_4_5 0xf4bb000f -/*P1_MODCODLSTC*/ +/* P1_MODCODLSTC */ #define RSTV0910_P1_MODCODLSTC 0xf4bc #define FSTV0910_P1_DIS_QPSK_3_4 0xf4bc00f0 #define FSTV0910_P1_DIS_QPSK_2_3 0xf4bc000f -/*P1_MODCODLSTD*/ +/* P1_MODCODLSTD */ #define RSTV0910_P1_MODCODLSTD 0xf4bd #define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0 #define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f -/*P1_MODCODLSTE*/ +/* P1_MODCODLSTE */ #define RSTV0910_P1_MODCODLSTE 0xf4be #define FSTV0910_P1_DIS_QPSK_2_5 0xf4be00f0 #define FSTV0910_P1_DIS_QPSK_1_3 0xf4be000f -/*P1_MODCODLSTF*/ +/* P1_MODCODLSTF */ #define RSTV0910_P1_MODCODLSTF 0xf4bf #define FSTV0910_P1_DIS_QPSK_1_4 0xf4bf00f0 #define FSTV0910_P1_DEMOD_INVMODLST 0xf4bf0008 @@ -2841,30 +2842,30 @@ #define FSTV0910_P1_DDEMOD_NSET 0xf4bf0002 #define FSTV0910_P1_MODCOD_NSTOCK 0xf4bf0001 -/*P1_GAUSSR0*/ +/* P1_GAUSSR0 */ #define RSTV0910_P1_GAUSSR0 0xf4c0 #define FSTV0910_P1_EN_CCIMODE 0xf4c00080 #define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f -/*P1_CCIR0*/ +/* P1_CCIR0 */ #define RSTV0910_P1_CCIR0 0xf4c1 #define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080 #define FSTV0910_P1_R0_CCI 0xf4c1007f -/*P1_CCIQUANT*/ +/* P1_CCIQUANT */ #define RSTV0910_P1_CCIQUANT 0xf4c2 #define FSTV0910_P1_CCI_BETA 0xf4c200e0 #define FSTV0910_P1_CCI_QUANT 0xf4c2001f -/*P1_CCITHRES*/ +/* P1_CCITHRES */ #define RSTV0910_P1_CCITHRES 0xf4c3 #define FSTV0910_P1_CCI_THRESHOLD 0xf4c300ff -/*P1_CCIACC*/ +/* P1_CCIACC */ #define RSTV0910_P1_CCIACC 0xf4c4 #define FSTV0910_P1_CCI_VALUE 0xf4c400ff -/*P1_DSTATUS4*/ +/* P1_DSTATUS4 */ #define RSTV0910_P1_DSTATUS4 0xf4c5 #define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080 #define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040 @@ -2873,234 +2874,234 @@ #define FSTV0910_P1_CSTENV_DETECT 0xf4c50002 #define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001 -/*P1_DMDRESCFG*/ +/* P1_DMDRESCFG */ #define RSTV0910_P1_DMDRESCFG 0xf4c6 #define FSTV0910_P1_DMDRES_RESET 0xf4c60080 #define FSTV0910_P1_DMDRES_STRALL 0xf4c60008 #define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004 #define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002 -/*P1_DMDRESADR*/ +/* P1_DMDRESADR */ #define RSTV0910_P1_DMDRESADR 0xf4c7 #define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040 #define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030 #define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f -/*P1_DMDRESDATA7*/ +/* P1_DMDRESDATA7 */ #define RSTV0910_P1_DMDRESDATA7 0xf4c8 #define FSTV0910_P1_DMDRES_DATA7 0xf4c800ff -/*P1_DMDRESDATA6*/ +/* P1_DMDRESDATA6 */ #define RSTV0910_P1_DMDRESDATA6 0xf4c9 #define FSTV0910_P1_DMDRES_DATA6 0xf4c900ff -/*P1_DMDRESDATA5*/ +/* P1_DMDRESDATA5 */ #define RSTV0910_P1_DMDRESDATA5 0xf4ca #define FSTV0910_P1_DMDRES_DATA5 0xf4ca00ff -/*P1_DMDRESDATA4*/ +/* P1_DMDRESDATA4 */ #define RSTV0910_P1_DMDRESDATA4 0xf4cb #define FSTV0910_P1_DMDRES_DATA4 0xf4cb00ff -/*P1_DMDRESDATA3*/ +/* P1_DMDRESDATA3 */ #define RSTV0910_P1_DMDRESDATA3 0xf4cc #define FSTV0910_P1_DMDRES_DATA3 0xf4cc00ff -/*P1_DMDRESDATA2*/ +/* P1_DMDRESDATA2 */ #define RSTV0910_P1_DMDRESDATA2 0xf4cd #define FSTV0910_P1_DMDRES_DATA2 0xf4cd00ff -/*P1_DMDRESDATA1*/ +/* P1_DMDRESDATA1 */ #define RSTV0910_P1_DMDRESDATA1 0xf4ce #define FSTV0910_P1_DMDRES_DATA1 0xf4ce00ff -/*P1_DMDRESDATA0*/ +/* P1_DMDRESDATA0 */ #define RSTV0910_P1_DMDRESDATA0 0xf4cf #define FSTV0910_P1_DMDRES_DATA0 0xf4cf00ff -/*P1_FFEI1*/ +/* P1_FFEI1 */ #define RSTV0910_P1_FFEI1 0xf4d0 #define FSTV0910_P1_FFE_ACCI1 0xf4d001ff -/*P1_FFEQ1*/ +/* P1_FFEQ1 */ #define RSTV0910_P1_FFEQ1 0xf4d1 #define FSTV0910_P1_FFE_ACCQ1 0xf4d101ff -/*P1_FFEI2*/ +/* P1_FFEI2 */ #define RSTV0910_P1_FFEI2 0xf4d2 #define FSTV0910_P1_FFE_ACCI2 0xf4d201ff -/*P1_FFEQ2*/ +/* P1_FFEQ2 */ #define RSTV0910_P1_FFEQ2 0xf4d3 #define FSTV0910_P1_FFE_ACCQ2 0xf4d301ff -/*P1_FFEI3*/ +/* P1_FFEI3 */ #define RSTV0910_P1_FFEI3 0xf4d4 #define FSTV0910_P1_FFE_ACCI3 0xf4d401ff -/*P1_FFEQ3*/ +/* P1_FFEQ3 */ #define RSTV0910_P1_FFEQ3 0xf4d5 #define FSTV0910_P1_FFE_ACCQ3 0xf4d501ff -/*P1_FFEI4*/ +/* P1_FFEI4 */ #define RSTV0910_P1_FFEI4 0xf4d6 #define FSTV0910_P1_FFE_ACCI4 0xf4d601ff -/*P1_FFEQ4*/ +/* P1_FFEQ4 */ #define RSTV0910_P1_FFEQ4 0xf4d7 #define FSTV0910_P1_FFE_ACCQ4 0xf4d701ff -/*P1_FFECFG*/ +/* P1_FFECFG */ #define RSTV0910_P1_FFECFG 0xf4d8 #define FSTV0910_P1_EQUALFFE_ON 0xf4d80040 #define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030 #define FSTV0910_P1_MU_EQUALFFE 0xf4d80007 -/*P1_TNRCFG2*/ +/* P1_TNRCFG2 */ #define RSTV0910_P1_TNRCFG2 0xf4e1 #define FSTV0910_P1_TUN_IQSWAP 0xf4e10080 -/*P1_SMAPCOEF7*/ +/* P1_SMAPCOEF7 */ #define RSTV0910_P1_SMAPCOEF7 0xf500 #define FSTV0910_P1_DIS_QSCALE 0xf5000080 #define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f -/*P1_SMAPCOEF6*/ +/* P1_SMAPCOEF6 */ #define RSTV0910_P1_SMAPCOEF6 0xf501 #define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080 #define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004 #define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002 #define FSTV0910_P1_DIS_AB8PSK 0xf5010001 -/*P1_SMAPCOEF5*/ +/* P1_SMAPCOEF5 */ #define RSTV0910_P1_SMAPCOEF5 0xf502 #define FSTV0910_P1_DIS_8SCALE 0xf5020080 #define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f -/*P1_SMAPCOEF4*/ +/* P1_SMAPCOEF4 */ #define RSTV0910_P1_SMAPCOEF4 0xf503 #define FSTV0910_P1_SMAPCOEF_16APSK_LLR12 0xf503017f -/*P1_SMAPCOEF3*/ +/* P1_SMAPCOEF3 */ #define RSTV0910_P1_SMAPCOEF3 0xf504 #define FSTV0910_P1_SMAPCOEF_16APSK_LLR34 0xf504017f -/*P1_SMAPCOEF2*/ +/* P1_SMAPCOEF2 */ #define RSTV0910_P1_SMAPCOEF2 0xf505 #define FSTV0910_P1_SMAPCOEF_32APSK_R2R3 0xf50501f0 #define FSTV0910_P1_SMAPCOEF_32APSK_LLR2 0xf505010f -/*P1_SMAPCOEF1*/ +/* P1_SMAPCOEF1 */ #define RSTV0910_P1_SMAPCOEF1 0xf506 #define FSTV0910_P1_DIS_16SCALE 0xf5060080 #define FSTV0910_P1_SMAPCOEF_32_LLR34 0xf506017f -/*P1_SMAPCOEF0*/ +/* P1_SMAPCOEF0 */ #define RSTV0910_P1_SMAPCOEF0 0xf507 #define FSTV0910_P1_DIS_32SCALE 0xf5070080 #define FSTV0910_P1_SMAPCOEF_32_LLR15 0xf507017f -/*P1_NOSTHRES1*/ +/* P1_NOSTHRES1 */ #define RSTV0910_P1_NOSTHRES1 0xf509 #define FSTV0910_P1_NOS_THRESHOLD1 0xf50900ff -/*P1_NOSTHRES2*/ +/* P1_NOSTHRES2 */ #define RSTV0910_P1_NOSTHRES2 0xf50a #define FSTV0910_P1_NOS_THRESHOLD2 0xf50a00ff -/*P1_NOSDIFF1*/ +/* P1_NOSDIFF1 */ #define RSTV0910_P1_NOSDIFF1 0xf50b #define FSTV0910_P1_NOSTHRES1_DIFF 0xf50b00ff -/*P1_RAINFADE*/ +/* P1_RAINFADE */ #define RSTV0910_P1_RAINFADE 0xf50c #define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080 #define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070 #define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007 -/*P1_NOSRAMCFG*/ +/* P1_NOSRAMCFG */ #define RSTV0910_P1_NOSRAMCFG 0xf50d #define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030 #define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008 #define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007 -/*P1_NOSRAMPOS*/ +/* P1_NOSRAMPOS */ #define RSTV0910_P1_NOSRAMPOS 0xf50e #define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0 #define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004 #define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003 -/*P1_NOSRAMVAL*/ +/* P1_NOSRAMVAL */ #define RSTV0910_P1_NOSRAMVAL 0xf50f #define FSTV0910_P1_NOSRAM_CNRVAL0 0xf50f00ff -/*P1_DMDPLHSTAT*/ +/* P1_DMDPLHSTAT */ #define RSTV0910_P1_DMDPLHSTAT 0xf520 #define FSTV0910_P1_PLH_STATISTIC 0xf52000ff -/*P1_LOCKTIME3*/ +/* P1_LOCKTIME3 */ #define RSTV0910_P1_LOCKTIME3 0xf522 #define FSTV0910_P1_DEMOD_LOCKTIME3 0xf52200ff -/*P1_LOCKTIME2*/ +/* P1_LOCKTIME2 */ #define RSTV0910_P1_LOCKTIME2 0xf523 #define FSTV0910_P1_DEMOD_LOCKTIME2 0xf52300ff -/*P1_LOCKTIME1*/ +/* P1_LOCKTIME1 */ #define RSTV0910_P1_LOCKTIME1 0xf524 #define FSTV0910_P1_DEMOD_LOCKTIME1 0xf52400ff -/*P1_LOCKTIME0*/ +/* P1_LOCKTIME0 */ #define RSTV0910_P1_LOCKTIME0 0xf525 #define FSTV0910_P1_DEMOD_LOCKTIME0 0xf52500ff -/*P1_VITSCALE*/ +/* P1_VITSCALE */ #define RSTV0910_P1_VITSCALE 0xf532 #define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080 #define FSTV0910_P1_VERROR_MAXMODE 0xf5320040 #define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008 #define FSTV0910_P1_DIS_RSFLOCK 0xf5320002 -/*P1_FECM*/ +/* P1_FECM */ #define RSTV0910_P1_FECM 0xf533 #define FSTV0910_P1_DSS_DVB 0xf5330080 #define FSTV0910_P1_DSS_SRCH 0xf5330010 #define FSTV0910_P1_SYNCVIT 0xf5330002 #define FSTV0910_P1_IQINV 0xf5330001 -/*P1_VTH12*/ +/* P1_VTH12 */ #define RSTV0910_P1_VTH12 0xf534 #define FSTV0910_P1_VTH12 0xf53400ff -/*P1_VTH23*/ +/* P1_VTH23 */ #define RSTV0910_P1_VTH23 0xf535 #define FSTV0910_P1_VTH23 0xf53500ff -/*P1_VTH34*/ +/* P1_VTH34 */ #define RSTV0910_P1_VTH34 0xf536 #define FSTV0910_P1_VTH34 0xf53600ff -/*P1_VTH56*/ +/* P1_VTH56 */ #define RSTV0910_P1_VTH56 0xf537 #define FSTV0910_P1_VTH56 0xf53700ff -/*P1_VTH67*/ +/* P1_VTH67 */ #define RSTV0910_P1_VTH67 0xf538 #define FSTV0910_P1_VTH67 0xf53800ff -/*P1_VTH78*/ +/* P1_VTH78 */ #define RSTV0910_P1_VTH78 0xf539 #define FSTV0910_P1_VTH78 0xf53900ff -/*P1_VITCURPUN*/ +/* P1_VITCURPUN */ #define RSTV0910_P1_VITCURPUN 0xf53a #define FSTV0910_P1_VIT_CURPUN 0xf53a001f -/*P1_VERROR*/ +/* P1_VERROR */ #define RSTV0910_P1_VERROR 0xf53b #define FSTV0910_P1_REGERR_VIT 0xf53b00ff -/*P1_PRVIT*/ +/* P1_PRVIT */ #define RSTV0910_P1_PRVIT 0xf53c #define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040 #define FSTV0910_P1_E7_8VIT 0xf53c0020 @@ -3110,7 +3111,7 @@ #define FSTV0910_P1_E2_3VIT 0xf53c0002 #define FSTV0910_P1_E1_2VIT 0xf53c0001 -/*P1_VAVSRVIT*/ +/* P1_VAVSRVIT */ #define RSTV0910_P1_VAVSRVIT 0xf53d #define FSTV0910_P1_AMVIT 0xf53d0080 #define FSTV0910_P1_FROZENVIT 0xf53d0040 @@ -3118,52 +3119,52 @@ #define FSTV0910_P1_TOVVIT 0xf53d000c #define FSTV0910_P1_HYPVIT 0xf53d0003 -/*P1_VSTATUSVIT*/ +/* P1_VSTATUSVIT */ #define RSTV0910_P1_VSTATUSVIT 0xf53e #define FSTV0910_P1_PRFVIT 0xf53e0010 #define FSTV0910_P1_LOCKEDVIT 0xf53e0008 -/*P1_VTHINUSE*/ +/* P1_VTHINUSE */ #define RSTV0910_P1_VTHINUSE 0xf53f #define FSTV0910_P1_VIT_INUSE 0xf53f00ff -/*P1_KDIV12*/ +/* P1_KDIV12 */ #define RSTV0910_P1_KDIV12 0xf540 #define FSTV0910_P1_K_DIVIDER_12 0xf540007f -/*P1_KDIV23*/ +/* P1_KDIV23 */ #define RSTV0910_P1_KDIV23 0xf541 #define FSTV0910_P1_K_DIVIDER_23 0xf541007f -/*P1_KDIV34*/ +/* P1_KDIV34 */ #define RSTV0910_P1_KDIV34 0xf542 #define FSTV0910_P1_K_DIVIDER_34 0xf542007f -/*P1_KDIV56*/ +/* P1_KDIV56 */ #define RSTV0910_P1_KDIV56 0xf543 #define FSTV0910_P1_K_DIVIDER_56 0xf543007f -/*P1_KDIV67*/ +/* P1_KDIV67 */ #define RSTV0910_P1_KDIV67 0xf544 #define FSTV0910_P1_K_DIVIDER_67 0xf544007f -/*P1_KDIV78*/ +/* P1_KDIV78 */ #define RSTV0910_P1_KDIV78 0xf545 #define FSTV0910_P1_K_DIVIDER_78 0xf545007f -/*P1_TSPIDFLT1*/ +/* P1_TSPIDFLT1 */ #define RSTV0910_P1_TSPIDFLT1 0xf546 #define FSTV0910_P1_PIDFLT_ADDR 0xf54600ff -/*P1_TSPIDFLT0*/ +/* P1_TSPIDFLT0 */ #define RSTV0910_P1_TSPIDFLT0 0xf547 #define FSTV0910_P1_PIDFLT_DATA 0xf54700ff -/*P1_PDELCTRL0*/ +/* P1_PDELCTRL0 */ #define RSTV0910_P1_PDELCTRL0 0xf54f #define FSTV0910_P1_ISIOBS_MODE 0xf54f0030 -/*P1_PDELCTRL1*/ +/* P1_PDELCTRL1 */ #define RSTV0910_P1_PDELCTRL1 0xf550 #define FSTV0910_P1_INV_MISMASK 0xf5500080 #define FSTV0910_P1_FILTER_EN 0xf5500020 @@ -3172,68 +3173,68 @@ #define FSTV0910_P1_EN_MIS00 0xf5500002 #define FSTV0910_P1_ALGOSWRST 0xf5500001 -/*P1_PDELCTRL2*/ +/* P1_PDELCTRL2 */ #define RSTV0910_P1_PDELCTRL2 0xf551 #define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080 #define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040 #define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020 #define FSTV0910_P1_FRAME_MODE 0xf5510002 -/*P1_HYSTTHRESH*/ +/* P1_HYSTTHRESH */ #define RSTV0910_P1_HYSTTHRESH 0xf554 #define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0 #define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f -/*P1_UPLCCST0*/ +/* P1_UPLCCST0 */ #define RSTV0910_P1_UPLCCST0 0xf558 #define FSTV0910_P1_UPL_CST0 0xf55800f8 #define FSTV0910_P1_UPL_MODE 0xf5580007 -/*P1_ISIENTRY*/ +/* P1_ISIENTRY */ #define RSTV0910_P1_ISIENTRY 0xf55e #define FSTV0910_P1_ISI_ENTRY 0xf55e00ff -/*P1_ISIBITENA*/ +/* P1_ISIBITENA */ #define RSTV0910_P1_ISIBITENA 0xf55f #define FSTV0910_P1_ISI_BIT_EN 0xf55f00ff -/*P1_MATSTR1*/ +/* P1_MATSTR1 */ #define RSTV0910_P1_MATSTR1 0xf560 #define FSTV0910_P1_MATYPE_CURRENT1 0xf56000ff -/*P1_MATSTR0*/ +/* P1_MATSTR0 */ #define RSTV0910_P1_MATSTR0 0xf561 #define FSTV0910_P1_MATYPE_CURRENT0 0xf56100ff -/*P1_UPLSTR1*/ +/* P1_UPLSTR1 */ #define RSTV0910_P1_UPLSTR1 0xf562 #define FSTV0910_P1_UPL_CURRENT1 0xf56200ff -/*P1_UPLSTR0*/ +/* P1_UPLSTR0 */ #define RSTV0910_P1_UPLSTR0 0xf563 #define FSTV0910_P1_UPL_CURRENT0 0xf56300ff -/*P1_DFLSTR1*/ +/* P1_DFLSTR1 */ #define RSTV0910_P1_DFLSTR1 0xf564 #define FSTV0910_P1_DFL_CURRENT1 0xf56400ff -/*P1_DFLSTR0*/ +/* P1_DFLSTR0 */ #define RSTV0910_P1_DFLSTR0 0xf565 #define FSTV0910_P1_DFL_CURRENT0 0xf56500ff -/*P1_SYNCSTR*/ +/* P1_SYNCSTR */ #define RSTV0910_P1_SYNCSTR 0xf566 #define FSTV0910_P1_SYNC_CURRENT 0xf56600ff -/*P1_SYNCDSTR1*/ +/* P1_SYNCDSTR1 */ #define RSTV0910_P1_SYNCDSTR1 0xf567 #define FSTV0910_P1_SYNCD_CURRENT1 0xf56700ff -/*P1_SYNCDSTR0*/ +/* P1_SYNCDSTR0 */ #define RSTV0910_P1_SYNCDSTR0 0xf568 #define FSTV0910_P1_SYNCD_CURRENT0 0xf56800ff -/*P1_PDELSTATUS1*/ +/* P1_PDELSTATUS1 */ #define RSTV0910_P1_PDELSTATUS1 0xf569 #define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080 #define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040 @@ -3242,33 +3243,33 @@ #define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002 #define FSTV0910_P1_FIRST_LOCK 0xf5690001 -/*P1_PDELSTATUS2*/ +/* P1_PDELSTATUS2 */ #define RSTV0910_P1_PDELSTATUS2 0xf56a #define FSTV0910_P1_FRAME_MODCOD 0xf56a007c #define FSTV0910_P1_FRAME_TYPE 0xf56a0003 -/*P1_BBFCRCKO1*/ +/* P1_BBFCRCKO1 */ #define RSTV0910_P1_BBFCRCKO1 0xf56b #define FSTV0910_P1_BBHCRC_KOCNT1 0xf56b00ff -/*P1_BBFCRCKO0*/ +/* P1_BBFCRCKO0 */ #define RSTV0910_P1_BBFCRCKO0 0xf56c #define FSTV0910_P1_BBHCRC_KOCNT0 0xf56c00ff -/*P1_UPCRCKO1*/ +/* P1_UPCRCKO1 */ #define RSTV0910_P1_UPCRCKO1 0xf56d #define FSTV0910_P1_PKTCRC_KOCNT1 0xf56d00ff -/*P1_UPCRCKO0*/ +/* P1_UPCRCKO0 */ #define RSTV0910_P1_UPCRCKO0 0xf56e #define FSTV0910_P1_PKTCRC_KOCNT0 0xf56e00ff -/*P1_PDELCTRL3*/ +/* P1_PDELCTRL3 */ #define RSTV0910_P1_PDELCTRL3 0xf56f #define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020 #define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010 -/*P1_TSSTATEM*/ +/* P1_TSSTATEM */ #define RSTV0910_P1_TSSTATEM 0xf570 #define FSTV0910_P1_TSDIL_ON 0xf5700080 #define FSTV0910_P1_TSRS_ON 0xf5700020 @@ -3278,7 +3279,7 @@ #define FSTV0910_P1_TSACM_MODE 0xf5700002 #define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001 -/*P1_TSSTATEL*/ +/* P1_TSSTATEL */ #define RSTV0910_P1_TSSTATEL 0xf571 #define FSTV0910_P1_TSNOSYNCBYTE 0xf5710080 #define FSTV0910_P1_TSPARITY_ON 0xf5710040 @@ -3287,7 +3288,7 @@ #define FSTV0910_P1_TSCRC8_ON 0xf5710002 #define FSTV0910_P1_TSDSS_PACKET 0xf5710001 -/*P1_TSCFGH*/ +/* P1_TSCFGH */ #define RSTV0910_P1_TSCFGH 0xf572 #define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080 #define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040 @@ -3297,14 +3298,14 @@ #define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006 #define FSTV0910_P1_RST_HWARE 0xf5720001 -/*P1_TSCFGM*/ +/* P1_TSCFGM */ #define RSTV0910_P1_TSCFGM 0xf573 #define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0 #define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020 #define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010 #define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001 -/*P1_TSCFGL*/ +/* P1_TSCFGL */ #define RSTV0910_P1_TSCFGL 0xf574 #define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0 #define FSTV0910_P1_BCHERROR_MODE 0xf5740030 @@ -3312,11 +3313,11 @@ #define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004 #define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003 -/*P1_TSSYNC*/ +/* P1_TSSYNC */ #define RSTV0910_P1_TSSYNC 0xf575 #define FSTV0910_P1_TSFIFO_SYNCMODE 0xf5750018 -/*P1_TSINSDELH*/ +/* P1_TSINSDELH */ #define RSTV0910_P1_TSINSDELH 0xf576 #define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080 #define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040 @@ -3324,7 +3325,7 @@ #define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002 #define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001 -/*P1_TSINSDELM*/ +/* P1_TSINSDELM */ #define RSTV0910_P1_TSINSDELM 0xf577 #define FSTV0910_P1_TSINS_EMODCOD 0xf5770010 #define FSTV0910_P1_TSINS_TOKEN 0xf5770008 @@ -3332,7 +3333,7 @@ #define FSTV0910_P1_TSINS_MATYPE 0xf5770002 #define FSTV0910_P1_TSINS_UPL 0xf5770001 -/*P1_TSINSDELL*/ +/* P1_TSINSDELL */ #define RSTV0910_P1_TSINSDELL 0xf578 #define FSTV0910_P1_TSINS_DFL 0xf5780080 #define FSTV0910_P1_TSINS_SYNCD 0xf5780040 @@ -3343,20 +3344,20 @@ #define FSTV0910_P1_TSINS_TSCONFIG 0xf5780002 #define FSTV0910_P1_TSINS_LATENCY 0xf5780001 -/*P1_TSDIVN*/ +/* P1_TSDIVN */ #define RSTV0910_P1_TSDIVN 0xf579 #define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0 #define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007 -/*P1_TSCFG4*/ +/* P1_TSCFG4 */ #define RSTV0910_P1_TSCFG4 0xf57a #define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0 -/*P1_TSSPEED*/ +/* P1_TSSPEED */ #define RSTV0910_P1_TSSPEED 0xf580 #define FSTV0910_P1_TSFIFO_OUTSPEED 0xf58000ff -/*P1_TSSTATUS*/ +/* P1_TSSTATUS */ #define RSTV0910_P1_TSSTATUS 0xf581 #define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080 #define FSTV0910_P1_TSFIFO_ERROR 0xf5810040 @@ -3364,111 +3365,111 @@ #define FSTV0910_P1_TSREGUL_ERROR 0xf5810004 #define FSTV0910_P1_DIL_READY 0xf5810001 -/*P1_TSSTATUS2*/ +/* P1_TSSTATUS2 */ #define RSTV0910_P1_TSSTATUS2 0xf582 #define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080 #define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040 #define FSTV0910_P1_DILXX_RESET 0xf5820020 #define FSTV0910_P1_SCRAMBDETECT 0xf5820002 -/*P1_TSBITRATE1*/ +/* P1_TSBITRATE1 */ #define RSTV0910_P1_TSBITRATE1 0xf583 #define FSTV0910_P1_TSFIFO_BITRATE1 0xf58300ff -/*P1_TSBITRATE0*/ +/* P1_TSBITRATE0 */ #define RSTV0910_P1_TSBITRATE0 0xf584 #define FSTV0910_P1_TSFIFO_BITRATE0 0xf58400ff -/*P1_TSPACKLEN1*/ +/* P1_TSPACKLEN1 */ #define RSTV0910_P1_TSPACKLEN1 0xf585 #define FSTV0910_P1_TSFIFO_PACKCPT 0xf58500e0 -/*P1_TSDLY2*/ +/* P1_TSDLY2 */ #define RSTV0910_P1_TSDLY2 0xf589 #define FSTV0910_P1_SOFFIFO_LATENCY2 0xf589000f -/*P1_TSDLY1*/ +/* P1_TSDLY1 */ #define RSTV0910_P1_TSDLY1 0xf58a #define FSTV0910_P1_SOFFIFO_LATENCY1 0xf58a00ff -/*P1_TSDLY0*/ +/* P1_TSDLY0 */ #define RSTV0910_P1_TSDLY0 0xf58b #define FSTV0910_P1_SOFFIFO_LATENCY0 0xf58b00ff -/*P1_TSNPDAV*/ +/* P1_TSNPDAV */ #define RSTV0910_P1_TSNPDAV 0xf58c #define FSTV0910_P1_TSNPD_AVERAGE 0xf58c00ff -/*P1_TSBUFSTAT2*/ +/* P1_TSBUFSTAT2 */ #define RSTV0910_P1_TSBUFSTAT2 0xf58d #define FSTV0910_P1_TSISCR_3BYTES 0xf58d0080 #define FSTV0910_P1_TSISCR_NEWDATA 0xf58d0040 #define FSTV0910_P1_TSISCR_BUFSTAT2 0xf58d003f -/*P1_TSBUFSTAT1*/ +/* P1_TSBUFSTAT1 */ #define RSTV0910_P1_TSBUFSTAT1 0xf58e #define FSTV0910_P1_TSISCR_BUFSTAT1 0xf58e00ff -/*P1_TSBUFSTAT0*/ +/* P1_TSBUFSTAT0 */ #define RSTV0910_P1_TSBUFSTAT0 0xf58f #define FSTV0910_P1_TSISCR_BUFSTAT0 0xf58f00ff -/*P1_TSDEBUGL*/ +/* P1_TSDEBUGL */ #define RSTV0910_P1_TSDEBUGL 0xf591 #define FSTV0910_P1_TSFIFO_ERROR_EVNT 0xf5910004 #define FSTV0910_P1_TSFIFO_OVERFLOWM 0xf5910001 -/*P1_TSDLYSET2*/ +/* P1_TSDLYSET2 */ #define RSTV0910_P1_TSDLYSET2 0xf592 #define FSTV0910_P1_SOFFIFO_OFFSET 0xf59200c0 #define FSTV0910_P1_HYSTERESIS_THRESHOLD 0xf5920030 #define FSTV0910_P1_SOFFIFO_SYMBOFFS2 0xf592000f -/*P1_TSDLYSET1*/ +/* P1_TSDLYSET1 */ #define RSTV0910_P1_TSDLYSET1 0xf593 #define FSTV0910_P1_SOFFIFO_SYMBOFFS1 0xf59300ff -/*P1_TSDLYSET0*/ +/* P1_TSDLYSET0 */ #define RSTV0910_P1_TSDLYSET0 0xf594 #define FSTV0910_P1_SOFFIFO_SYMBOFFS0 0xf59400ff -/*P1_ERRCTRL1*/ +/* P1_ERRCTRL1 */ #define RSTV0910_P1_ERRCTRL1 0xf598 #define FSTV0910_P1_ERR_SOURCE1 0xf59800f0 #define FSTV0910_P1_NUM_EVENT1 0xf5980007 -/*P1_ERRCNT12*/ +/* P1_ERRCNT12 */ #define RSTV0910_P1_ERRCNT12 0xf599 #define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080 #define FSTV0910_P1_ERR_CNT12 0xf599007f -/*P1_ERRCNT11*/ +/* P1_ERRCNT11 */ #define RSTV0910_P1_ERRCNT11 0xf59a #define FSTV0910_P1_ERR_CNT11 0xf59a00ff -/*P1_ERRCNT10*/ +/* P1_ERRCNT10 */ #define RSTV0910_P1_ERRCNT10 0xf59b #define FSTV0910_P1_ERR_CNT10 0xf59b00ff -/*P1_ERRCTRL2*/ +/* P1_ERRCTRL2 */ #define RSTV0910_P1_ERRCTRL2 0xf59c #define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0 #define FSTV0910_P1_NUM_EVENT2 0xf59c0007 -/*P1_ERRCNT22*/ +/* P1_ERRCNT22 */ #define RSTV0910_P1_ERRCNT22 0xf59d #define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080 #define FSTV0910_P1_ERR_CNT22 0xf59d007f -/*P1_ERRCNT21*/ +/* P1_ERRCNT21 */ #define RSTV0910_P1_ERRCNT21 0xf59e #define FSTV0910_P1_ERR_CNT21 0xf59e00ff -/*P1_ERRCNT20*/ +/* P1_ERRCNT20 */ #define RSTV0910_P1_ERRCNT20 0xf59f #define FSTV0910_P1_ERR_CNT20 0xf59f00ff -/*P1_FECSPY*/ +/* P1_FECSPY */ #define RSTV0910_P1_FECSPY 0xf5a0 #define FSTV0910_P1_SPY_ENABLE 0xf5a00080 #define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040 @@ -3478,7 +3479,7 @@ #define FSTV0910_P1_BERMETER_LMODE 0xf5a00002 #define FSTV0910_P1_BERMETER_RESET 0xf5a00001 -/*P1_FSPYCFG*/ +/* P1_FSPYCFG */ #define RSTV0910_P1_FSPYCFG 0xf5a1 #define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0 #define FSTV0910_P1_RST_ON_ERROR 0xf5a10020 @@ -3486,18 +3487,18 @@ #define FSTV0910_P1_I2C_MODE 0xf5a1000c #define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003 -/*P1_FSPYDATA*/ +/* P1_FSPYDATA */ #define RSTV0910_P1_FSPYDATA 0xf5a2 #define FSTV0910_P1_SPY_STUFFING 0xf5a20080 #define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020 #define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f -/*P1_FSPYOUT*/ +/* P1_FSPYOUT */ #define RSTV0910_P1_FSPYOUT 0xf5a3 #define FSTV0910_P1_FSPY_DIRECT 0xf5a30080 #define FSTV0910_P1_STUFF_MODE 0xf5a30007 -/*P1_FSTATUS*/ +/* P1_FSTATUS */ #define RSTV0910_P1_FSTATUS 0xf5a4 #define FSTV0910_P1_SPY_ENDSIM 0xf5a40080 #define FSTV0910_P1_VALID_SIM 0xf5a40040 @@ -3505,49 +3506,49 @@ #define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010 #define FSTV0910_P1_RESULT_STATE 0xf5a4000f -/*P1_FBERCPT4*/ +/* P1_FBERCPT4 */ #define RSTV0910_P1_FBERCPT4 0xf5a8 #define FSTV0910_P1_FBERMETER_CPT4 0xf5a800ff -/*P1_FBERCPT3*/ +/* P1_FBERCPT3 */ #define RSTV0910_P1_FBERCPT3 0xf5a9 #define FSTV0910_P1_FBERMETER_CPT3 0xf5a900ff -/*P1_FBERCPT2*/ +/* P1_FBERCPT2 */ #define RSTV0910_P1_FBERCPT2 0xf5aa #define FSTV0910_P1_FBERMETER_CPT2 0xf5aa00ff -/*P1_FBERCPT1*/ +/* P1_FBERCPT1 */ #define RSTV0910_P1_FBERCPT1 0xf5ab #define FSTV0910_P1_FBERMETER_CPT1 0xf5ab00ff -/*P1_FBERCPT0*/ +/* P1_FBERCPT0 */ #define RSTV0910_P1_FBERCPT0 0xf5ac #define FSTV0910_P1_FBERMETER_CPT0 0xf5ac00ff -/*P1_FBERERR2*/ +/* P1_FBERERR2 */ #define RSTV0910_P1_FBERERR2 0xf5ad #define FSTV0910_P1_FBERMETER_ERR2 0xf5ad00ff -/*P1_FBERERR1*/ +/* P1_FBERERR1 */ #define RSTV0910_P1_FBERERR1 0xf5ae #define FSTV0910_P1_FBERMETER_ERR1 0xf5ae00ff -/*P1_FBERERR0*/ +/* P1_FBERERR0 */ #define RSTV0910_P1_FBERERR0 0xf5af #define FSTV0910_P1_FBERMETER_ERR0 0xf5af00ff -/*P1_FSPYBER*/ +/* P1_FSPYBER */ #define RSTV0910_P1_FSPYBER 0xf5b2 #define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010 #define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008 #define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007 -/*P1_SFERROR*/ +/* P1_SFERROR */ #define RSTV0910_P1_SFERROR 0xf5c1 #define FSTV0910_P1_SFEC_REGERR_VIT 0xf5c100ff -/*P1_SFECSTATUS*/ +/* P1_SFECSTATUS */ #define RSTV0910_P1_SFECSTATUS 0xf5c3 #define FSTV0910_P1_SFEC_ON 0xf5c30080 #define FSTV0910_P1_SFEC_OFF 0xf5c30040 @@ -3556,31 +3557,31 @@ #define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002 #define FSTV0910_P1_SFEC_OVFON 0xf5c30001 -/*P1_SFKDIV12*/ +/* P1_SFKDIV12 */ #define RSTV0910_P1_SFKDIV12 0xf5c4 #define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080 -/*P1_SFKDIV23*/ +/* P1_SFKDIV23 */ #define RSTV0910_P1_SFKDIV23 0xf5c5 #define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080 -/*P1_SFKDIV34*/ +/* P1_SFKDIV34 */ #define RSTV0910_P1_SFKDIV34 0xf5c6 #define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080 -/*P1_SFKDIV56*/ +/* P1_SFKDIV56 */ #define RSTV0910_P1_SFKDIV56 0xf5c7 #define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080 -/*P1_SFKDIV67*/ +/* P1_SFKDIV67 */ #define RSTV0910_P1_SFKDIV67 0xf5c8 #define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080 -/*P1_SFKDIV78*/ +/* P1_SFKDIV78 */ #define RSTV0910_P1_SFKDIV78 0xf5c9 #define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080 -/*P1_SFSTATUS*/ +/* P1_SFSTATUS */ #define RSTV0910_P1_SFSTATUS 0xf5cc #define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080 #define FSTV0910_P1_SFEC_ERROR 0xf5cc0040 @@ -3591,29 +3592,29 @@ #define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002 #define FSTV0910_P1_SFEC_READY 0xf5cc0001 -/*P1_SFDLYSET2*/ +/* P1_SFDLYSET2 */ #define RSTV0910_P1_SFDLYSET2 0xf5d0 #define FSTV0910_P1_SFEC_DISABLE 0xf5d00002 -/*P1_SFERRCTRL*/ +/* P1_SFERRCTRL */ #define RSTV0910_P1_SFERRCTRL 0xf5d8 #define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0 #define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007 -/*P1_SFERRCNT2*/ +/* P1_SFERRCNT2 */ #define RSTV0910_P1_SFERRCNT2 0xf5d9 #define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080 #define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f -/*P1_SFERRCNT1*/ +/* P1_SFERRCNT1 */ #define RSTV0910_P1_SFERRCNT1 0xf5da #define FSTV0910_P1_SFEC_ERR_CNT1 0xf5da00ff -/*P1_SFERRCNT0*/ +/* P1_SFERRCNT0 */ #define RSTV0910_P1_SFERRCNT0 0xf5db #define FSTV0910_P1_SFEC_ERR_CNT0 0xf5db00ff -/*RCCFG2*/ +/* RCCFG2 */ #define RSTV0910_RCCFG2 0xf600 #define FSTV0910_TSRCFIFO_DVBCI 0xf6000080 #define FSTV0910_TSRCFIFO_SERIAL 0xf6000040 @@ -3622,21 +3623,21 @@ #define FSTV0910_TSRCFIFO_HSGNLOUT 0xf6000008 #define FSTV0910_TSRCFIFO_ERRMODE 0xf6000006 -/*RCCFG1*/ +/* RCCFG1 */ #define RSTV0910_RCCFG1 0xf601 #define FSTV0910_TSRCFIFO_MANSPEED 0xf60100c0 #define FSTV0910_TSRCFIFO_PERMDATA 0xf6010020 #define FSTV0910_TSRCFIFO_NONEWSGNL 0xf6010010 #define FSTV0910_TSRCFIFO_INVDATA 0xf6010001 -/*RCCFG0*/ +/* RCCFG0 */ #define RSTV0910_RCCFG0 0xf602 #define FSTV0910_TSRCFIFO_BCLKDEL1CK 0xf60200c0 #define FSTV0910_TSRCFIFO_DUTY50 0xf6020010 #define FSTV0910_TSRCFIFO_NSGNL2DATA 0xf6020008 #define FSTV0910_TSRCFIFO_NPDSGNL 0xf6020004 -/*RCINSDEL2*/ +/* RCINSDEL2 */ #define RSTV0910_RCINSDEL2 0xf603 #define FSTV0910_TSRCDEL_SYNCBYTE 0xf6030080 #define FSTV0910_TSRCDEL_XXHEADER 0xf6030040 @@ -3647,7 +3648,7 @@ #define FSTV0910_TSRCINSDEL_RSPARITY 0xf6030002 #define FSTV0910_TSRCINSDEL_CRC8 0xf6030001 -/*RCINSDEL1*/ +/* RCINSDEL1 */ #define RSTV0910_RCINSDEL1 0xf604 #define FSTV0910_TSRCINS_BBPADDING 0xf6040080 #define FSTV0910_TSRCINS_BCHFEC 0xf6040040 @@ -3657,7 +3658,7 @@ #define FSTV0910_TSRCINS_MATYPE 0xf6040002 #define FSTV0910_TSRCINS_UPL 0xf6040001 -/*RCINSDEL0*/ +/* RCINSDEL0 */ #define RSTV0910_RCINSDEL0 0xf605 #define FSTV0910_TSRCINS_DFL 0xf6050080 #define FSTV0910_TSRCINS_SYNCD 0xf6050040 @@ -3668,7 +3669,7 @@ #define FSTV0910_TSRCINS_TSCONFIG 0xf6050002 #define FSTV0910_TSRCINS_LATENCY 0xf6050001 -/*RCSTATUS*/ +/* RCSTATUS */ #define RSTV0910_RCSTATUS 0xf606 #define FSTV0910_TSRCFIFO_LINEOK 0xf6060080 #define FSTV0910_TSRCFIFO_ERROR 0xf6060040 @@ -3677,17 +3678,17 @@ #define FSTV0910_TSRCFIFOSPEED_STORE 0xf6060004 #define FSTV0910_TSRCSPEED_IMPOSSIBLE 0xf6060001 -/*RCSPEED*/ +/* RCSPEED */ #define RSTV0910_RCSPEED 0xf607 #define FSTV0910_TSRCFIFO_OUTSPEED 0xf60700ff -/*TSGENERAL*/ +/* TSGENERAL */ #define RSTV0910_TSGENERAL 0xf630 #define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040 #define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008 #define FSTV0910_TSFIFO_PERMPARAL 0xf6300006 -/*P1_DISIRQCFG*/ +/* P1_DISIRQCFG */ #define RSTV0910_P1_DISIRQCFG 0xf700 #define FSTV0910_P1_ENRXEND 0xf7000040 #define FSTV0910_P1_ENRXFIFO8B 0xf7000020 @@ -3697,7 +3698,7 @@ #define FSTV0910_P1_ENTXFIFO64B 0xf7000002 #define FSTV0910_P1_ENGAPBURST 0xf7000001 -/*P1_DISIRQSTAT*/ +/* P1_DISIRQSTAT */ #define RSTV0910_P1_DISIRQSTAT 0xf701 #define FSTV0910_P1_IRQRXEND 0xf7010040 #define FSTV0910_P1_IRQRXFIFO8B 0xf7010020 @@ -3707,7 +3708,7 @@ #define FSTV0910_P1_IRQTXFIFO64B 0xf7010002 #define FSTV0910_P1_IRQGAPBURST 0xf7010001 -/*P1_DISTXCFG*/ +/* P1_DISTXCFG */ #define RSTV0910_P1_DISTXCFG 0xf702 #define FSTV0910_P1_DISTX_RESET 0xf7020080 #define FSTV0910_P1_TIM_OFF 0xf7020040 @@ -3716,7 +3717,7 @@ #define FSTV0910_P1_DIS_PRECHARGE 0xf7020004 #define FSTV0910_P1_DISEQC_MODE 0xf7020003 -/*P1_DISTXSTATUS*/ +/* P1_DISTXSTATUS */ #define RSTV0910_P1_DISTXSTATUS 0xf703 #define FSTV0910_P1_TX_FIFO_FULL 0xf7030040 #define FSTV0910_P1_TX_IDLE 0xf7030020 @@ -3726,28 +3727,28 @@ #define FSTV0910_P1_TR_TIMEOUT 0xf7030002 #define FSTV0910_P1_TR_FINISH 0xf7030001 -/*P1_DISTXBYTES*/ +/* P1_DISTXBYTES */ #define RSTV0910_P1_DISTXBYTES 0xf704 #define FSTV0910_P1_TXFIFO_BYTES 0xf70400ff -/*P1_DISTXFIFO*/ +/* P1_DISTXFIFO */ #define RSTV0910_P1_DISTXFIFO 0xf705 #define FSTV0910_P1_DISEQC_TX_FIFO 0xf70500ff -/*P1_DISTXF22*/ +/* P1_DISTXF22 */ #define RSTV0910_P1_DISTXF22 0xf706 #define FSTV0910_P1_F22TX 0xf70600ff -/*P1_DISTIMEOCFG*/ +/* P1_DISTIMEOCFG */ #define RSTV0910_P1_DISTIMEOCFG 0xf708 #define FSTV0910_P1_RXCHOICE 0xf7080006 #define FSTV0910_P1_TIMEOUT_OFF 0xf7080001 -/*P1_DISTIMEOUT*/ +/* P1_DISTIMEOUT */ #define RSTV0910_P1_DISTIMEOUT 0xf709 #define FSTV0910_P1_TIMEOUT_COUNT 0xf70900ff -/*P1_DISRXCFG*/ +/* P1_DISRXCFG */ #define RSTV0910_P1_DISRXCFG 0xf70a #define FSTV0910_P1_DISRX_RESET 0xf70a0080 #define FSTV0910_P1_EXTENVELOP 0xf70a0040 @@ -3756,7 +3757,7 @@ #define FSTV0910_P1_SIGNED_RXIN 0xf70a0002 #define FSTV0910_P1_DISRX_ON 0xf70a0001 -/*P1_DISRXSTAT1*/ +/* P1_DISRXSTAT1 */ #define RSTV0910_P1_DISRXSTAT1 0xf70b #define FSTV0910_P1_RXEND 0xf70b0080 #define FSTV0910_P1_RXACTIVE 0xf70b0040 @@ -3765,7 +3766,7 @@ #define FSTV0910_P1_8BFIFOREADY 0xf70b0008 #define FSTV0910_P1_FIFOEMPTY 0xf70b0004 -/*P1_DISRXSTAT0*/ +/* P1_DISRXSTAT0 */ #define RSTV0910_P1_DISRXSTAT0 0xf70c #define FSTV0910_P1_RXFAIL 0xf70c0080 #define FSTV0910_P1_FIFOPFAIL 0xf70c0040 @@ -3774,55 +3775,55 @@ #define FSTV0910_P1_SHORT22K 0xf70c0008 #define FSTV0910_P1_RXMSGLOST 0xf70c0004 -/*P1_DISRXBYTES*/ +/* P1_DISRXBYTES */ #define RSTV0910_P1_DISRXBYTES 0xf70d #define FSTV0910_P1_RXFIFO_BYTES 0xf70d001f -/*P1_DISRXPARITY1*/ +/* P1_DISRXPARITY1 */ #define RSTV0910_P1_DISRXPARITY1 0xf70e #define FSTV0910_P1_DISRX_PARITY1 0xf70e00ff -/*P1_DISRXPARITY0*/ +/* P1_DISRXPARITY0 */ #define RSTV0910_P1_DISRXPARITY0 0xf70f #define FSTV0910_P1_DISRX_PARITY0 0xf70f00ff -/*P1_DISRXFIFO*/ +/* P1_DISRXFIFO */ #define RSTV0910_P1_DISRXFIFO 0xf710 #define FSTV0910_P1_DISEQC_RX_FIFO 0xf71000ff -/*P1_DISRXDC1*/ +/* P1_DISRXDC1 */ #define RSTV0910_P1_DISRXDC1 0xf711 #define FSTV0910_P1_DC_VALUE1 0xf7110103 -/*P1_DISRXDC0*/ +/* P1_DISRXDC0 */ #define RSTV0910_P1_DISRXDC0 0xf712 #define FSTV0910_P1_DC_VALUE0 0xf71200ff -/*P1_DISRXF221*/ +/* P1_DISRXF221 */ #define RSTV0910_P1_DISRXF221 0xf714 #define FSTV0910_P1_F22RX1 0xf714000f -/*P1_DISRXF220*/ +/* P1_DISRXF220 */ #define RSTV0910_P1_DISRXF220 0xf715 #define FSTV0910_P1_F22RX0 0xf71500ff -/*P1_DISRXF100*/ +/* P1_DISRXF100 */ #define RSTV0910_P1_DISRXF100 0xf716 #define FSTV0910_P1_F100RX 0xf71600ff -/*P1_DISRXSHORT22K*/ +/* P1_DISRXSHORT22K */ #define RSTV0910_P1_DISRXSHORT22K 0xf71c #define FSTV0910_P1_SHORT22K_LENGTH 0xf71c001f -/*P1_ACRPRESC*/ +/* P1_ACRPRESC */ #define RSTV0910_P1_ACRPRESC 0xf71e #define FSTV0910_P1_ACR_PRESC 0xf71e0007 -/*P1_ACRDIV*/ +/* P1_ACRDIV */ #define RSTV0910_P1_ACRDIV 0xf71f #define FSTV0910_P1_ACR_DIV 0xf71f00ff -/*P2_DISIRQCFG*/ +/* P2_DISIRQCFG */ #define RSTV0910_P2_DISIRQCFG 0xf740 #define FSTV0910_P2_ENRXEND 0xf7400040 #define FSTV0910_P2_ENRXFIFO8B 0xf7400020 @@ -3832,7 +3833,7 @@ #define FSTV0910_P2_ENTXFIFO64B 0xf7400002 #define FSTV0910_P2_ENGAPBURST 0xf7400001 -/*P2_DISIRQSTAT*/ +/* P2_DISIRQSTAT */ #define RSTV0910_P2_DISIRQSTAT 0xf741 #define FSTV0910_P2_IRQRXEND 0xf7410040 #define FSTV0910_P2_IRQRXFIFO8B 0xf7410020 @@ -3842,7 +3843,7 @@ #define FSTV0910_P2_IRQTXFIFO64B 0xf7410002 #define FSTV0910_P2_IRQGAPBURST 0xf7410001 -/*P2_DISTXCFG*/ +/* P2_DISTXCFG */ #define RSTV0910_P2_DISTXCFG 0xf742 #define FSTV0910_P2_DISTX_RESET 0xf7420080 #define FSTV0910_P2_TIM_OFF 0xf7420040 @@ -3851,7 +3852,7 @@ #define FSTV0910_P2_DIS_PRECHARGE 0xf7420004 #define FSTV0910_P2_DISEQC_MODE 0xf7420003 -/*P2_DISTXSTATUS*/ +/* P2_DISTXSTATUS */ #define RSTV0910_P2_DISTXSTATUS 0xf743 #define FSTV0910_P2_TX_FIFO_FULL 0xf7430040 #define FSTV0910_P2_TX_IDLE 0xf7430020 @@ -3861,28 +3862,28 @@ #define FSTV0910_P2_TR_TIMEOUT 0xf7430002 #define FSTV0910_P2_TR_FINISH 0xf7430001 -/*P2_DISTXBYTES*/ +/* P2_DISTXBYTES */ #define RSTV0910_P2_DISTXBYTES 0xf744 #define FSTV0910_P2_TXFIFO_BYTES 0xf74400ff -/*P2_DISTXFIFO*/ +/* P2_DISTXFIFO */ #define RSTV0910_P2_DISTXFIFO 0xf745 #define FSTV0910_P2_DISEQC_TX_FIFO 0xf74500ff -/*P2_DISTXF22*/ +/* P2_DISTXF22 */ #define RSTV0910_P2_DISTXF22 0xf746 #define FSTV0910_P2_F22TX 0xf74600ff -/*P2_DISTIMEOCFG*/ +/* P2_DISTIMEOCFG */ #define RSTV0910_P2_DISTIMEOCFG 0xf748 #define FSTV0910_P2_RXCHOICE 0xf7480006 #define FSTV0910_P2_TIMEOUT_OFF 0xf7480001 -/*P2_DISTIMEOUT*/ +/* P2_DISTIMEOUT */ #define RSTV0910_P2_DISTIMEOUT 0xf749 #define FSTV0910_P2_TIMEOUT_COUNT 0xf74900ff -/*P2_DISRXCFG*/ +/* P2_DISRXCFG */ #define RSTV0910_P2_DISRXCFG 0xf74a #define FSTV0910_P2_DISRX_RESET 0xf74a0080 #define FSTV0910_P2_EXTENVELOP 0xf74a0040 @@ -3891,7 +3892,7 @@ #define FSTV0910_P2_SIGNED_RXIN 0xf74a0002 #define FSTV0910_P2_DISRX_ON 0xf74a0001 -/*P2_DISRXSTAT1*/ +/* P2_DISRXSTAT1 */ #define RSTV0910_P2_DISRXSTAT1 0xf74b #define FSTV0910_P2_RXEND 0xf74b0080 #define FSTV0910_P2_RXACTIVE 0xf74b0040 @@ -3900,7 +3901,7 @@ #define FSTV0910_P2_8BFIFOREADY 0xf74b0008 #define FSTV0910_P2_FIFOEMPTY 0xf74b0004 -/*P2_DISRXSTAT0*/ +/* P2_DISRXSTAT0 */ #define RSTV0910_P2_DISRXSTAT0 0xf74c #define FSTV0910_P2_RXFAIL 0xf74c0080 #define FSTV0910_P2_FIFOPFAIL 0xf74c0040 @@ -3909,270 +3910,270 @@ #define FSTV0910_P2_SHORT22K 0xf74c0008 #define FSTV0910_P2_RXMSGLOST 0xf74c0004 -/*P2_DISRXBYTES*/ +/* P2_DISRXBYTES */ #define RSTV0910_P2_DISRXBYTES 0xf74d #define FSTV0910_P2_RXFIFO_BYTES 0xf74d001f -/*P2_DISRXPARITY1*/ +/* P2_DISRXPARITY1 */ #define RSTV0910_P2_DISRXPARITY1 0xf74e #define FSTV0910_P2_DISRX_PARITY1 0xf74e00ff -/*P2_DISRXPARITY0*/ +/* P2_DISRXPARITY0 */ #define RSTV0910_P2_DISRXPARITY0 0xf74f #define FSTV0910_P2_DISRX_PARITY0 0xf74f00ff -/*P2_DISRXFIFO*/ +/* P2_DISRXFIFO */ #define RSTV0910_P2_DISRXFIFO 0xf750 #define FSTV0910_P2_DISEQC_RX_FIFO 0xf75000ff -/*P2_DISRXDC1*/ +/* P2_DISRXDC1 */ #define RSTV0910_P2_DISRXDC1 0xf751 #define FSTV0910_P2_DC_VALUE1 0xf7510103 -/*P2_DISRXDC0*/ +/* P2_DISRXDC0 */ #define RSTV0910_P2_DISRXDC0 0xf752 #define FSTV0910_P2_DC_VALUE0 0xf75200ff -/*P2_DISRXF221*/ +/* P2_DISRXF221 */ #define RSTV0910_P2_DISRXF221 0xf754 #define FSTV0910_P2_F22RX1 0xf754000f -/*P2_DISRXF220*/ +/* P2_DISRXF220 */ #define RSTV0910_P2_DISRXF220 0xf755 #define FSTV0910_P2_F22RX0 0xf75500ff -/*P2_DISRXF100*/ +/* P2_DISRXF100 */ #define RSTV0910_P2_DISRXF100 0xf756 #define FSTV0910_P2_F100RX 0xf75600ff -/*P2_DISRXSHORT22K*/ +/* P2_DISRXSHORT22K */ #define RSTV0910_P2_DISRXSHORT22K 0xf75c #define FSTV0910_P2_SHORT22K_LENGTH 0xf75c001f -/*P2_ACRPRESC*/ +/* P2_ACRPRESC */ #define RSTV0910_P2_ACRPRESC 0xf75e #define FSTV0910_P2_ACR_PRESC 0xf75e0007 -/*P2_ACRDIV*/ +/* P2_ACRDIV */ #define RSTV0910_P2_ACRDIV 0xf75f #define FSTV0910_P2_ACR_DIV 0xf75f00ff -/*P1_NBITER_NF1*/ +/* P1_NBITER_NF1 */ #define RSTV0910_P1_NBITER_NF1 0xfa00 #define FSTV0910_P1_NBITER_NF_QPSK_1_4 0xfa0000ff -/*P1_NBITER_NF2*/ +/* P1_NBITER_NF2 */ #define RSTV0910_P1_NBITER_NF2 0xfa01 #define FSTV0910_P1_NBITER_NF_QPSK_1_3 0xfa0100ff -/*P1_NBITER_NF3*/ +/* P1_NBITER_NF3 */ #define RSTV0910_P1_NBITER_NF3 0xfa02 #define FSTV0910_P1_NBITER_NF_QPSK_2_5 0xfa0200ff -/*P1_NBITER_NF4*/ +/* P1_NBITER_NF4 */ #define RSTV0910_P1_NBITER_NF4 0xfa03 #define FSTV0910_P1_NBITER_NF_QPSK_1_2 0xfa0300ff -/*P1_NBITER_NF5*/ +/* P1_NBITER_NF5 */ #define RSTV0910_P1_NBITER_NF5 0xfa04 #define FSTV0910_P1_NBITER_NF_QPSK_3_5 0xfa0400ff -/*P1_NBITER_NF6*/ +/* P1_NBITER_NF6 */ #define RSTV0910_P1_NBITER_NF6 0xfa05 #define FSTV0910_P1_NBITER_NF_QPSK_2_3 0xfa0500ff -/*P1_NBITER_NF7*/ +/* P1_NBITER_NF7 */ #define RSTV0910_P1_NBITER_NF7 0xfa06 #define FSTV0910_P1_NBITER_NF_QPSK_3_4 0xfa0600ff -/*P1_NBITER_NF8*/ +/* P1_NBITER_NF8 */ #define RSTV0910_P1_NBITER_NF8 0xfa07 #define FSTV0910_P1_NBITER_NF_QPSK_4_5 0xfa0700ff -/*P1_NBITER_NF9*/ +/* P1_NBITER_NF9 */ #define RSTV0910_P1_NBITER_NF9 0xfa08 #define FSTV0910_P1_NBITER_NF_QPSK_5_6 0xfa0800ff -/*P1_NBITER_NF10*/ +/* P1_NBITER_NF10 */ #define RSTV0910_P1_NBITER_NF10 0xfa09 #define FSTV0910_P1_NBITER_NF_QPSK_8_9 0xfa0900ff -/*P1_NBITER_NF11*/ +/* P1_NBITER_NF11 */ #define RSTV0910_P1_NBITER_NF11 0xfa0a #define FSTV0910_P1_NBITER_NF_QPSK_9_10 0xfa0a00ff -/*P1_NBITER_NF12*/ +/* P1_NBITER_NF12 */ #define RSTV0910_P1_NBITER_NF12 0xfa0b #define FSTV0910_P1_NBITER_NF_8PSK_3_5 0xfa0b00ff -/*P1_NBITER_NF13*/ +/* P1_NBITER_NF13 */ #define RSTV0910_P1_NBITER_NF13 0xfa0c #define FSTV0910_P1_NBITER_NF_8PSK_2_3 0xfa0c00ff -/*P1_NBITER_NF14*/ +/* P1_NBITER_NF14 */ #define RSTV0910_P1_NBITER_NF14 0xfa0d #define FSTV0910_P1_NBITER_NF_8PSK_3_4 0xfa0d00ff -/*P1_NBITER_NF15*/ +/* P1_NBITER_NF15 */ #define RSTV0910_P1_NBITER_NF15 0xfa0e #define FSTV0910_P1_NBITER_NF_8PSK_5_6 0xfa0e00ff -/*P1_NBITER_NF16*/ +/* P1_NBITER_NF16 */ #define RSTV0910_P1_NBITER_NF16 0xfa0f #define FSTV0910_P1_NBITER_NF_8PSK_8_9 0xfa0f00ff -/*P1_NBITER_NF17*/ +/* P1_NBITER_NF17 */ #define RSTV0910_P1_NBITER_NF17 0xfa10 #define FSTV0910_P1_NBITER_NF_8PSK_9_10 0xfa1000ff -/*P1_NBITER_NF18*/ +/* P1_NBITER_NF18 */ #define RSTV0910_P1_NBITER_NF18 0xfa11 #define FSTV0910_P1_NBITER_NF_16APSK_2_3 0xfa1100ff -/*P1_NBITER_NF19*/ +/* P1_NBITER_NF19 */ #define RSTV0910_P1_NBITER_NF19 0xfa12 #define FSTV0910_P1_NBITER_NF_16APSK_3_4 0xfa1200ff -/*P1_NBITER_NF20*/ +/* P1_NBITER_NF20 */ #define RSTV0910_P1_NBITER_NF20 0xfa13 #define FSTV0910_P1_NBITER_NF_16APSK_4_5 0xfa1300ff -/*P1_NBITER_NF21*/ +/* P1_NBITER_NF21 */ #define RSTV0910_P1_NBITER_NF21 0xfa14 #define FSTV0910_P1_NBITER_NF_16APSK_5_6 0xfa1400ff -/*P1_NBITER_NF22*/ +/* P1_NBITER_NF22 */ #define RSTV0910_P1_NBITER_NF22 0xfa15 #define FSTV0910_P1_NBITER_NF_16APSK_8_9 0xfa1500ff -/*P1_NBITER_NF23*/ +/* P1_NBITER_NF23 */ #define RSTV0910_P1_NBITER_NF23 0xfa16 #define FSTV0910_P1_NBITER_NF_16APSK_9_10 0xfa1600ff -/*P1_NBITER_NF24*/ +/* P1_NBITER_NF24 */ #define RSTV0910_P1_NBITER_NF24 0xfa17 #define FSTV0910_P1_NBITER_NF_32APSK_3_4 0xfa1700ff -/*P1_NBITER_NF25*/ +/* P1_NBITER_NF25 */ #define RSTV0910_P1_NBITER_NF25 0xfa18 #define FSTV0910_P1_NBITER_NF_32APSK_4_5 0xfa1800ff -/*P1_NBITER_NF26*/ +/* P1_NBITER_NF26 */ #define RSTV0910_P1_NBITER_NF26 0xfa19 #define FSTV0910_P1_NBITER_NF_32APSK_5_6 0xfa1900ff -/*P1_NBITER_NF27*/ +/* P1_NBITER_NF27 */ #define RSTV0910_P1_NBITER_NF27 0xfa1a #define FSTV0910_P1_NBITER_NF_32APSK_8_9 0xfa1a00ff -/*P1_NBITER_NF28*/ +/* P1_NBITER_NF28 */ #define RSTV0910_P1_NBITER_NF28 0xfa1b #define FSTV0910_P1_NBITER_NF_32APSK_9_10 0xfa1b00ff -/*P1_NBITER_SF1*/ +/* P1_NBITER_SF1 */ #define RSTV0910_P1_NBITER_SF1 0xfa1c #define FSTV0910_P1_NBITER_SF_QPSK_1_4 0xfa1c00ff -/*P1_NBITER_SF2*/ +/* P1_NBITER_SF2 */ #define RSTV0910_P1_NBITER_SF2 0xfa1d #define FSTV0910_P1_NBITER_SF_QPSK_1_3 0xfa1d00ff -/*P1_NBITER_SF3*/ +/* P1_NBITER_SF3 */ #define RSTV0910_P1_NBITER_SF3 0xfa1e #define FSTV0910_P1_NBITER_SF_QPSK_2_5 0xfa1e00ff -/*P1_NBITER_SF4*/ +/* P1_NBITER_SF4 */ #define RSTV0910_P1_NBITER_SF4 0xfa1f #define FSTV0910_P1_NBITER_SF_QPSK_1_2 0xfa1f00ff -/*P1_NBITER_SF5*/ +/* P1_NBITER_SF5 */ #define RSTV0910_P1_NBITER_SF5 0xfa20 #define FSTV0910_P1_NBITER_SF_QPSK_3_5 0xfa2000ff -/*P1_NBITER_SF6*/ +/* P1_NBITER_SF6 */ #define RSTV0910_P1_NBITER_SF6 0xfa21 #define FSTV0910_P1_NBITER_SF_QPSK_2_3 0xfa2100ff -/*P1_NBITER_SF7*/ +/* P1_NBITER_SF7 */ #define RSTV0910_P1_NBITER_SF7 0xfa22 #define FSTV0910_P1_NBITER_SF_QPSK_3_4 0xfa2200ff -/*P1_NBITER_SF8*/ +/* P1_NBITER_SF8 */ #define RSTV0910_P1_NBITER_SF8 0xfa23 #define FSTV0910_P1_NBITER_SF_QPSK_4_5 0xfa2300ff -/*P1_NBITER_SF9*/ +/* P1_NBITER_SF9 */ #define RSTV0910_P1_NBITER_SF9 0xfa24 #define FSTV0910_P1_NBITER_SF_QPSK_5_6 0xfa2400ff -/*P1_NBITER_SF10*/ +/* P1_NBITER_SF10 */ #define RSTV0910_P1_NBITER_SF10 0xfa25 #define FSTV0910_P1_NBITER_SF_QPSK_8_9 0xfa2500ff -/*P1_NBITER_SF12*/ +/* P1_NBITER_SF12 */ #define RSTV0910_P1_NBITER_SF12 0xfa26 #define FSTV0910_P1_NBITER_SF_8PSK_3_5 0xfa2600ff -/*P1_NBITER_SF13*/ +/* P1_NBITER_SF13 */ #define RSTV0910_P1_NBITER_SF13 0xfa27 #define FSTV0910_P1_NBITER_SF_8PSK_2_3 0xfa2700ff -/*P1_NBITER_SF14*/ +/* P1_NBITER_SF14 */ #define RSTV0910_P1_NBITER_SF14 0xfa28 #define FSTV0910_P1_NBITER_SF_8PSK_3_4 0xfa2800ff -/*P1_NBITER_SF15*/ +/* P1_NBITER_SF15 */ #define RSTV0910_P1_NBITER_SF15 0xfa29 #define FSTV0910_P1_NBITER_SF_8PSK_5_6 0xfa2900ff -/*P1_NBITER_SF16*/ +/* P1_NBITER_SF16 */ #define RSTV0910_P1_NBITER_SF16 0xfa2a #define FSTV0910_P1_NBITER_SF_8PSK_8_9 0xfa2a00ff -/*P1_NBITER_SF18*/ +/* P1_NBITER_SF18 */ #define RSTV0910_P1_NBITER_SF18 0xfa2b #define FSTV0910_P1_NBITER_SF_16APSK_2_3 0xfa2b00ff -/*P1_NBITER_SF19*/ +/* P1_NBITER_SF19 */ #define RSTV0910_P1_NBITER_SF19 0xfa2c #define FSTV0910_P1_NBITER_SF_16APSK_3_4 0xfa2c00ff -/*P1_NBITER_SF20*/ +/* P1_NBITER_SF20 */ #define RSTV0910_P1_NBITER_SF20 0xfa2d #define FSTV0910_P1_NBITER_SF_16APSK_4_5 0xfa2d00ff -/*P1_NBITER_SF21*/ +/* P1_NBITER_SF21 */ #define RSTV0910_P1_NBITER_SF21 0xfa2e #define FSTV0910_P1_NBITER_SF_16APSK_5_6 0xfa2e00ff -/*P1_NBITER_SF22*/ +/* P1_NBITER_SF22 */ #define RSTV0910_P1_NBITER_SF22 0xfa2f #define FSTV0910_P1_NBITER_SF_16APSK_8_9 0xfa2f00ff -/*P1_NBITER_SF24*/ +/* P1_NBITER_SF24 */ #define RSTV0910_P1_NBITER_SF24 0xfa30 #define FSTV0910_P1_NBITER_SF_32APSK_3_4 0xfa3000ff -/*P1_NBITER_SF25*/ +/* P1_NBITER_SF25 */ #define RSTV0910_P1_NBITER_SF25 0xfa31 #define FSTV0910_P1_NBITER_SF_32APSK_4_5 0xfa3100ff -/*P1_NBITER_SF26*/ +/* P1_NBITER_SF26 */ #define RSTV0910_P1_NBITER_SF26 0xfa32 #define FSTV0910_P1_NBITER_SF_32APSK_5_6 0xfa3200ff -/*P1_NBITER_SF27*/ +/* P1_NBITER_SF27 */ #define RSTV0910_P1_NBITER_SF27 0xfa33 #define FSTV0910_P1_NBITER_SF_32APSK_8_9 0xfa3300ff -/*SELSATUR6*/ +/* SELSATUR6 */ #define RSTV0910_SELSATUR6 0xfa34 #define FSTV0910_SSAT_SF27 0xfa340008 #define FSTV0910_SSAT_SF26 0xfa340004 #define FSTV0910_SSAT_SF25 0xfa340002 #define FSTV0910_SSAT_SF24 0xfa340001 -/*SELSATUR5*/ +/* SELSATUR5 */ #define RSTV0910_SELSATUR5 0xfa35 #define FSTV0910_SSAT_SF22 0xfa350080 #define FSTV0910_SSAT_SF21 0xfa350040 @@ -4183,7 +4184,7 @@ #define FSTV0910_SSAT_SF15 0xfa350002 #define FSTV0910_SSAT_SF14 0xfa350001 -/*SELSATUR4*/ +/* SELSATUR4 */ #define RSTV0910_SELSATUR4 0xfa36 #define FSTV0910_SSAT_SF13 0xfa360080 #define FSTV0910_SSAT_SF12 0xfa360040 @@ -4194,7 +4195,7 @@ #define FSTV0910_SSAT_SF6 0xfa360002 #define FSTV0910_SSAT_SF5 0xfa360001 -/*SELSATUR3*/ +/* SELSATUR3 */ #define RSTV0910_SELSATUR3 0xfa37 #define FSTV0910_SSAT_SF4 0xfa370080 #define FSTV0910_SSAT_SF3 0xfa370040 @@ -4205,7 +4206,7 @@ #define FSTV0910_SSAT_NF26 0xfa370002 #define FSTV0910_SSAT_NF25 0xfa370001 -/*SELSATUR2*/ +/* SELSATUR2 */ #define RSTV0910_SELSATUR2 0xfa38 #define FSTV0910_SSAT_NF24 0xfa380080 #define FSTV0910_SSAT_NF23 0xfa380040 @@ -4216,7 +4217,7 @@ #define FSTV0910_SSAT_NF18 0xfa380002 #define FSTV0910_SSAT_NF17 0xfa380001 -/*SELSATUR1*/ +/* SELSATUR1 */ #define RSTV0910_SELSATUR1 0xfa39 #define FSTV0910_SSAT_NF16 0xfa390080 #define FSTV0910_SSAT_NF15 0xfa390040 @@ -4227,7 +4228,7 @@ #define FSTV0910_SSAT_NF10 0xfa390002 #define FSTV0910_SSAT_NF9 0xfa390001 -/*SELSATUR0*/ +/* SELSATUR0 */ #define RSTV0910_SELSATUR0 0xfa3a #define FSTV0910_SSAT_NF8 0xfa3a0080 #define FSTV0910_SSAT_NF7 0xfa3a0040 @@ -4238,519 +4239,519 @@ #define FSTV0910_SSAT_NF2 0xfa3a0002 #define FSTV0910_SSAT_NF1 0xfa3a0001 -/*GAINLLR_NF1*/ +/* GAINLLR_NF1 */ #define RSTV0910_GAINLLR_NF1 0xfa40 #define FSTV0910_GAINLLR_NF_QPSK_1_4 0xfa40007f -/*GAINLLR_NF2*/ +/* GAINLLR_NF2 */ #define RSTV0910_GAINLLR_NF2 0xfa41 #define FSTV0910_GAINLLR_NF_QPSK_1_3 0xfa41007f -/*GAINLLR_NF3*/ +/* GAINLLR_NF3 */ #define RSTV0910_GAINLLR_NF3 0xfa42 #define FSTV0910_GAINLLR_NF_QPSK_2_5 0xfa42007f -/*GAINLLR_NF4*/ +/* GAINLLR_NF4 */ #define RSTV0910_GAINLLR_NF4 0xfa43 #define FSTV0910_GAINLLR_NF_QPSK_1_2 0xfa43007f -/*GAINLLR_NF5*/ +/* GAINLLR_NF5 */ #define RSTV0910_GAINLLR_NF5 0xfa44 #define FSTV0910_GAINLLR_NF_QPSK_3_5 0xfa44007f -/*GAINLLR_NF6*/ +/* GAINLLR_NF6 */ #define RSTV0910_GAINLLR_NF6 0xfa45 #define FSTV0910_GAINLLR_NF_QPSK_2_3 0xfa45007f -/*GAINLLR_NF7*/ +/* GAINLLR_NF7 */ #define RSTV0910_GAINLLR_NF7 0xfa46 #define FSTV0910_GAINLLR_NF_QPSK_3_4 0xfa46007f -/*GAINLLR_NF8*/ +/* GAINLLR_NF8 */ #define RSTV0910_GAINLLR_NF8 0xfa47 #define FSTV0910_GAINLLR_NF_QPSK_4_5 0xfa47007f -/*GAINLLR_NF9*/ +/* GAINLLR_NF9 */ #define RSTV0910_GAINLLR_NF9 0xfa48 #define FSTV0910_GAINLLR_NF_QPSK_5_6 0xfa48007f -/*GAINLLR_NF10*/ +/* GAINLLR_NF10 */ #define RSTV0910_GAINLLR_NF10 0xfa49 #define FSTV0910_GAINLLR_NF_QPSK_8_9 0xfa49007f -/*GAINLLR_NF11*/ +/* GAINLLR_NF11 */ #define RSTV0910_GAINLLR_NF11 0xfa4a #define FSTV0910_GAINLLR_NF_QPSK_9_10 0xfa4a007f -/*GAINLLR_NF12*/ +/* GAINLLR_NF12 */ #define RSTV0910_GAINLLR_NF12 0xfa4b #define FSTV0910_GAINLLR_NF_8PSK_3_5 0xfa4b007f -/*GAINLLR_NF13*/ +/* GAINLLR_NF13 */ #define RSTV0910_GAINLLR_NF13 0xfa4c #define FSTV0910_GAINLLR_NF_8PSK_2_3 0xfa4c007f -/*GAINLLR_NF14*/ +/* GAINLLR_NF14 */ #define RSTV0910_GAINLLR_NF14 0xfa4d #define FSTV0910_GAINLLR_NF_8PSK_3_4 0xfa4d007f -/*GAINLLR_NF15*/ +/* GAINLLR_NF15 */ #define RSTV0910_GAINLLR_NF15 0xfa4e #define FSTV0910_GAINLLR_NF_8PSK_5_6 0xfa4e007f -/*GAINLLR_NF16*/ +/* GAINLLR_NF16 */ #define RSTV0910_GAINLLR_NF16 0xfa4f #define FSTV0910_GAINLLR_NF_8PSK_8_9 0xfa4f007f -/*GAINLLR_NF17*/ +/* GAINLLR_NF17 */ #define RSTV0910_GAINLLR_NF17 0xfa50 #define FSTV0910_GAINLLR_NF_8PSK_9_10 0xfa50007f -/*GAINLLR_NF18*/ +/* GAINLLR_NF18 */ #define RSTV0910_GAINLLR_NF18 0xfa51 #define FSTV0910_GAINLLR_NF_16APSK_2_3 0xfa51007f -/*GAINLLR_NF19*/ +/* GAINLLR_NF19 */ #define RSTV0910_GAINLLR_NF19 0xfa52 #define FSTV0910_GAINLLR_NF_16APSK_3_4 0xfa52007f -/*GAINLLR_NF20*/ +/* GAINLLR_NF20 */ #define RSTV0910_GAINLLR_NF20 0xfa53 #define FSTV0910_GAINLLR_NF_16APSK_4_5 0xfa53007f -/*GAINLLR_NF21*/ +/* GAINLLR_NF21 */ #define RSTV0910_GAINLLR_NF21 0xfa54 #define FSTV0910_GAINLLR_NF_16APSK_5_6 0xfa54007f -/*GAINLLR_NF22*/ +/* GAINLLR_NF22 */ #define RSTV0910_GAINLLR_NF22 0xfa55 #define FSTV0910_GAINLLR_NF_16APSK_8_9 0xfa55007f -/*GAINLLR_NF23*/ +/* GAINLLR_NF23 */ #define RSTV0910_GAINLLR_NF23 0xfa56 #define FSTV0910_GAINLLR_NF_16APSK_9_10 0xfa56007f -/*GAINLLR_NF24*/ +/* GAINLLR_NF24 */ #define RSTV0910_GAINLLR_NF24 0xfa57 #define FSTV0910_GAINLLR_NF_32APSK_3_4 0xfa57007f -/*GAINLLR_NF25*/ +/* GAINLLR_NF25 */ #define RSTV0910_GAINLLR_NF25 0xfa58 #define FSTV0910_GAINLLR_NF_32APSK_4_5 0xfa58007f -/*GAINLLR_NF26*/ +/* GAINLLR_NF26 */ #define RSTV0910_GAINLLR_NF26 0xfa59 #define FSTV0910_GAINLLR_NF_32APSK_5_6 0xfa59007f -/*GAINLLR_NF27*/ +/* GAINLLR_NF27 */ #define RSTV0910_GAINLLR_NF27 0xfa5a #define FSTV0910_GAINLLR_NF_32APSK_8_9 0xfa5a007f -/*GAINLLR_NF28*/ +/* GAINLLR_NF28 */ #define RSTV0910_GAINLLR_NF28 0xfa5b #define FSTV0910_GAINLLR_NF_32APSK_9_10 0xfa5b007f -/*GAINLLR_SF1*/ +/* GAINLLR_SF1 */ #define RSTV0910_GAINLLR_SF1 0xfa5c #define FSTV0910_GAINLLR_SF_QPSK_1_4 0xfa5c007f -/*GAINLLR_SF2*/ +/* GAINLLR_SF2 */ #define RSTV0910_GAINLLR_SF2 0xfa5d #define FSTV0910_GAINLLR_SF_QPSK_1_3 0xfa5d007f -/*GAINLLR_SF3*/ +/* GAINLLR_SF3 */ #define RSTV0910_GAINLLR_SF3 0xfa5e #define FSTV0910_GAINLLR_SF_QPSK_2_5 0xfa5e007f -/*GAINLLR_SF4*/ +/* GAINLLR_SF4 */ #define RSTV0910_GAINLLR_SF4 0xfa5f #define FSTV0910_GAINLLR_SF_QPSK_1_2 0xfa5f007f -/*GAINLLR_SF5*/ +/* GAINLLR_SF5 */ #define RSTV0910_GAINLLR_SF5 0xfa60 #define FSTV0910_GAINLLR_SF_QPSK_3_5 0xfa60007f -/*GAINLLR_SF6*/ +/* GAINLLR_SF6 */ #define RSTV0910_GAINLLR_SF6 0xfa61 #define FSTV0910_GAINLLR_SF_QPSK_2_3 0xfa61007f -/*GAINLLR_SF7*/ +/* GAINLLR_SF7 */ #define RSTV0910_GAINLLR_SF7 0xfa62 #define FSTV0910_GAINLLR_SF_QPSK_3_4 0xfa62007f -/*GAINLLR_SF8*/ +/* GAINLLR_SF8 */ #define RSTV0910_GAINLLR_SF8 0xfa63 #define FSTV0910_GAINLLR_SF_QPSK_4_5 0xfa63007f -/*GAINLLR_SF9*/ +/* GAINLLR_SF9 */ #define RSTV0910_GAINLLR_SF9 0xfa64 #define FSTV0910_GAINLLR_SF_QPSK_5_6 0xfa64007f -/*GAINLLR_SF10*/ +/* GAINLLR_SF10 */ #define RSTV0910_GAINLLR_SF10 0xfa65 #define FSTV0910_GAINLLR_SF_QPSK_8_9 0xfa65007f -/*GAINLLR_SF12*/ +/* GAINLLR_SF12 */ #define RSTV0910_GAINLLR_SF12 0xfa66 #define FSTV0910_GAINLLR_SF_8PSK_3_5 0xfa66007f -/*GAINLLR_SF13*/ +/* GAINLLR_SF13 */ #define RSTV0910_GAINLLR_SF13 0xfa67 #define FSTV0910_GAINLLR_SF_8PSK_2_3 0xfa67007f -/*GAINLLR_SF14*/ +/* GAINLLR_SF14 */ #define RSTV0910_GAINLLR_SF14 0xfa68 #define FSTV0910_GAINLLR_SF_8PSK_3_4 0xfa68007f -/*GAINLLR_SF15*/ +/* GAINLLR_SF15 */ #define RSTV0910_GAINLLR_SF15 0xfa69 #define FSTV0910_GAINLLR_SF_8PSK_5_6 0xfa69007f -/*GAINLLR_SF16*/ +/* GAINLLR_SF16 */ #define RSTV0910_GAINLLR_SF16 0xfa6a #define FSTV0910_GAINLLR_SF_8PSK_8_9 0xfa6a007f -/*GAINLLR_SF18*/ +/* GAINLLR_SF18 */ #define RSTV0910_GAINLLR_SF18 0xfa6b #define FSTV0910_GAINLLR_SF_16APSK_2_3 0xfa6b007f -/*GAINLLR_SF19*/ +/* GAINLLR_SF19 */ #define RSTV0910_GAINLLR_SF19 0xfa6c #define FSTV0910_GAINLLR_SF_16APSK_3_4 0xfa6c007f -/*GAINLLR_SF20*/ +/* GAINLLR_SF20 */ #define RSTV0910_GAINLLR_SF20 0xfa6d #define FSTV0910_GAINLLR_SF_16APSK_4_5 0xfa6d007f -/*GAINLLR_SF21*/ +/* GAINLLR_SF21 */ #define RSTV0910_GAINLLR_SF21 0xfa6e #define FSTV0910_GAINLLR_SF_16APSK_5_6 0xfa6e007f -/*GAINLLR_SF22*/ +/* GAINLLR_SF22 */ #define RSTV0910_GAINLLR_SF22 0xfa6f #define FSTV0910_GAINLLR_SF_16APSK_8_9 0xfa6f007f -/*GAINLLR_SF24*/ +/* GAINLLR_SF24 */ #define RSTV0910_GAINLLR_SF24 0xfa70 #define FSTV0910_GAINLLR_SF_32APSK_3_4 0xfa70007f -/*GAINLLR_SF25*/ +/* GAINLLR_SF25 */ #define RSTV0910_GAINLLR_SF25 0xfa71 #define FSTV0910_GAINLLR_SF_32APSK_4_5 0xfa71007f -/*GAINLLR_SF26*/ +/* GAINLLR_SF26 */ #define RSTV0910_GAINLLR_SF26 0xfa72 #define FSTV0910_GAINLLR_SF_32APSK_5_6 0xfa72007f -/*GAINLLR_SF27*/ +/* GAINLLR_SF27 */ #define RSTV0910_GAINLLR_SF27 0xfa73 #define FSTV0910_GAINLLR_SF_32APSK_8_9 0xfa73007f -/*CFGEXT*/ +/* CFGEXT */ #define RSTV0910_CFGEXT 0xfa80 #define FSTV0910_BYPBCH 0xfa800040 #define FSTV0910_BYPLDPC 0xfa800020 #define FSTV0910_SHORTMULT 0xfa800004 -/*GENCFG*/ +/* GENCFG */ #define RSTV0910_GENCFG 0xfa86 #define FSTV0910_BROADCAST 0xfa860010 #define FSTV0910_CROSSINPUT 0xfa860002 #define FSTV0910_DDEMOD 0xfa860001 -/*LDPCERR1*/ +/* LDPCERR1 */ #define RSTV0910_LDPCERR1 0xfa96 #define FSTV0910_LDPC_ERRORS1 0xfa9600ff -/*LDPCERR0*/ +/* LDPCERR0 */ #define RSTV0910_LDPCERR0 0xfa97 #define FSTV0910_LDPC_ERRORS0 0xfa9700ff -/*BCHERR*/ +/* BCHERR */ #define RSTV0910_BCHERR 0xfa98 #define FSTV0910_ERRORFLAG 0xfa980010 #define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f -/*P1_MAXEXTRAITER*/ +/* P1_MAXEXTRAITER */ #define RSTV0910_P1_MAXEXTRAITER 0xfab1 #define FSTV0910_P1_MAX_EXTRA_ITER 0xfab100ff -/*P2_MAXEXTRAITER*/ +/* P2_MAXEXTRAITER */ #define RSTV0910_P2_MAXEXTRAITER 0xfab6 #define FSTV0910_P2_MAX_EXTRA_ITER 0xfab600ff -/*P1_STATUSITER*/ +/* P1_STATUSITER */ #define RSTV0910_P1_STATUSITER 0xfabc #define FSTV0910_P1_STATUS_ITER 0xfabc00ff -/*P1_STATUSMAXITER*/ +/* P1_STATUSMAXITER */ #define RSTV0910_P1_STATUSMAXITER 0xfabd #define FSTV0910_P1_STATUS_MAX_ITER 0xfabd00ff -/*P2_STATUSITER*/ +/* P2_STATUSITER */ #define RSTV0910_P2_STATUSITER 0xfabe #define FSTV0910_P2_STATUS_ITER 0xfabe00ff -/*P2_STATUSMAXITER*/ +/* P2_STATUSMAXITER */ #define RSTV0910_P2_STATUSMAXITER 0xfabf #define FSTV0910_P2_STATUS_MAX_ITER 0xfabf00ff -/*P2_NBITER_NF1*/ +/* P2_NBITER_NF1 */ #define RSTV0910_P2_NBITER_NF1 0xfac0 #define FSTV0910_P2_NBITER_NF_QPSK_1_4 0xfac000ff -/*P2_NBITER_NF2*/ +/* P2_NBITER_NF2 */ #define RSTV0910_P2_NBITER_NF2 0xfac1 #define FSTV0910_P2_NBITER_NF_QPSK_1_3 0xfac100ff -/*P2_NBITER_NF3*/ +/* P2_NBITER_NF3 */ #define RSTV0910_P2_NBITER_NF3 0xfac2 #define FSTV0910_P2_NBITER_NF_QPSK_2_5 0xfac200ff -/*P2_NBITER_NF4*/ +/* P2_NBITER_NF4 */ #define RSTV0910_P2_NBITER_NF4 0xfac3 #define FSTV0910_P2_NBITER_NF_QPSK_1_2 0xfac300ff -/*P2_NBITER_NF5*/ +/* P2_NBITER_NF5 */ #define RSTV0910_P2_NBITER_NF5 0xfac4 #define FSTV0910_P2_NBITER_NF_QPSK_3_5 0xfac400ff -/*P2_NBITER_NF6*/ +/* P2_NBITER_NF6 */ #define RSTV0910_P2_NBITER_NF6 0xfac5 #define FSTV0910_P2_NBITER_NF_QPSK_2_3 0xfac500ff -/*P2_NBITER_NF7*/ +/* P2_NBITER_NF7 */ #define RSTV0910_P2_NBITER_NF7 0xfac6 #define FSTV0910_P2_NBITER_NF_QPSK_3_4 0xfac600ff -/*P2_NBITER_NF8*/ +/* P2_NBITER_NF8 */ #define RSTV0910_P2_NBITER_NF8 0xfac7 #define FSTV0910_P2_NBITER_NF_QPSK_4_5 0xfac700ff -/*P2_NBITER_NF9*/ +/* P2_NBITER_NF9 */ #define RSTV0910_P2_NBITER_NF9 0xfac8 #define FSTV0910_P2_NBITER_NF_QPSK_5_6 0xfac800ff -/*P2_NBITER_NF10*/ +/* P2_NBITER_NF10 */ #define RSTV0910_P2_NBITER_NF10 0xfac9 #define FSTV0910_P2_NBITER_NF_QPSK_8_9 0xfac900ff -/*P2_NBITER_NF11*/ +/* P2_NBITER_NF11 */ #define RSTV0910_P2_NBITER_NF11 0xfaca #define FSTV0910_P2_NBITER_NF_QPSK_9_10 0xfaca00ff -/*P2_NBITER_NF12*/ +/* P2_NBITER_NF12 */ #define RSTV0910_P2_NBITER_NF12 0xfacb #define FSTV0910_P2_NBITER_NF_8PSK_3_5 0xfacb00ff -/*P2_NBITER_NF13*/ +/* P2_NBITER_NF13 */ #define RSTV0910_P2_NBITER_NF13 0xfacc #define FSTV0910_P2_NBITER_NF_8PSK_2_3 0xfacc00ff -/*P2_NBITER_NF14*/ +/* P2_NBITER_NF14 */ #define RSTV0910_P2_NBITER_NF14 0xfacd #define FSTV0910_P2_NBITER_NF_8PSK_3_4 0xfacd00ff -/*P2_NBITER_NF15*/ +/* P2_NBITER_NF15 */ #define RSTV0910_P2_NBITER_NF15 0xface #define FSTV0910_P2_NBITER_NF_8PSK_5_6 0xface00ff -/*P2_NBITER_NF16*/ +/* P2_NBITER_NF16 */ #define RSTV0910_P2_NBITER_NF16 0xfacf #define FSTV0910_P2_NBITER_NF_8PSK_8_9 0xfacf00ff -/*P2_NBITER_NF17*/ +/* P2_NBITER_NF17 */ #define RSTV0910_P2_NBITER_NF17 0xfad0 #define FSTV0910_P2_NBITER_NF_8PSK_9_10 0xfad000ff -/*P2_NBITER_NF18*/ +/* P2_NBITER_NF18 */ #define RSTV0910_P2_NBITER_NF18 0xfad1 #define FSTV0910_P2_NBITER_NF_16APSK_2_3 0xfad100ff -/*P2_NBITER_NF19*/ +/* P2_NBITER_NF19 */ #define RSTV0910_P2_NBITER_NF19 0xfad2 #define FSTV0910_P2_NBITER_NF_16APSK_3_4 0xfad200ff -/*P2_NBITER_NF20*/ +/* P2_NBITER_NF20 */ #define RSTV0910_P2_NBITER_NF20 0xfad3 #define FSTV0910_P2_NBITER_NF_16APSK_4_5 0xfad300ff -/*P2_NBITER_NF21*/ +/* P2_NBITER_NF21 */ #define RSTV0910_P2_NBITER_NF21 0xfad4 #define FSTV0910_P2_NBITER_NF_16APSK_5_6 0xfad400ff -/*P2_NBITER_NF22*/ +/* P2_NBITER_NF22 */ #define RSTV0910_P2_NBITER_NF22 0xfad5 #define FSTV0910_P2_NBITER_NF_16APSK_8_9 0xfad500ff -/*P2_NBITER_NF23*/ +/* P2_NBITER_NF23 */ #define RSTV0910_P2_NBITER_NF23 0xfad6 #define FSTV0910_P2_NBITER_NF_16APSK_9_10 0xfad600ff -/*P2_NBITER_NF24*/ +/* P2_NBITER_NF24 */ #define RSTV0910_P2_NBITER_NF24 0xfad7 #define FSTV0910_P2_NBITER_NF_32APSK_3_4 0xfad700ff -/*P2_NBITER_NF25*/ +/* P2_NBITER_NF25 */ #define RSTV0910_P2_NBITER_NF25 0xfad8 #define FSTV0910_P2_NBITER_NF_32APSK_4_5 0xfad800ff -/*P2_NBITER_NF26*/ +/* P2_NBITER_NF26 */ #define RSTV0910_P2_NBITER_NF26 0xfad9 #define FSTV0910_P2_NBITER_NF_32APSK_5_6 0xfad900ff -/*P2_NBITER_NF27*/ +/* P2_NBITER_NF27 */ #define RSTV0910_P2_NBITER_NF27 0xfada #define FSTV0910_P2_NBITER_NF_32APSK_8_9 0xfada00ff -/*P2_NBITER_NF28*/ +/* P2_NBITER_NF28 */ #define RSTV0910_P2_NBITER_NF28 0xfadb #define FSTV0910_P2_NBITER_NF_32APSK_9_10 0xfadb00ff -/*P2_NBITER_SF1*/ +/* P2_NBITER_SF1 */ #define RSTV0910_P2_NBITER_SF1 0xfadc #define FSTV0910_P2_NBITER_SF_QPSK_1_4 0xfadc00ff -/*P2_NBITER_SF2*/ +/* P2_NBITER_SF2 */ #define RSTV0910_P2_NBITER_SF2 0xfadd #define FSTV0910_P2_NBITER_SF_QPSK_1_3 0xfadd00ff -/*P2_NBITER_SF3*/ +/* P2_NBITER_SF3 */ #define RSTV0910_P2_NBITER_SF3 0xfade #define FSTV0910_P2_NBITER_SF_QPSK_2_5 0xfade00ff -/*P2_NBITER_SF4*/ +/* P2_NBITER_SF4 */ #define RSTV0910_P2_NBITER_SF4 0xfadf #define FSTV0910_P2_NBITER_SF_QPSK_1_2 0xfadf00ff -/*P2_NBITER_SF5*/ +/* P2_NBITER_SF5 */ #define RSTV0910_P2_NBITER_SF5 0xfae0 #define FSTV0910_P2_NBITER_SF_QPSK_3_5 0xfae000ff -/*P2_NBITER_SF6*/ +/* P2_NBITER_SF6 */ #define RSTV0910_P2_NBITER_SF6 0xfae1 #define FSTV0910_P2_NBITER_SF_QPSK_2_3 0xfae100ff -/*P2_NBITER_SF7*/ +/* P2_NBITER_SF7 */ #define RSTV0910_P2_NBITER_SF7 0xfae2 #define FSTV0910_P2_NBITER_SF_QPSK_3_4 0xfae200ff -/*P2_NBITER_SF8*/ +/* P2_NBITER_SF8 */ #define RSTV0910_P2_NBITER_SF8 0xfae3 #define FSTV0910_P2_NBITER_SF_QPSK_4_5 0xfae300ff -/*P2_NBITER_SF9*/ +/* P2_NBITER_SF9 */ #define RSTV0910_P2_NBITER_SF9 0xfae4 #define FSTV0910_P2_NBITER_SF_QPSK_5_6 0xfae400ff -/*P2_NBITER_SF10*/ +/* P2_NBITER_SF10 */ #define RSTV0910_P2_NBITER_SF10 0xfae5 #define FSTV0910_P2_NBITER_SF_QPSK_8_9 0xfae500ff -/*P2_NBITER_SF12*/ +/* P2_NBITER_SF12 */ #define RSTV0910_P2_NBITER_SF12 0xfae6 #define FSTV0910_P2_NBITER_SF_8PSK_3_5 0xfae600ff -/*P2_NBITER_SF13*/ +/* P2_NBITER_SF13 */ #define RSTV0910_P2_NBITER_SF13 0xfae7 #define FSTV0910_P2_NBITER_SF_8PSK_2_3 0xfae700ff -/*P2_NBITER_SF14*/ +/* P2_NBITER_SF14 */ #define RSTV0910_P2_NBITER_SF14 0xfae8 #define FSTV0910_P2_NBITER_SF_8PSK_3_4 0xfae800ff -/*P2_NBITER_SF15*/ +/* P2_NBITER_SF15 */ #define RSTV0910_P2_NBITER_SF15 0xfae9 #define FSTV0910_P2_NBITER_SF_8PSK_5_6 0xfae900ff -/*P2_NBITER_SF16*/ +/* P2_NBITER_SF16 */ #define RSTV0910_P2_NBITER_SF16 0xfaea #define FSTV0910_P2_NBITER_SF_8PSK_8_9 0xfaea00ff -/*P2_NBITER_SF18*/ +/* P2_NBITER_SF18 */ #define RSTV0910_P2_NBITER_SF18 0xfaeb #define FSTV0910_P2_NBITER_SF_16APSK_2_3 0xfaeb00ff -/*P2_NBITER_SF19*/ +/* P2_NBITER_SF19 */ #define RSTV0910_P2_NBITER_SF19 0xfaec #define FSTV0910_P2_NBITER_SF_16APSK_3_4 0xfaec00ff -/*P2_NBITER_SF20*/ +/* P2_NBITER_SF20 */ #define RSTV0910_P2_NBITER_SF20 0xfaed #define FSTV0910_P2_NBITER_SF_16APSK_4_5 0xfaed00ff -/*P2_NBITER_SF21*/ +/* P2_NBITER_SF21 */ #define RSTV0910_P2_NBITER_SF21 0xfaee #define FSTV0910_P2_NBITER_SF_16APSK_5_6 0xfaee00ff -/*P2_NBITER_SF22*/ +/* P2_NBITER_SF22 */ #define RSTV0910_P2_NBITER_SF22 0xfaef #define FSTV0910_P2_NBITER_SF_16APSK_8_9 0xfaef00ff -/*P2_NBITER_SF24*/ +/* P2_NBITER_SF24 */ #define RSTV0910_P2_NBITER_SF24 0xfaf0 #define FSTV0910_P2_NBITER_SF_32APSK_3_4 0xfaf000ff -/*P2_NBITER_SF25*/ +/* P2_NBITER_SF25 */ #define RSTV0910_P2_NBITER_SF25 0xfaf1 #define FSTV0910_P2_NBITER_SF_32APSK_4_5 0xfaf100ff -/*P2_NBITER_SF26*/ +/* P2_NBITER_SF26 */ #define RSTV0910_P2_NBITER_SF26 0xfaf2 #define FSTV0910_P2_NBITER_SF_32APSK_5_6 0xfaf200ff -/*P2_NBITER_SF27*/ +/* P2_NBITER_SF27 */ #define RSTV0910_P2_NBITER_SF27 0xfaf3 #define FSTV0910_P2_NBITER_SF_32APSK_8_9 0xfaf300ff -/*TSTRES0*/ +/* TSTRES0 */ #define RSTV0910_TSTRES0 0xff11 #define FSTV0910_FRESFEC 0xff110080 #define FSTV0910_FRESSYM1 0xff110008 #define FSTV0910_FRESSYM2 0xff110004 -/*TSTOUT*/ +/* TSTOUT */ #define RSTV0910_TSTOUT 0xff12 #define FSTV0910_TS 0xff12003e #define FSTV0910_TEST_OUT 0xff120001 -/*TSTIN*/ +/* TSTIN */ #define RSTV0910_TSTIN 0xff13 #define FSTV0910_TEST_IN 0xff130080 -/*P2_TSTDMD*/ +/* P2_TSTDMD */ #define RSTV0910_P2_TSTDMD 0xff20 #define FSTV0910_P2_CFRINIT_INVZIGZAG 0xff200008 -/*P2_TCTL1*/ +/* P2_TCTL1 */ #define RSTV0910_P2_TCTL1 0xff24 #define FSTV0910_P2_TST_IQSYMBSEL 0xff24001f -/*P2_TCTL4*/ +/* P2_TCTL4 */ #define RSTV0910_P2_TCTL4 0xff28 #define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0 -/*P2_TPKTDELIN*/ +/* P2_TPKTDELIN */ #define RSTV0910_P2_TPKTDELIN 0xff37 #define FSTV0910_P2_CFG_RSPARITYON 0xff370080 -/*P1_TSTDMD*/ +/* P1_TSTDMD */ #define RSTV0910_P1_TSTDMD 0xff40 #define FSTV0910_P1_CFRINIT_INVZIGZAG 0xff400008 -/*P1_TCTL1*/ +/* P1_TCTL1 */ #define RSTV0910_P1_TCTL1 0xff44 #define FSTV0910_P1_TST_IQSYMBSEL 0xff44001f -/*P1_TCTL4*/ +/* P1_TCTL4 */ #define RSTV0910_P1_TCTL4 0xff48 #define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0 -/*P1_TPKTDELIN*/ +/* P1_TPKTDELIN */ #define RSTV0910_P1_TPKTDELIN 0xff57 #define FSTV0910_P1_CFG_RSPARITYON 0xff570080 -/*TSTTSRS*/ +/* TSTTSRS */ #define RSTV0910_TSTTSRS 0xff6d #define FSTV0910_TSTRS_DISRS2 0xff6d0002 #define FSTV0910_TSTRS_DISRS1 0xff6d0001 -- cgit v1.2.3 From 2af07a49dd4a1c96acb0b8e90db2602a7a729ab6 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:13 -0400 Subject: media: dvb-frontends/stv6111: coding style cleanup Fix up all remainders reported by checkpatch-strict. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv6111.c | 38 ++++++++++++++++++++--------------- drivers/media/dvb-frontends/stv6111.h | 7 ++++--- 2 files changed, 26 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c index ce5b5ff936d5..91e24ba44c30 100644 --- a/drivers/media/dvb-frontends/stv6111.c +++ b/drivers/media/dvb-frontends/stv6111.c @@ -298,7 +298,7 @@ static inline u32 muldiv32(u32 a, u32 b, u32 c) tmp64 = (u64)a * (u64)b; do_div(tmp64, c); - return (u32) tmp64; + return (u32)tmp64; } static int i2c_read(struct i2c_adapter *adap, @@ -429,10 +429,10 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency) index = 6; if (index > 50) index = 50; - if ((state->reg[0x08] & ~0xFC) == ((index-6) << 2)) + if ((state->reg[0x08] & ~0xFC) == ((index - 6) << 2)) return 0; - state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index-6) << 2); + state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2); state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -542,12 +542,12 @@ static s32 table_lookup(struct slookup *table, int table_size, u16 reg_value) int i; /* Assumes Table[0].RegValue < Table[imax].RegValue */ - if (reg_value <= table[0].reg_value) + if (reg_value <= table[0].reg_value) { gain = table[0].value; - else if (reg_value >= table[imax].reg_value) + } else if (reg_value >= table[imax].reg_value) { gain = table[imax].value; - else { - while (imax-imin > 1) { + } else { + while ((imax - imin) > 1) { i = (imax + imin) / 2; if ((table[imin].reg_value <= reg_value) && (reg_value <= table[i].reg_value)) @@ -558,9 +558,9 @@ static s32 table_lookup(struct slookup *table, int table_size, u16 reg_value) reg_diff = table[imax].reg_value - table[imin].reg_value; gain = table[imin].value; if (reg_diff != 0) - gain += ((s32) (reg_value - table[imin].reg_value) * + gain += ((s32)(reg_value - table[imin].reg_value) * (s32)(table[imax].value - - table[imin].value))/(reg_diff); + - table[imin].value)) / reg_diff; } return gain; } @@ -587,27 +587,33 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 *st) if ((state->reg[0x02] & 0x80) == 0) /* NF */ gain = table_lookup(lnagain_nf_lookup, - ARRAY_SIZE(lnagain_nf_lookup), reg & 0x1F); + ARRAY_SIZE(lnagain_nf_lookup), + reg & 0x1F); else /* IIP3 */ gain = table_lookup(lnagain_iip3_lookup, - ARRAY_SIZE(lnagain_iip3_lookup), reg & 0x1F); + ARRAY_SIZE(lnagain_iip3_lookup), + reg & 0x1F); gain += table_lookup(gain_rfagc_lookup, - ARRAY_SIZE(gain_rfagc_lookup), rfagc); + ARRAY_SIZE(gain_rfagc_lookup), rfagc); + gain -= 2400; } else { /* Channel Mode */ if ((state->reg[0x02] & 0x80) == 0) { /* NF */ - gain = table_lookup(gain_channel_agc_nf_lookup, + gain = table_lookup( + gain_channel_agc_nf_lookup, ARRAY_SIZE(gain_channel_agc_nf_lookup), rfagc); + gain += 600; } else { /* IIP3 */ - gain = table_lookup(gain_channel_agc_iip3_lookup, + gain = table_lookup( + gain_channel_agc_iip3_lookup, ARRAY_SIZE(gain_channel_agc_iip3_lookup), - rfagc); + rfagc); } } @@ -647,7 +653,7 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, struct stv *state; int stat; - state = kzalloc(sizeof(struct stv), GFP_KERNEL); + state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) return NULL; state->adr = adr; diff --git a/drivers/media/dvb-frontends/stv6111.h b/drivers/media/dvb-frontends/stv6111.h index 066dd70c9426..5bc1228dc9bd 100644 --- a/drivers/media/dvb-frontends/stv6111.h +++ b/drivers/media/dvb-frontends/stv6111.h @@ -3,13 +3,14 @@ #if IS_REACHABLE(CONFIG_DVB_STV6111) -extern struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 adr); +struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 adr); #else static inline struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 adr) + struct i2c_adapter *i2c, + u8 adr) { pr_warn("%s: Driver disabled by Kconfig\n", __func__); return NULL; -- cgit v1.2.3 From 85e36b47ea8400bfa39d3c073f9cf5a192d817d1 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:14 -0400 Subject: media: dvb-frontends/stv6111: cosmetics: comments fixup, misc Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv6111.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c index 91e24ba44c30..c4db5e6c18af 100644 --- a/drivers/media/dvb-frontends/stv6111.c +++ b/drivers/media/dvb-frontends/stv6111.c @@ -42,7 +42,7 @@ struct slookup { }; static struct slookup lnagain_nf_lookup[] = { - /*Gain *100dB*/ /*Reg*/ + /* Gain *100dB // Reg */ { 2572, 0 }, { 2575, 1 }, { 2580, 2 }, @@ -78,7 +78,7 @@ static struct slookup lnagain_nf_lookup[] = { }; static struct slookup lnagain_iip3_lookup[] = { - /*Gain *100dB*/ /*reg*/ + /* Gain *100dB // reg */ { 1548, 0 }, { 1552, 1 }, { 1569, 2 }, @@ -114,7 +114,7 @@ static struct slookup lnagain_iip3_lookup[] = { }; static struct slookup gain_rfagc_lookup[] = { - /*Gain *100dB*/ /*reg*/ + /* Gain *100dB // reg */ { 4870, 0x3000 }, { 4850, 0x3C00 }, { 4800, 0x4500 }, @@ -174,7 +174,7 @@ static struct slookup gain_rfagc_lookup[] = { * a different BB_MAG setting) */ static struct slookup gain_channel_agc_nf_lookup[] = { - /*Gain *100dB*/ /*reg*/ + /* Gain *100dB // reg */ { 7082, 0x3000 }, { 7052, 0x4000 }, { 7007, 0x4600 }, @@ -233,7 +233,7 @@ static struct slookup gain_channel_agc_nf_lookup[] = { }; static struct slookup gain_channel_agc_iip3_lookup[] = { - /*Gain *100dB*/ /*reg*/ + /* Gain *100dB // reg */ { 7070, 0x3000 }, { 7028, 0x4000 }, { 7019, 0x4600 }, @@ -483,7 +483,7 @@ static int set_lof(struct stv *state, u32 local_frequency, u32 cutoff_frequency) else icp = 7; - state->reg[0x02] |= 0x80; /* LNA IIP3 Mode */ + state->reg[0x02] |= 0x80; /* LNA IIP3 Mode */ state->reg[0x03] = (state->reg[0x03] & ~0x80) | (psel << 7); state->reg[0x04] = (div & 0xFF); @@ -503,7 +503,7 @@ static int set_lof(struct stv *state, u32 local_frequency, u32 cutoff_frequency) read_reg(state, 0x03, &tmp); if (tmp & 0x10) { - state->reg[0x02] &= ~0x80; /* LNA NF Mode */ + state->reg[0x02] &= ~0x80; /* LNA NF Mode */ write_regs(state, 2, 1); } read_reg(state, 0x08, &tmp); @@ -636,15 +636,15 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 *st) static struct dvb_tuner_ops tuner_ops = { .info = { - .name = "STV6111", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0 + .name = "STV6111", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 0 }, - .set_params = set_params, - .release = release, - .get_rf_strength = get_rf_strength, - .set_bandwidth = set_bandwidth, + .set_params = set_params, + .release = release, + .get_rf_strength = get_rf_strength, + .set_bandwidth = set_bandwidth, }; struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, -- cgit v1.2.3 From 20e671dff9e40fa882574de29be9cc647737aee8 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 06:13:15 -0400 Subject: media: dvb-frontends/stv{0910,6111}: constify tables Mark lookup tables and fe_ops things const so the compiler can put them into .rodata. While at it, improve name and identifier strings (moddesc, fe_ops). Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 24 ++++++++++++------------ drivers/media/dvb-frontends/stv6111.c | 19 ++++++++++--------- 2 files changed, 22 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 08a5a3ec5391..45d94c3a29f2 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -207,7 +207,7 @@ static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val) return status; } -static struct slookup s1_sn_lookup[] = { +static const struct slookup s1_sn_lookup[] = { { 0, 9242 }, /* C/N= 0dB */ { 5, 9105 }, /* C/N= 0.5dB */ { 10, 8950 }, /* C/N= 1.0dB */ @@ -264,7 +264,7 @@ static struct slookup s1_sn_lookup[] = { { 510, 425 } /* C/N=51.0dB */ }; -static struct slookup s2_sn_lookup[] = { +static const struct slookup s2_sn_lookup[] = { { -30, 13950 }, /* C/N=-2.5dB */ { -25, 13580 }, /* C/N=-2.5dB */ { -20, 13150 }, /* C/N=-2.0dB */ @@ -327,7 +327,7 @@ static struct slookup s2_sn_lookup[] = { { 510, 463 }, /* C/N=51.0dB */ }; -static struct slookup padc_lookup[] = { +static const struct slookup padc_lookup[] = { { 0, 118000 }, /* PADC= +0dBm */ { -100, 93600 }, /* PADC= -1dBm */ { -200, 74500 }, /* PADC= -2dBm */ @@ -349,7 +349,7 @@ static struct slookup padc_lookup[] = { /********************************************************************* * Tracking carrier loop carrier QPSK 1/4 to 8PSK 9/10 long Frame *********************************************************************/ -static u8 s2car_loop[] = { +static const u8 s2car_loop[] = { /* * Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff * 20MPon 20MPoff 30MPon 30MPoff @@ -587,7 +587,7 @@ static int tracking_optimization(struct stv *state) return 0; } -static s32 table_lookup(struct slookup *table, +static s32 table_lookup(const struct slookup *table, int table_size, u32 reg_value) { s32 value; @@ -629,7 +629,7 @@ static int get_signal_to_noise(struct stv *state, s32 *signal_to_noise) u8 data1; u16 data; int n_lookup; - struct slookup *lookup; + const struct slookup *lookup; *signal_to_noise = 0; @@ -693,7 +693,7 @@ static int get_bit_error_rate_s(struct stv *state, u32 *bernumerator, static u32 dvbs2_nbch(enum dvbs2_mod_cod mod_cod, enum dvbs2_fectype fectype) { - static u32 nbch[][2] = { + static const u32 nbch[][2] = { { 0, 0}, /* DUMMY_PLF */ {16200, 3240}, /* QPSK_1_4, */ {21600, 5400}, /* QPSK_1_3, */ @@ -953,7 +953,7 @@ static int set_vth_default(struct stv *state) static int set_vth(struct stv *state) { - static struct slookup vthlookup_table[] = { + static const struct slookup vthlookup_table[] = { {250, 8780}, /* C/N= 1.5dB */ {100, 7405}, /* C/N= 4.5dB */ {40, 6330}, /* C/N= 6.5dB */ @@ -1515,7 +1515,7 @@ static int get_frontend(struct dvb_frontend *fe, if (state->receive_mode == RCVMODE_DVBS2) { u32 mc; - enum fe_modulation modcod2mod[0x20] = { + const enum fe_modulation modcod2mod[0x20] = { QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, QPSK, @@ -1525,7 +1525,7 @@ static int get_frontend(struct dvb_frontend *fe, APSK_32, APSK_32, APSK_32, APSK_32, APSK_32, }; - enum fe_code_rate modcod2fec[0x20] = { + const enum fe_code_rate modcod2fec[0x20] = { FEC_NONE, FEC_NONE, FEC_NONE, FEC_2_5, FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, @@ -1673,10 +1673,10 @@ static int sleep(struct dvb_frontend *fe) return 0; } -static struct dvb_frontend_ops stv0910_ops = { +static const struct dvb_frontend_ops stv0910_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { - .name = "STV0910", + .name = "ST STV0910", .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 0, diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c index c4db5e6c18af..9a59fa318207 100644 --- a/drivers/media/dvb-frontends/stv6111.c +++ b/drivers/media/dvb-frontends/stv6111.c @@ -41,7 +41,7 @@ struct slookup { u16 reg_value; }; -static struct slookup lnagain_nf_lookup[] = { +static const struct slookup lnagain_nf_lookup[] = { /* Gain *100dB // Reg */ { 2572, 0 }, { 2575, 1 }, @@ -77,7 +77,7 @@ static struct slookup lnagain_nf_lookup[] = { { 5102, 31 } }; -static struct slookup lnagain_iip3_lookup[] = { +static const struct slookup lnagain_iip3_lookup[] = { /* Gain *100dB // reg */ { 1548, 0 }, { 1552, 1 }, @@ -113,7 +113,7 @@ static struct slookup lnagain_iip3_lookup[] = { { 4535, 31 } }; -static struct slookup gain_rfagc_lookup[] = { +static const struct slookup gain_rfagc_lookup[] = { /* Gain *100dB // reg */ { 4870, 0x3000 }, { 4850, 0x3C00 }, @@ -173,7 +173,7 @@ static struct slookup gain_rfagc_lookup[] = { * This table is 6 dB too low comapred to the others (probably created with * a different BB_MAG setting) */ -static struct slookup gain_channel_agc_nf_lookup[] = { +static const struct slookup gain_channel_agc_nf_lookup[] = { /* Gain *100dB // reg */ { 7082, 0x3000 }, { 7052, 0x4000 }, @@ -232,7 +232,7 @@ static struct slookup gain_channel_agc_nf_lookup[] = { { 1927, 0xFF00 } }; -static struct slookup gain_channel_agc_iip3_lookup[] = { +static const struct slookup gain_channel_agc_iip3_lookup[] = { /* Gain *100dB // reg */ { 7070, 0x3000 }, { 7028, 0x4000 }, @@ -533,7 +533,8 @@ static int set_params(struct dvb_frontend *fe) return 0; } -static s32 table_lookup(struct slookup *table, int table_size, u16 reg_value) +static s32 table_lookup(const struct slookup *table, + int table_size, u16 reg_value) { s32 gain; s32 reg_diff; @@ -634,9 +635,9 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 *st) return 0; } -static struct dvb_tuner_ops tuner_ops = { +static const struct dvb_tuner_ops tuner_ops = { .info = { - .name = "STV6111", + .name = "ST STV6111", .frequency_min = 950000, .frequency_max = 2150000, .frequency_step = 0 @@ -675,6 +676,6 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, } EXPORT_SYMBOL_GPL(stv6111_attach); -MODULE_DESCRIPTION("STV6111 driver"); +MODULE_DESCRIPTION("ST STV6111 satellite tuner driver"); MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 3c4e04153f9aacfb34e8c5c884c1424e08994aaf Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 9 Jul 2017 15:42:43 -0400 Subject: media: dvb-frontends: MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver This adds the frontend driver for the MaxLinear MxL5xx family of tuner- demodulators, as used on Digital Devices MaxS4/8 four/eight-tuner cards. The driver was picked from the dddvb vendor driver package and - judging solely from the diff - has undergone a 100% rework: - Silly #define's used to pass multiple values to functions were expanded. This resulted in macro/register names not being usable anymore for such occurences, but makes the code WAY more read-, understand- and maintainable. - CamelCase was changed to kernel_case - All typedef were removed - Overall code style was fixed, besides >80char lines in _defs.h and _regs.h, checkpatch is happy. - Also, signal stat acquisition was made to comply with the DVB API ways to do these things. Permission to reuse and mainline the driver code was formally granted by Ralph Metzler . Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 9 + drivers/media/dvb-frontends/Makefile | 1 + drivers/media/dvb-frontends/mxl5xx.c | 1873 +++++++++++++++++++++++++++++ drivers/media/dvb-frontends/mxl5xx.h | 41 + drivers/media/dvb-frontends/mxl5xx_defs.h | 731 +++++++++++ drivers/media/dvb-frontends/mxl5xx_regs.h | 367 ++++++ 6 files changed, 3022 insertions(+) create mode 100644 drivers/media/dvb-frontends/mxl5xx.c create mode 100644 drivers/media/dvb-frontends/mxl5xx.h create mode 100644 drivers/media/dvb-frontends/mxl5xx_defs.h create mode 100644 drivers/media/dvb-frontends/mxl5xx_regs.h (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index d2d3160abdf7..2631d0e0a024 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -53,6 +53,15 @@ config DVB_STV6111 Say Y when you want to support these frontends. +config DVB_MXL5XX + tristate "MaxLinear MxL5xx based tuner-demodulators" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + MaxLinear MxL5xx family of DVB-S/S2 tuners/demodulators. + + Say Y when you want to support these frontends. + config DVB_M88DS3103 tristate "Montage Technology M88DS3103" depends on DVB_CORE && I2C && I2C_MUX diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index e8bf1d873485..f45f6a4a4371 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -112,6 +112,7 @@ obj-$(CONFIG_DVB_DRXK) += drxk.o obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o obj-$(CONFIG_DVB_STV0910) += stv0910.o obj-$(CONFIG_DVB_STV6111) += stv6111.o +obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o obj-$(CONFIG_DVB_SI2165) += si2165.o obj-$(CONFIG_DVB_A8293) += a8293.o obj-$(CONFIG_DVB_SP2) += sp2.o diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c new file mode 100644 index 000000000000..676c96c216c3 --- /dev/null +++ b/drivers/media/dvb-frontends/mxl5xx.c @@ -0,0 +1,1873 @@ +/* + * Driver for the MaxLinear MxL5xx family of tuners/demods + * + * Copyright (C) 2014-2015 Ralph Metzler + * Marcus Metzler + * developed for Digital Devices GmbH + * + * based on code: + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved + * which was released under GPL V2 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "mxl5xx.h" +#include "mxl5xx_regs.h" +#include "mxl5xx_defs.h" + +#define BYTE0(v) ((v >> 0) & 0xff) +#define BYTE1(v) ((v >> 8) & 0xff) +#define BYTE2(v) ((v >> 16) & 0xff) +#define BYTE3(v) ((v >> 24) & 0xff) + +LIST_HEAD(mxllist); + +struct mxl_base { + struct list_head mxllist; + struct list_head mxls; + + u8 adr; + struct i2c_adapter *i2c; + + u32 count; + u32 type; + u32 sku_type; + u32 chipversion; + u32 clock; + u32 fwversion; + + u8 *ts_map; + u8 can_clkout; + u8 chan_bond; + u8 demod_num; + u8 tuner_num; + + unsigned long next_tune; + + struct mutex i2c_lock; + struct mutex status_lock; + struct mutex tune_lock; + + u8 buf[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; + + u32 cmd_size; + u8 cmd_data[MAX_CMD_DATA]; +}; + +struct mxl { + struct list_head mxl; + + struct mxl_base *base; + struct dvb_frontend fe; + struct device *i2cdev; + u32 demod; + u32 tuner; + u32 tuner_in_use; + u8 xbar[3]; + + unsigned long tune_time; +}; + +static void convert_endian(u8 flag, u32 size, u8 *d) +{ + u32 i; + + if (!flag) + return; + for (i = 0; i < (size & ~3); i += 4) { + d[i + 0] ^= d[i + 3]; + d[i + 3] ^= d[i + 0]; + d[i + 0] ^= d[i + 3]; + + d[i + 1] ^= d[i + 2]; + d[i + 2] ^= d[i + 1]; + d[i + 1] ^= d[i + 2]; + } + + switch (size & 3) { + case 0: + case 1: + /* do nothing */ + break; + case 2: + d[i + 0] ^= d[i + 1]; + d[i + 1] ^= d[i + 0]; + d[i + 0] ^= d[i + 1]; + break; + + case 3: + d[i + 0] ^= d[i + 2]; + d[i + 2] ^= d[i + 0]; + d[i + 0] ^= d[i + 2]; + break; + } + +} + +static int i2c_write(struct i2c_adapter *adap, u8 adr, + u8 *data, u32 len) +{ + struct i2c_msg msg = {.addr = adr, .flags = 0, + .buf = data, .len = len}; + + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; +} + +static int i2c_read(struct i2c_adapter *adap, u8 adr, + u8 *data, u32 len) +{ + struct i2c_msg msg = {.addr = adr, .flags = I2C_M_RD, + .buf = data, .len = len}; + + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; +} + +static int i2cread(struct mxl *state, u8 *data, int len) +{ + return i2c_read(state->base->i2c, state->base->adr, data, len); +} + +static int i2cwrite(struct mxl *state, u8 *data, int len) +{ + return i2c_write(state->base->i2c, state->base->adr, data, len); +} + +static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val) +{ + int stat; + u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = { + MXL_HYDRA_PLID_REG_READ, 0x04, + GET_BYTE(reg, 0), GET_BYTE(reg, 1), + GET_BYTE(reg, 2), GET_BYTE(reg, 3), + }; + + stat = i2cwrite(state, data, + MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE); + if (stat) + dev_err(state->i2cdev, "i2c read error 1\n"); + if (!stat) + stat = i2cread(state, (u8 *) val, + MXL_HYDRA_REG_SIZE_IN_BYTES); + le32_to_cpus(val); + if (stat) + dev_err(state->i2cdev, "i2c read error 2\n"); + return stat; +} + +#define DMA_I2C_INTERRUPT_ADDR 0x8000011C +#define DMA_INTR_PROT_WR_CMP 0x08 + +static int send_command(struct mxl *state, u32 size, u8 *buf) +{ + int stat; + u32 val, count = 10; + + mutex_lock(&state->base->i2c_lock); + if (state->base->fwversion > 0x02010109) { + read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val); + if (DMA_INTR_PROT_WR_CMP & val) + dev_info(state->i2cdev, "%s busy\n", __func__); + while ((DMA_INTR_PROT_WR_CMP & val) && --count) { + mutex_unlock(&state->base->i2c_lock); + usleep_range(1000, 2000); + mutex_lock(&state->base->i2c_lock); + read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, + &val); + } + if (!count) { + dev_info(state->i2cdev, "%s busy\n", __func__); + mutex_unlock(&state->base->i2c_lock); + return -EBUSY; + } + } + stat = i2cwrite(state, buf, size); + mutex_unlock(&state->base->i2c_lock); + return stat; +} + +static int write_register(struct mxl *state, u32 reg, u32 val) +{ + int stat; + u8 data[MXL_HYDRA_REG_WRITE_LEN] = { + MXL_HYDRA_PLID_REG_WRITE, 0x08, + BYTE0(reg), BYTE1(reg), BYTE2(reg), BYTE3(reg), + BYTE0(val), BYTE1(val), BYTE2(val), BYTE3(val), + }; + mutex_lock(&state->base->i2c_lock); + stat = i2cwrite(state, data, sizeof(data)); + mutex_unlock(&state->base->i2c_lock); + if (stat) + dev_err(state->i2cdev, "i2c write error\n"); + return stat; +} + +static int write_firmware_block(struct mxl *state, + u32 reg, u32 size, u8 *reg_data_ptr) +{ + int stat; + u8 *buf = state->base->buf; + + mutex_lock(&state->base->i2c_lock); + buf[0] = MXL_HYDRA_PLID_REG_WRITE; + buf[1] = size + 4; + buf[2] = GET_BYTE(reg, 0); + buf[3] = GET_BYTE(reg, 1); + buf[4] = GET_BYTE(reg, 2); + buf[5] = GET_BYTE(reg, 3); + memcpy(&buf[6], reg_data_ptr, size); + stat = i2cwrite(state, buf, + MXL_HYDRA_I2C_HDR_SIZE + + MXL_HYDRA_REG_SIZE_IN_BYTES + size); + mutex_unlock(&state->base->i2c_lock); + if (stat) + dev_err(state->i2cdev, "fw block write failed\n"); + return stat; +} + +static int read_register(struct mxl *state, u32 reg, u32 *val) +{ + int stat; + u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = { + MXL_HYDRA_PLID_REG_READ, 0x04, + GET_BYTE(reg, 0), GET_BYTE(reg, 1), + GET_BYTE(reg, 2), GET_BYTE(reg, 3), + }; + + mutex_lock(&state->base->i2c_lock); + stat = i2cwrite(state, data, + MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE); + if (stat) + dev_err(state->i2cdev, "i2c read error 1\n"); + if (!stat) + stat = i2cread(state, (u8 *) val, + MXL_HYDRA_REG_SIZE_IN_BYTES); + mutex_unlock(&state->base->i2c_lock); + le32_to_cpus(val); + if (stat) + dev_err(state->i2cdev, "i2c read error 2\n"); + return stat; +} + +static int read_register_block(struct mxl *state, u32 reg, u32 size, u8 *data) +{ + int stat; + u8 *buf = state->base->buf; + + mutex_lock(&state->base->i2c_lock); + + buf[0] = MXL_HYDRA_PLID_REG_READ; + buf[1] = size + 4; + buf[2] = GET_BYTE(reg, 0); + buf[3] = GET_BYTE(reg, 1); + buf[4] = GET_BYTE(reg, 2); + buf[5] = GET_BYTE(reg, 3); + stat = i2cwrite(state, buf, + MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES); + if (!stat) { + stat = i2cread(state, data, size); + convert_endian(MXL_ENABLE_BIG_ENDIAN, size, data); + } + mutex_unlock(&state->base->i2c_lock); + return stat; +} + +static int read_by_mnemonic(struct mxl *state, + u32 reg, u8 lsbloc, u8 numofbits, u32 *val) +{ + u32 data = 0, mask = 0; + int stat; + + stat = read_register(state, reg, &data); + if (stat) + return stat; + mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); + data &= mask; + data >>= lsbloc; + *val = data; + return 0; +} + + +static int update_by_mnemonic(struct mxl *state, + u32 reg, u8 lsbloc, u8 numofbits, u32 val) +{ + u32 data, mask; + int stat; + + stat = read_register(state, reg, &data); + if (stat) + return stat; + mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); + data = (data & ~mask) | ((val << lsbloc) & mask); + stat = write_register(state, reg, data); + return stat; +} + +static int firmware_is_alive(struct mxl *state) +{ + u32 hb0, hb1; + + if (read_register(state, HYDRA_HEAR_BEAT, &hb0)) + return 0; + msleep(20); + if (read_register(state, HYDRA_HEAR_BEAT, &hb1)) + return 0; + if (hb1 == hb0) + return 0; + return 1; +} + +static int init(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + /* init fe stats */ + p->strength.len = 1; + p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->cnr.len = 1; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_error.len = 1; + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.len = 1; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_error.len = 1; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_count.len = 1; + p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + return 0; +} + +static void release(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + + list_del(&state->mxl); + /* Release one frontend, two more shall take its place! */ + state->base->count--; + if (state->base->count == 0) { + list_del(&state->base->mxllist); + kfree(state->base); + } + kfree(state); +} + +static int get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_HW; +} + +static int cfg_demod_abort_tune(struct mxl *state) +{ + struct MXL_HYDRA_DEMOD_ABORT_TUNE_T abort_tune_cmd; + u8 cmd_size = sizeof(abort_tune_cmd); + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; + + abort_tune_cmd.demod_id = state->demod; + BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, + cmd_size, &abort_tune_cmd, cmd_buff); + return send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, + &cmd_buff[0]); +} + +static int send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + /*struct mxl *state = fe->demodulator_priv;*/ + + return 0; /*CfgDemodAbortTune(state);*/ +} + +static int set_parameters(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + struct MXL_HYDRA_DEMOD_PARAM_T demod_chan_cfg; + u8 cmd_size = sizeof(demod_chan_cfg); + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; + u32 srange = 10; + int stat; + + if (p->frequency < 950000 || p->frequency > 2150000) + return -EINVAL; + if (p->symbol_rate < 1000000 || p->symbol_rate > 45000000) + return -EINVAL; + + /* CfgDemodAbortTune(state); */ + + switch (p->delivery_system) { + case SYS_DSS: + demod_chan_cfg.standard = MXL_HYDRA_DSS; + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; + break; + case SYS_DVBS: + srange = p->symbol_rate / 1000000; + if (srange > 10) + srange = 10; + demod_chan_cfg.standard = MXL_HYDRA_DVBS; + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_0_35; + demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_QPSK; + demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_OFF; + break; + case SYS_DVBS2: + demod_chan_cfg.standard = MXL_HYDRA_DVBS2; + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; + demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_AUTO; + demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_AUTO; + /* cfg_scrambler(state); */ + break; + default: + return -EINVAL; + } + demod_chan_cfg.tuner_index = state->tuner; + demod_chan_cfg.demod_index = state->demod; + demod_chan_cfg.frequency_in_hz = p->frequency * 1000; + demod_chan_cfg.symbol_rate_in_hz = p->symbol_rate; + demod_chan_cfg.max_carrier_offset_in_mhz = srange; + demod_chan_cfg.spectrum_inversion = MXL_HYDRA_SPECTRUM_AUTO; + demod_chan_cfg.fec_code_rate = MXL_HYDRA_FEC_AUTO; + + mutex_lock(&state->base->tune_lock); + if (time_after(jiffies + msecs_to_jiffies(200), + state->base->next_tune)) + while (time_before(jiffies, state->base->next_tune)) + usleep_range(10000, 11000); + state->base->next_tune = jiffies + msecs_to_jiffies(100); + state->tuner_in_use = state->tuner; + BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE, + cmd_size, &demod_chan_cfg, cmd_buff); + stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, + &cmd_buff[0]); + mutex_unlock(&state->base->tune_lock); + return stat; +} + +static int enable_tuner(struct mxl *state, u32 tuner, u32 enable); + +static int sleep(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + struct mxl *p; + + cfg_demod_abort_tune(state); + if (state->tuner_in_use != 0xffffffff) { + mutex_lock(&state->base->tune_lock); + state->tuner_in_use = 0xffffffff; + list_for_each_entry(p, &state->base->mxls, mxl) { + if (p->tuner_in_use == state->tuner) + break; + } + if (&p->mxl == &state->base->mxls) + enable_tuner(state, state->tuner, 0); + mutex_unlock(&state->base->tune_lock); + } + return 0; +} + +static int read_snr(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + int stat; + u32 reg_data = 0; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + mutex_lock(&state->base->status_lock); + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); + stat = read_register(state, (HYDRA_DMD_SNR_ADDR_OFFSET + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + ®_data); + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); + mutex_unlock(&state->base->status_lock); + + p->cnr.stat[0].scale = FE_SCALE_DECIBEL; + p->cnr.stat[0].svalue = (s16)reg_data * 10; + + return stat; +} + +static int read_ber(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 reg[8]; + + mutex_lock(&state->base->status_lock); + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); + read_register_block(state, + (HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + (4 * sizeof(u32)), + (u8 *) ®[0]); + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); + + switch (p->delivery_system) { + case SYS_DSS: + case SYS_DVBS: + p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_error.stat[0].uvalue = reg[2]; + p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_count.stat[0].uvalue = reg[3]; + break; + default: + break; + } + + read_register_block(state, + (HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + (7 * sizeof(u32)), + (u8 *) ®[0]); + + switch (p->delivery_system) { + case SYS_DSS: + case SYS_DVBS: + p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + p->post_bit_error.stat[0].uvalue = reg[5]; + p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + p->post_bit_count.stat[0].uvalue = reg[6]; + break; + case SYS_DVBS2: + p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + p->post_bit_error.stat[0].uvalue = reg[1]; + p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + p->post_bit_count.stat[0].uvalue = reg[2]; + break; + default: + break; + } + + mutex_unlock(&state->base->status_lock); + + return 0; +} + +static int read_signal_strength(struct dvb_frontend *fe) +{ + struct mxl *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + int stat; + u32 reg_data = 0; + + mutex_lock(&state->base->status_lock); + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); + stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + ®_data); + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); + mutex_unlock(&state->base->status_lock); + + p->strength.stat[0].scale = FE_SCALE_DECIBEL; + p->strength.stat[0].svalue = (s16) reg_data * 10; /* fix scale */ + + return stat; +} + +static int read_status(struct dvb_frontend *fe, enum fe_status *status) +{ + struct mxl *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 reg_data = 0; + + mutex_lock(&state->base->status_lock); + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); + read_register(state, (HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + ®_data); + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); + mutex_unlock(&state->base->status_lock); + + *status = (reg_data == 1) ? 0x1f : 0; + + /* signal statistics */ + + /* signal strength is always available */ + read_signal_strength(fe); + + if (*status & FE_HAS_CARRIER) + read_snr(fe); + else + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + if (*status & FE_HAS_SYNC) + read_ber(fe); + else { + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + + return 0; +} + +static int tune(struct dvb_frontend *fe, bool re_tune, + unsigned int mode_flags, + unsigned int *delay, enum fe_status *status) +{ + struct mxl *state = fe->demodulator_priv; + int r = 0; + + *delay = HZ / 2; + if (re_tune) { + r = set_parameters(fe); + if (r) + return r; + state->tune_time = jiffies; + return 0; + } + if (*status & FE_HAS_LOCK) + return 0; + + r = read_status(fe, status); + if (r) + return r; + + return 0; +} + +static enum fe_code_rate conv_fec(enum MXL_HYDRA_FEC_E fec) +{ + enum fe_code_rate fec2fec[11] = { + FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3, + FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, + FEC_7_8, FEC_8_9, FEC_9_10 + }; + + if (fec > MXL_HYDRA_FEC_9_10) + return FEC_NONE; + return fec2fec[fec]; +} + +static int get_frontend(struct dvb_frontend *fe, + struct dtv_frontend_properties *p) +{ + struct mxl *state = fe->demodulator_priv; + u32 reg_data[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE]; + u32 freq; + + mutex_lock(&state->base->status_lock); + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); + read_register_block(state, + (HYDRA_DMD_STANDARD_ADDR_OFFSET + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + (MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), /* 25 * 4 bytes */ + (u8 *) ®_data[0]); + /* read demod channel parameters */ + read_register_block(state, + (HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR + + HYDRA_DMD_STATUS_OFFSET(state->demod)), + (4), /* 4 bytes */ + (u8 *) &freq); + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); + mutex_unlock(&state->base->status_lock); + + dev_dbg(state->i2cdev, "freq=%u delsys=%u srate=%u\n", + freq * 1000, reg_data[DMD_STANDARD_ADDR], + reg_data[DMD_SYMBOL_RATE_ADDR]); + p->symbol_rate = reg_data[DMD_SYMBOL_RATE_ADDR]; + p->frequency = freq; + /* + * p->delivery_system = + * (MXL_HYDRA_BCAST_STD_E) regData[DMD_STANDARD_ADDR]; + * p->inversion = + * (MXL_HYDRA_SPECTRUM_E) regData[DMD_SPECTRUM_INVERSION_ADDR]; + * freqSearchRangeKHz = + * (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]); + */ + + p->fec_inner = conv_fec(reg_data[DMD_FEC_CODE_RATE_ADDR]); + switch (p->delivery_system) { + case SYS_DSS: + break; + case SYS_DVBS2: + switch ((enum MXL_HYDRA_PILOTS_E) + reg_data[DMD_DVBS2_PILOT_ON_OFF_ADDR]) { + case MXL_HYDRA_PILOTS_OFF: + p->pilot = PILOT_OFF; + break; + case MXL_HYDRA_PILOTS_ON: + p->pilot = PILOT_ON; + break; + default: + break; + } + case SYS_DVBS: + switch ((enum MXL_HYDRA_MODULATION_E) + reg_data[DMD_MODULATION_SCHEME_ADDR]) { + case MXL_HYDRA_MOD_QPSK: + p->modulation = QPSK; + break; + case MXL_HYDRA_MOD_8PSK: + p->modulation = PSK_8; + break; + default: + break; + } + switch ((enum MXL_HYDRA_ROLLOFF_E) + reg_data[DMD_SPECTRUM_ROLL_OFF_ADDR]) { + case MXL_HYDRA_ROLLOFF_0_20: + p->rolloff = ROLLOFF_20; + break; + case MXL_HYDRA_ROLLOFF_0_35: + p->rolloff = ROLLOFF_35; + break; + case MXL_HYDRA_ROLLOFF_0_25: + p->rolloff = ROLLOFF_25; + break; + default: + break; + } + break; + default: + return -EINVAL; + } + return 0; +} + +static int set_input(struct dvb_frontend *fe, int input) +{ + struct mxl *state = fe->demodulator_priv; + + state->tuner = input; + return 0; +} + +static struct dvb_frontend_ops mxl_ops = { + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, + .info = { + .name = "MaxLinear MxL5xx DVB-S/S2 tuner-demodulator", + .frequency_min = 300000, + .frequency_max = 2350000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_2G_MODULATION + }, + .init = init, + .release = release, + .get_frontend_algo = get_algo, + .tune = tune, + .read_status = read_status, + .sleep = sleep, + .get_frontend = get_frontend, + .diseqc_send_master_cmd = send_master_cmd, +}; + +static struct mxl_base *match_base(struct i2c_adapter *i2c, u8 adr) +{ + struct mxl_base *p; + + list_for_each_entry(p, &mxllist, mxllist) + if (p->i2c == i2c && p->adr == adr) + return p; + return NULL; +} + +static void cfg_dev_xtal(struct mxl *state, u32 freq, u32 cap, u32 enable) +{ + if (state->base->can_clkout || !enable) + update_by_mnemonic(state, 0x90200054, 23, 1, enable); + + if (freq == 24000000) + write_register(state, HYDRA_CRYSTAL_SETTING, 0); + else + write_register(state, HYDRA_CRYSTAL_SETTING, 1); + + write_register(state, HYDRA_CRYSTAL_CAP, cap); +} + +static u32 get_big_endian(u8 num_of_bits, const u8 buf[]) +{ + u32 ret_value = 0; + + switch (num_of_bits) { + case 24: + ret_value = (((u32) buf[0]) << 16) | + (((u32) buf[1]) << 8) | buf[2]; + break; + case 32: + ret_value = (((u32) buf[0]) << 24) | + (((u32) buf[1]) << 16) | + (((u32) buf[2]) << 8) | buf[3]; + break; + default: + break; + } + + return ret_value; +} + +static int write_fw_segment(struct mxl *state, + u32 mem_addr, u32 total_size, u8 *data_ptr) +{ + int status; + u32 data_count = 0; + u32 size = 0; + u32 orig_size = 0; + u8 *w_buf_ptr = NULL; + u32 block_size = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - + (MXL_HYDRA_I2C_HDR_SIZE + + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4; + u8 w_msg_buffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - + (MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)]; + + do { + size = orig_size = (((u32)(data_count + block_size)) > total_size) ? + (total_size - data_count) : block_size; + + if (orig_size & 3) + size = (orig_size + 4) & ~3; + w_buf_ptr = &w_msg_buffer[0]; + memset((void *) w_buf_ptr, 0, size); + memcpy((void *) w_buf_ptr, (void *) data_ptr, orig_size); + convert_endian(1, size, w_buf_ptr); + status = write_firmware_block(state, mem_addr, size, w_buf_ptr); + if (status) + return status; + data_count += size; + mem_addr += size; + data_ptr += size; + } while (data_count < total_size); + + return status; +} + +static int do_firmware_download(struct mxl *state, u8 *mbin_buffer_ptr, + u32 mbin_buffer_size) + +{ + int status; + u32 index = 0; + u32 seg_length = 0; + u32 seg_address = 0; + struct MBIN_FILE_T *mbin_ptr = (struct MBIN_FILE_T *)mbin_buffer_ptr; + struct MBIN_SEGMENT_T *segment_ptr; + enum MXL_BOOL_E xcpu_fw_flag = MXL_FALSE; + + if (mbin_ptr->header.id != MBIN_FILE_HEADER_ID) { + dev_err(state->i2cdev, "%s: Invalid file header ID (%c)\n", + __func__, mbin_ptr->header.id); + return -EINVAL; + } + status = write_register(state, FW_DL_SIGN_ADDR, 0); + if (status) + return status; + segment_ptr = (struct MBIN_SEGMENT_T *) (&mbin_ptr->data[0]); + for (index = 0; index < mbin_ptr->header.num_segments; index++) { + if (segment_ptr->header.id != MBIN_SEGMENT_HEADER_ID) { + dev_err(state->i2cdev, "%s: Invalid segment header ID (%c)\n", + __func__, segment_ptr->header.id); + return -EINVAL; + } + seg_length = get_big_endian(24, + &(segment_ptr->header.len24[0])); + seg_address = get_big_endian(32, + &(segment_ptr->header.address[0])); + + if (state->base->type == MXL_HYDRA_DEVICE_568) { + if ((((seg_address & 0x90760000) == 0x90760000) || + ((seg_address & 0x90740000) == 0x90740000)) && + (xcpu_fw_flag == MXL_FALSE)) { + update_by_mnemonic(state, 0x8003003C, 0, 1, 1); + msleep(200); + write_register(state, 0x90720000, 0); + usleep_range(10000, 11000); + xcpu_fw_flag = MXL_TRUE; + } + status = write_fw_segment(state, seg_address, + seg_length, + (u8 *) segment_ptr->data); + } else { + if (((seg_address & 0x90760000) != 0x90760000) && + ((seg_address & 0x90740000) != 0x90740000)) + status = write_fw_segment(state, seg_address, + seg_length, (u8 *) segment_ptr->data); + } + if (status) + return status; + segment_ptr = (struct MBIN_SEGMENT_T *) + &(segment_ptr->data[((seg_length + 3) / 4) * 4]); + } + return status; +} + +static int check_fw(struct mxl *state, u8 *mbin, u32 mbin_len) +{ + struct MBIN_FILE_HEADER_T *fh = (struct MBIN_FILE_HEADER_T *) mbin; + u32 flen = (fh->image_size24[0] << 16) | + (fh->image_size24[1] << 8) | fh->image_size24[2]; + u8 *fw, cs = 0; + u32 i; + + if (fh->id != 'M' || fh->fmt_version != '1' || flen > 0x3FFF0) { + dev_info(state->i2cdev, "Invalid FW Header\n"); + return -1; + } + fw = mbin + sizeof(struct MBIN_FILE_HEADER_T); + for (i = 0; i < flen; i += 1) + cs += fw[i]; + if (cs != fh->image_checksum) { + dev_info(state->i2cdev, "Invalid FW Checksum\n"); + return -1; + } + return 0; +} + +static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len) +{ + int status; + u32 reg_data = 0; + struct MXL_HYDRA_SKU_COMMAND_T dev_sku_cfg; + u8 cmd_size = sizeof(struct MXL_HYDRA_SKU_COMMAND_T); + u8 cmd_buff[sizeof(struct MXL_HYDRA_SKU_COMMAND_T) + 6]; + + if (check_fw(state, mbin, mbin_len)) + return -1; + + /* put CPU into reset */ + status = update_by_mnemonic(state, 0x8003003C, 0, 1, 0); + if (status) + return status; + usleep_range(1000, 2000); + + /* Reset TX FIFO's, BBAND, XBAR */ + status = write_register(state, HYDRA_RESET_TRANSPORT_FIFO_REG, + HYDRA_RESET_TRANSPORT_FIFO_DATA); + if (status) + return status; + status = write_register(state, HYDRA_RESET_BBAND_REG, + HYDRA_RESET_BBAND_DATA); + if (status) + return status; + status = write_register(state, HYDRA_RESET_XBAR_REG, + HYDRA_RESET_XBAR_DATA); + if (status) + return status; + + /* Disable clock to Baseband, Wideband, SerDes, + * Alias ext & Transport modules + */ + status = write_register(state, HYDRA_MODULES_CLK_2_REG, + HYDRA_DISABLE_CLK_2); + if (status) + return status; + /* Clear Software & Host interrupt status - (Clear on read) */ + status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®_data); + if (status) + return status; + status = do_firmware_download(state, mbin, mbin_len); + if (status) + return status; + + if (state->base->type == MXL_HYDRA_DEVICE_568) { + usleep_range(10000, 11000); + + /* bring XCPU out of reset */ + status = write_register(state, 0x90720000, 1); + if (status) + return status; + msleep(500); + + /* Enable XCPU UART message processing in MCPU */ + status = write_register(state, 0x9076B510, 1); + if (status) + return status; + } else { + /* Bring CPU out of reset */ + status = update_by_mnemonic(state, 0x8003003C, 0, 1, 1); + if (status) + return status; + /* Wait until FW boots */ + msleep(150); + } + + /* Initialize XPT XBAR */ + status = write_register(state, XPT_DMD0_BASEADDR, 0x76543210); + if (status) + return status; + + if (!firmware_is_alive(state)) + return -1; + + dev_info(state->i2cdev, "Hydra FW alive. Hail!\n"); + + /* sometimes register values are wrong shortly + * after first heart beats + */ + msleep(50); + + dev_sku_cfg.sku_type = state->base->sku_type; + BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE, + cmd_size, &dev_sku_cfg, cmd_buff); + status = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, + &cmd_buff[0]); + + return status; +} + +static int cfg_ts_pad_mux(struct mxl *state, enum MXL_BOOL_E enable_serial_ts) +{ + int status = 0; + u32 pad_mux_value = 0; + + if (enable_serial_ts == MXL_TRUE) { + pad_mux_value = 0; + if ((state->base->type == MXL_HYDRA_DEVICE_541) || + (state->base->type == MXL_HYDRA_DEVICE_541S)) + pad_mux_value = 2; + } else { + if ((state->base->type == MXL_HYDRA_DEVICE_581) || + (state->base->type == MXL_HYDRA_DEVICE_581S)) + pad_mux_value = 2; + else + pad_mux_value = 3; + } + + switch (state->base->type) { + case MXL_HYDRA_DEVICE_561: + case MXL_HYDRA_DEVICE_581: + case MXL_HYDRA_DEVICE_541: + case MXL_HYDRA_DEVICE_541S: + case MXL_HYDRA_DEVICE_561S: + case MXL_HYDRA_DEVICE_581S: + status |= update_by_mnemonic(state, 0x90000170, 24, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000170, 28, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 0, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 4, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 8, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 12, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 16, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 20, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 24, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000174, 28, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000178, 0, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000178, 4, 3, + pad_mux_value); + status |= update_by_mnemonic(state, 0x90000178, 8, 3, + pad_mux_value); + break; + + case MXL_HYDRA_DEVICE_544: + case MXL_HYDRA_DEVICE_542: + status |= update_by_mnemonic(state, 0x9000016C, 4, 3, 1); + status |= update_by_mnemonic(state, 0x9000016C, 8, 3, 0); + status |= update_by_mnemonic(state, 0x9000016C, 12, 3, 0); + status |= update_by_mnemonic(state, 0x9000016C, 16, 3, 0); + status |= update_by_mnemonic(state, 0x90000170, 0, 3, 0); + status |= update_by_mnemonic(state, 0x90000178, 12, 3, 1); + status |= update_by_mnemonic(state, 0x90000178, 16, 3, 1); + status |= update_by_mnemonic(state, 0x90000178, 20, 3, 1); + status |= update_by_mnemonic(state, 0x90000178, 24, 3, 1); + status |= update_by_mnemonic(state, 0x9000017C, 0, 3, 1); + status |= update_by_mnemonic(state, 0x9000017C, 4, 3, 1); + if (enable_serial_ts == MXL_ENABLE) { + status |= update_by_mnemonic(state, + 0x90000170, 4, 3, 0); + status |= update_by_mnemonic(state, + 0x90000170, 8, 3, 0); + status |= update_by_mnemonic(state, + 0x90000170, 12, 3, 0); + status |= update_by_mnemonic(state, + 0x90000170, 16, 3, 0); + status |= update_by_mnemonic(state, + 0x90000170, 20, 3, 1); + status |= update_by_mnemonic(state, + 0x90000170, 24, 3, 1); + status |= update_by_mnemonic(state, + 0x90000170, 28, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 0, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 4, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 8, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 12, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 16, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 20, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 24, 3, 2); + status |= update_by_mnemonic(state, + 0x90000174, 28, 3, 2); + status |= update_by_mnemonic(state, + 0x90000178, 0, 3, 2); + status |= update_by_mnemonic(state, + 0x90000178, 4, 3, 2); + status |= update_by_mnemonic(state, + 0x90000178, 8, 3, 2); + } else { + status |= update_by_mnemonic(state, + 0x90000170, 4, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 8, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 12, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 16, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 20, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 24, 3, 3); + status |= update_by_mnemonic(state, + 0x90000170, 28, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 0, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 4, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 8, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 12, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 16, 3, 3); + status |= update_by_mnemonic(state, + 0x90000174, 20, 3, 1); + status |= update_by_mnemonic(state, + 0x90000174, 24, 3, 1); + status |= update_by_mnemonic(state, + 0x90000174, 28, 3, 1); + status |= update_by_mnemonic(state, + 0x90000178, 0, 3, 1); + status |= update_by_mnemonic(state, + 0x90000178, 4, 3, 1); + status |= update_by_mnemonic(state, + 0x90000178, 8, 3, 1); + } + break; + + case MXL_HYDRA_DEVICE_568: + if (enable_serial_ts == MXL_FALSE) { + status |= update_by_mnemonic(state, + 0x9000016C, 8, 3, 5); + status |= update_by_mnemonic(state, + 0x9000016C, 12, 3, 5); + status |= update_by_mnemonic(state, + 0x9000016C, 16, 3, 5); + status |= update_by_mnemonic(state, + 0x9000016C, 20, 3, 5); + status |= update_by_mnemonic(state, + 0x9000016C, 24, 3, 5); + status |= update_by_mnemonic(state, + 0x9000016C, 28, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 0, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 4, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 8, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 12, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 16, 3, 5); + status |= update_by_mnemonic(state, + 0x90000170, 20, 3, 5); + + status |= update_by_mnemonic(state, + 0x90000170, 24, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 0, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 4, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 8, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 12, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 16, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 20, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 24, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 28, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000178, 0, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000178, 4, 3, pad_mux_value); + + status |= update_by_mnemonic(state, + 0x90000178, 8, 3, 5); + status |= update_by_mnemonic(state, + 0x90000178, 12, 3, 5); + status |= update_by_mnemonic(state, + 0x90000178, 16, 3, 5); + status |= update_by_mnemonic(state, + 0x90000178, 20, 3, 5); + status |= update_by_mnemonic(state, + 0x90000178, 24, 3, 5); + status |= update_by_mnemonic(state, + 0x90000178, 28, 3, 5); + status |= update_by_mnemonic(state, + 0x9000017C, 0, 3, 5); + status |= update_by_mnemonic(state, + 0x9000017C, 4, 3, 5); + } else { + status |= update_by_mnemonic(state, + 0x90000170, 4, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 8, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 12, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 16, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 20, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 24, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 28, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 0, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 4, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 8, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 12, 3, pad_mux_value); + } + break; + + + case MXL_HYDRA_DEVICE_584: + default: + status |= update_by_mnemonic(state, + 0x90000170, 4, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 8, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 12, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 16, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 20, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 24, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000170, 28, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 0, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 4, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 8, 3, pad_mux_value); + status |= update_by_mnemonic(state, + 0x90000174, 12, 3, pad_mux_value); + break; + } + return status; +} + +static int set_drive_strength(struct mxl *state, + enum MXL_HYDRA_TS_DRIVE_STRENGTH_E ts_drive_strength) +{ + int stat = 0; + u32 val; + + read_register(state, 0x90000194, &val); + dev_info(state->i2cdev, "DIGIO = %08x\n", val); + dev_info(state->i2cdev, "set drive_strength = %u\n", ts_drive_strength); + + + stat |= update_by_mnemonic(state, 0x90000194, 0, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000194, 20, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000194, 24, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000198, 12, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000198, 16, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000198, 20, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x90000198, 24, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x9000019C, 0, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x9000019C, 4, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x9000019C, 8, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x9000019C, 24, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x9000019C, 28, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x900001A0, 0, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x900001A0, 4, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x900001A0, 20, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x900001A0, 24, 3, ts_drive_strength); + stat |= update_by_mnemonic(state, 0x900001A0, 28, 3, ts_drive_strength); + + return stat; +} + +static int enable_tuner(struct mxl *state, u32 tuner, u32 enable) +{ + int stat = 0; + struct MXL_HYDRA_TUNER_CMD ctrl_tuner_cmd; + u8 cmd_size = sizeof(ctrl_tuner_cmd); + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; + u32 val, count = 10; + + ctrl_tuner_cmd.tuner_id = tuner; + ctrl_tuner_cmd.enable = enable; + BUILD_HYDRA_CMD(MXL_HYDRA_TUNER_ACTIVATE_CMD, MXL_CMD_WRITE, + cmd_size, &ctrl_tuner_cmd, cmd_buff); + stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, + &cmd_buff[0]); + if (stat) + return stat; + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); + while (--count && ((val >> tuner) & 1) != enable) { + msleep(20); + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); + } + if (!count) + return -1; + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); + dev_dbg(state->i2cdev, "tuner %u ready = %u\n", + tuner, (val >> tuner) & 1); + + return 0; +} + + +static int config_ts(struct mxl *state, enum MXL_HYDRA_DEMOD_ID_E demod_id, + struct MXL_HYDRA_MPEGOUT_PARAM_T *mpeg_out_param_ptr) +{ + int status = 0; + u32 nco_count_min = 0; + u32 clk_type = 0; + + struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { + {0x90700010, 8, 1}, {0x90700010, 9, 1}, + {0x90700010, 10, 1}, {0x90700010, 11, 1}, + {0x90700010, 12, 1}, {0x90700010, 13, 1}, + {0x90700010, 14, 1}, {0x90700010, 15, 1} }; + struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { + {0x90700010, 16, 1}, {0x90700010, 17, 1}, + {0x90700010, 18, 1}, {0x90700010, 19, 1}, + {0x90700010, 20, 1}, {0x90700010, 21, 1}, + {0x90700010, 22, 1}, {0x90700010, 23, 1} }; + struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { + {0x90700014, 0, 1}, {0x90700014, 1, 1}, + {0x90700014, 2, 1}, {0x90700014, 3, 1}, + {0x90700014, 4, 1}, {0x90700014, 5, 1}, + {0x90700014, 6, 1}, {0x90700014, 7, 1} }; + struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { + {0x90700018, 0, 3}, {0x90700018, 4, 3}, + {0x90700018, 8, 3}, {0x90700018, 12, 3}, + {0x90700018, 16, 3}, {0x90700018, 20, 3}, + {0x90700018, 24, 3}, {0x90700018, 28, 3} }; + struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { + {0x9070000C, 16, 1}, {0x9070000C, 17, 1}, + {0x9070000C, 18, 1}, {0x9070000C, 19, 1}, + {0x9070000C, 20, 1}, {0x9070000C, 21, 1}, + {0x9070000C, 22, 1}, {0x9070000C, 23, 1} }; + struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { + {0x90700010, 0, 1}, {0x90700010, 1, 1}, + {0x90700010, 2, 1}, {0x90700010, 3, 1}, + {0x90700010, 4, 1}, {0x90700010, 5, 1}, + {0x90700010, 6, 1}, {0x90700010, 7, 1} }; + struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { + {0x9070000C, 0, 1}, {0x9070000C, 1, 1}, + {0x9070000C, 2, 1}, {0x9070000C, 3, 1}, + {0x9070000C, 4, 1}, {0x9070000C, 5, 1}, + {0x9070000C, 6, 1}, {0x9070000C, 7, 1} }; + struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { + {0x9070000C, 24, 1}, {0x9070000C, 25, 1}, + {0x9070000C, 26, 1}, {0x9070000C, 27, 1}, + {0x9070000C, 28, 1}, {0x9070000C, 29, 1}, + {0x9070000C, 30, 1}, {0x9070000C, 31, 1} }; + struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { + {0x90700014, 8, 1}, {0x90700014, 9, 1}, + {0x90700014, 10, 1}, {0x90700014, 11, 1}, + {0x90700014, 12, 1}, {0x90700014, 13, 1}, + {0x90700014, 14, 1}, {0x90700014, 15, 1} }; + struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { + {0x907001D4, 0, 1}, {0x907001D4, 1, 1}, + {0x907001D4, 2, 1}, {0x907001D4, 3, 1}, + {0x907001D4, 4, 1}, {0x907001D4, 5, 1}, + {0x907001D4, 6, 1}, {0x907001D4, 7, 1} }; + struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { + {0x90700044, 16, 80}, {0x90700044, 16, 81}, + {0x90700044, 16, 82}, {0x90700044, 16, 83}, + {0x90700044, 16, 84}, {0x90700044, 16, 85}, + {0x90700044, 16, 86}, {0x90700044, 16, 87} }; + + demod_id = state->base->ts_map[demod_id]; + + if (mpeg_out_param_ptr->enable == MXL_ENABLE) { + if (mpeg_out_param_ptr->mpeg_mode == + MXL_HYDRA_MPEG_MODE_PARALLEL) { + } else { + cfg_ts_pad_mux(state, MXL_TRUE); + update_by_mnemonic(state, + 0x90700010, 27, 1, MXL_FALSE); + } + } + + nco_count_min = + (u32)(MXL_HYDRA_NCO_CLK / mpeg_out_param_ptr->max_mpeg_clk_rate); + + if (state->base->chipversion >= 2) { + status |= update_by_mnemonic(state, + xpt_nco_clock_rate[demod_id].reg_addr, /* Reg Addr */ + xpt_nco_clock_rate[demod_id].lsb_pos, /* LSB pos */ + xpt_nco_clock_rate[demod_id].num_of_bits, /* Num of bits */ + nco_count_min); /* Data */ + } else + update_by_mnemonic(state, 0x90700044, 16, 8, nco_count_min); + + if (mpeg_out_param_ptr->mpeg_clk_type == MXL_HYDRA_MPEG_CLK_CONTINUOUS) + clk_type = 1; + + if (mpeg_out_param_ptr->mpeg_mode < MXL_HYDRA_MPEG_MODE_PARALLEL) { + status |= update_by_mnemonic(state, + xpt_continuous_clock[demod_id].reg_addr, + xpt_continuous_clock[demod_id].lsb_pos, + xpt_continuous_clock[demod_id].num_of_bits, + clk_type); + } else + update_by_mnemonic(state, 0x907001D4, 8, 1, clk_type); + + status |= update_by_mnemonic(state, + xpt_sync_polarity[demod_id].reg_addr, + xpt_sync_polarity[demod_id].lsb_pos, + xpt_sync_polarity[demod_id].num_of_bits, + mpeg_out_param_ptr->mpeg_sync_pol); + + status |= update_by_mnemonic(state, + xpt_valid_polarity[demod_id].reg_addr, + xpt_valid_polarity[demod_id].lsb_pos, + xpt_valid_polarity[demod_id].num_of_bits, + mpeg_out_param_ptr->mpeg_valid_pol); + + status |= update_by_mnemonic(state, + xpt_clock_polarity[demod_id].reg_addr, + xpt_clock_polarity[demod_id].lsb_pos, + xpt_clock_polarity[demod_id].num_of_bits, + mpeg_out_param_ptr->mpeg_clk_pol); + + status |= update_by_mnemonic(state, + xpt_sync_byte[demod_id].reg_addr, + xpt_sync_byte[demod_id].lsb_pos, + xpt_sync_byte[demod_id].num_of_bits, + mpeg_out_param_ptr->mpeg_sync_pulse_width); + + status |= update_by_mnemonic(state, + xpt_ts_clock_phase[demod_id].reg_addr, + xpt_ts_clock_phase[demod_id].lsb_pos, + xpt_ts_clock_phase[demod_id].num_of_bits, + mpeg_out_param_ptr->mpeg_clk_phase); + + status |= update_by_mnemonic(state, + xpt_lsb_first[demod_id].reg_addr, + xpt_lsb_first[demod_id].lsb_pos, + xpt_lsb_first[demod_id].num_of_bits, + mpeg_out_param_ptr->lsb_or_msb_first); + + switch (mpeg_out_param_ptr->mpeg_error_indication) { + case MXL_HYDRA_MPEG_ERR_REPLACE_SYNC: + status |= update_by_mnemonic(state, + xpt_err_replace_sync[demod_id].reg_addr, + xpt_err_replace_sync[demod_id].lsb_pos, + xpt_err_replace_sync[demod_id].num_of_bits, + MXL_TRUE); + status |= update_by_mnemonic(state, + xpt_err_replace_valid[demod_id].reg_addr, + xpt_err_replace_valid[demod_id].lsb_pos, + xpt_err_replace_valid[demod_id].num_of_bits, + MXL_FALSE); + break; + + case MXL_HYDRA_MPEG_ERR_REPLACE_VALID: + status |= update_by_mnemonic(state, + xpt_err_replace_sync[demod_id].reg_addr, + xpt_err_replace_sync[demod_id].lsb_pos, + xpt_err_replace_sync[demod_id].num_of_bits, + MXL_FALSE); + + status |= update_by_mnemonic(state, + xpt_err_replace_valid[demod_id].reg_addr, + xpt_err_replace_valid[demod_id].lsb_pos, + xpt_err_replace_valid[demod_id].num_of_bits, + MXL_TRUE); + break; + + case MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED: + default: + status |= update_by_mnemonic(state, + xpt_err_replace_sync[demod_id].reg_addr, + xpt_err_replace_sync[demod_id].lsb_pos, + xpt_err_replace_sync[demod_id].num_of_bits, + MXL_FALSE); + + status |= update_by_mnemonic(state, + xpt_err_replace_valid[demod_id].reg_addr, + xpt_err_replace_valid[demod_id].lsb_pos, + xpt_err_replace_valid[demod_id].num_of_bits, + MXL_FALSE); + + break; + + } + + if (mpeg_out_param_ptr->mpeg_mode != MXL_HYDRA_MPEG_MODE_PARALLEL) { + status |= update_by_mnemonic(state, + xpt_enable_output[demod_id].reg_addr, + xpt_enable_output[demod_id].lsb_pos, + xpt_enable_output[demod_id].num_of_bits, + mpeg_out_param_ptr->enable); + } + return status; +} + +static int config_mux(struct mxl *state) +{ + update_by_mnemonic(state, 0x9070000C, 0, 1, 0); + update_by_mnemonic(state, 0x9070000C, 1, 1, 0); + update_by_mnemonic(state, 0x9070000C, 2, 1, 0); + update_by_mnemonic(state, 0x9070000C, 3, 1, 0); + update_by_mnemonic(state, 0x9070000C, 4, 1, 0); + update_by_mnemonic(state, 0x9070000C, 5, 1, 0); + update_by_mnemonic(state, 0x9070000C, 6, 1, 0); + update_by_mnemonic(state, 0x9070000C, 7, 1, 0); + update_by_mnemonic(state, 0x90700008, 0, 2, 1); + update_by_mnemonic(state, 0x90700008, 2, 2, 1); + return 0; +} + +static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg) +{ + int stat = 0; + u8 *buf; + + if (cfg->fw) + return firmware_download(state, cfg->fw, cfg->fw_len); + + if (!cfg->fw_read) + return -1; + + buf = vmalloc(0x40000); + if (!buf) + return -ENOMEM; + + cfg->fw_read(cfg->fw_priv, buf, 0x40000); + stat = firmware_download(state, buf, 0x40000); + vfree(buf); + + return stat; +} + +static int validate_sku(struct mxl *state) +{ + u32 pad_mux_bond = 0, prcm_chip_id = 0, prcm_so_cid = 0; + int status; + u32 type = state->base->type; + + status = read_by_mnemonic(state, 0x90000190, 0, 3, &pad_mux_bond); + status |= read_by_mnemonic(state, 0x80030000, 0, 12, &prcm_chip_id); + status |= read_by_mnemonic(state, 0x80030004, 24, 8, &prcm_so_cid); + if (status) + return -1; + + dev_info(state->i2cdev, "padMuxBond=%08x, prcmChipId=%08x, prcmSoCId=%08x\n", + pad_mux_bond, prcm_chip_id, prcm_so_cid); + + if (prcm_chip_id != 0x560) { + switch (pad_mux_bond) { + case MXL_HYDRA_SKU_ID_581: + if (type == MXL_HYDRA_DEVICE_581) + return 0; + if (type == MXL_HYDRA_DEVICE_581S) { + state->base->type = MXL_HYDRA_DEVICE_581; + return 0; + } + break; + case MXL_HYDRA_SKU_ID_584: + if (type == MXL_HYDRA_DEVICE_584) + return 0; + break; + case MXL_HYDRA_SKU_ID_544: + if (type == MXL_HYDRA_DEVICE_544) + return 0; + if (type == MXL_HYDRA_DEVICE_542) + return 0; + break; + case MXL_HYDRA_SKU_ID_582: + if (type == MXL_HYDRA_DEVICE_582) + return 0; + break; + default: + return -1; + } + } else { + + } + return -1; +} + +static int get_fwinfo(struct mxl *state) +{ + int status; + u32 val = 0; + + status = read_by_mnemonic(state, 0x90000190, 0, 3, &val); + if (status) + return status; + dev_info(state->i2cdev, "chipID=%08x\n", val); + + status = read_by_mnemonic(state, 0x80030004, 8, 8, &val); + if (status) + return status; + dev_info(state->i2cdev, "chipVer=%08x\n", val); + + status = read_register(state, HYDRA_FIRMWARE_VERSION, &val); + if (status) + return status; + dev_info(state->i2cdev, "FWVer=%08x\n", val); + + state->base->fwversion = val; + return status; +} + + +static u8 ts_map1_to_1[MXL_HYDRA_DEMOD_MAX] = { + MXL_HYDRA_DEMOD_ID_0, + MXL_HYDRA_DEMOD_ID_1, + MXL_HYDRA_DEMOD_ID_2, + MXL_HYDRA_DEMOD_ID_3, + MXL_HYDRA_DEMOD_ID_4, + MXL_HYDRA_DEMOD_ID_5, + MXL_HYDRA_DEMOD_ID_6, + MXL_HYDRA_DEMOD_ID_7, +}; + +static u8 ts_map54x[MXL_HYDRA_DEMOD_MAX] = { + MXL_HYDRA_DEMOD_ID_2, + MXL_HYDRA_DEMOD_ID_3, + MXL_HYDRA_DEMOD_ID_4, + MXL_HYDRA_DEMOD_ID_5, + MXL_HYDRA_DEMOD_MAX, + MXL_HYDRA_DEMOD_MAX, + MXL_HYDRA_DEMOD_MAX, + MXL_HYDRA_DEMOD_MAX, +}; + +static int probe(struct mxl *state, struct mxl5xx_cfg *cfg) +{ + u32 chipver; + int fw, status, j; + struct MXL_HYDRA_MPEGOUT_PARAM_T mpeg_interface_cfg; + + state->base->ts_map = ts_map1_to_1; + + switch (state->base->type) { + case MXL_HYDRA_DEVICE_581: + case MXL_HYDRA_DEVICE_581S: + state->base->can_clkout = 1; + state->base->demod_num = 8; + state->base->tuner_num = 1; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_581; + break; + case MXL_HYDRA_DEVICE_582: + state->base->can_clkout = 1; + state->base->demod_num = 8; + state->base->tuner_num = 3; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_582; + break; + case MXL_HYDRA_DEVICE_585: + state->base->can_clkout = 0; + state->base->demod_num = 8; + state->base->tuner_num = 4; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_585; + break; + case MXL_HYDRA_DEVICE_544: + state->base->can_clkout = 0; + state->base->demod_num = 4; + state->base->tuner_num = 4; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_544; + state->base->ts_map = ts_map54x; + break; + case MXL_HYDRA_DEVICE_541: + case MXL_HYDRA_DEVICE_541S: + state->base->can_clkout = 0; + state->base->demod_num = 4; + state->base->tuner_num = 1; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_541; + state->base->ts_map = ts_map54x; + break; + case MXL_HYDRA_DEVICE_561: + case MXL_HYDRA_DEVICE_561S: + state->base->can_clkout = 0; + state->base->demod_num = 6; + state->base->tuner_num = 1; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_561; + break; + case MXL_HYDRA_DEVICE_568: + state->base->can_clkout = 0; + state->base->demod_num = 8; + state->base->tuner_num = 1; + state->base->chan_bond = 1; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_568; + break; + case MXL_HYDRA_DEVICE_542: + state->base->can_clkout = 1; + state->base->demod_num = 4; + state->base->tuner_num = 3; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_542; + state->base->ts_map = ts_map54x; + break; + case MXL_HYDRA_DEVICE_TEST: + case MXL_HYDRA_DEVICE_584: + default: + state->base->can_clkout = 0; + state->base->demod_num = 8; + state->base->tuner_num = 4; + state->base->sku_type = MXL_HYDRA_SKU_TYPE_584; + break; + } + + status = validate_sku(state); + if (status) + return status; + + update_by_mnemonic(state, 0x80030014, 9, 1, 1); + update_by_mnemonic(state, 0x8003003C, 12, 1, 1); + status = read_by_mnemonic(state, 0x80030000, 12, 4, &chipver); + if (status) + state->base->chipversion = 0; + else + state->base->chipversion = (chipver == 2) ? 2 : 1; + dev_info(state->i2cdev, "Hydra chip version %u\n", + state->base->chipversion); + + cfg_dev_xtal(state, cfg->clk, cfg->cap, 0); + + fw = firmware_is_alive(state); + if (!fw) { + status = load_fw(state, cfg); + if (status) + return status; + } + get_fwinfo(state); + + config_mux(state); + mpeg_interface_cfg.enable = MXL_ENABLE; + mpeg_interface_cfg.lsb_or_msb_first = MXL_HYDRA_MPEG_SERIAL_MSB_1ST; + /* supports only (0-104&139)MHz */ + if (cfg->ts_clk) + mpeg_interface_cfg.max_mpeg_clk_rate = cfg->ts_clk; + else + mpeg_interface_cfg.max_mpeg_clk_rate = 69; /* 139; */ + mpeg_interface_cfg.mpeg_clk_phase = MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG; + mpeg_interface_cfg.mpeg_clk_pol = MXL_HYDRA_MPEG_CLK_IN_PHASE; + /* MXL_HYDRA_MPEG_CLK_GAPPED; */ + mpeg_interface_cfg.mpeg_clk_type = MXL_HYDRA_MPEG_CLK_CONTINUOUS; + mpeg_interface_cfg.mpeg_error_indication = + MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED; + mpeg_interface_cfg.mpeg_mode = MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE; + mpeg_interface_cfg.mpeg_sync_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH; + mpeg_interface_cfg.mpeg_sync_pulse_width = MXL_HYDRA_MPEG_SYNC_WIDTH_BIT; + mpeg_interface_cfg.mpeg_valid_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH; + + for (j = 0; j < state->base->demod_num; j++) { + status = config_ts(state, (enum MXL_HYDRA_DEMOD_ID_E) j, + &mpeg_interface_cfg); + if (status) + return status; + } + set_drive_strength(state, 1); + return 0; +} + +struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)) +{ + struct mxl *state; + struct mxl_base *base; + + state = kzalloc(sizeof(struct mxl), GFP_KERNEL); + if (!state) + return NULL; + + state->demod = demod; + state->tuner = tuner; + state->tuner_in_use = 0xffffffff; + state->i2cdev = &i2c->dev; + + base = match_base(i2c, cfg->adr); + if (base) { + base->count++; + if (base->count > base->demod_num) + goto fail; + state->base = base; + } else { + base = kzalloc(sizeof(struct mxl_base), GFP_KERNEL); + if (!base) + goto fail; + base->i2c = i2c; + base->adr = cfg->adr; + base->type = cfg->type; + base->count = 1; + mutex_init(&base->i2c_lock); + mutex_init(&base->status_lock); + mutex_init(&base->tune_lock); + INIT_LIST_HEAD(&base->mxls); + + state->base = base; + if (probe(state, cfg) < 0) { + kfree(base); + goto fail; + } + list_add(&base->mxllist, &mxllist); + } + state->fe.ops = mxl_ops; + state->xbar[0] = 4; + state->xbar[1] = demod; + state->xbar[2] = 8; + state->fe.demodulator_priv = state; + *fn_set_input = set_input; + + list_add(&state->mxl, &base->mxls); + return &state->fe; + +fail: + kfree(state); + return NULL; +} +EXPORT_SYMBOL_GPL(mxl5xx_attach); + +MODULE_DESCRIPTION("MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver"); +MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/mxl5xx.h b/drivers/media/dvb-frontends/mxl5xx.h new file mode 100644 index 000000000000..532e08111537 --- /dev/null +++ b/drivers/media/dvb-frontends/mxl5xx.h @@ -0,0 +1,41 @@ +#ifndef _MXL5XX_H_ +#define _MXL5XX_H_ + +#include +#include + +#include "dvb_frontend.h" + +struct mxl5xx_cfg { + u8 adr; + u8 type; + u32 cap; + u32 clk; + u32 ts_clk; + + u8 *fw; + u32 fw_len; + + int (*fw_read)(void *priv, u8 *buf, u32 len); + void *fw_priv; +}; + +#if IS_REACHABLE(CONFIG_DVB_MXL5XX) + +extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)); + +#else + +static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)) +{ + pr_warn("%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +#endif /* CONFIG_DVB_MXL5XX */ + +#endif /* _MXL5XX_H_ */ diff --git a/drivers/media/dvb-frontends/mxl5xx_defs.h b/drivers/media/dvb-frontends/mxl5xx_defs.h new file mode 100644 index 000000000000..fd9e61e0188f --- /dev/null +++ b/drivers/media/dvb-frontends/mxl5xx_defs.h @@ -0,0 +1,731 @@ +/* + * Defines for the Maxlinear MX58x family of tuners/demods + * + * Copyright (C) 2014 Digital Devices GmbH + * + * based on code: + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved + * which was released under GPL V2 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, as published by the Free Software Foundation. + */ + +enum MXL_BOOL_E { + MXL_DISABLE = 0, + MXL_ENABLE = 1, + + MXL_FALSE = 0, + MXL_TRUE = 1, + + MXL_INVALID = 0, + MXL_VALID = 1, + + MXL_NO = 0, + MXL_YES = 1, + + MXL_OFF = 0, + MXL_ON = 1 +}; + +/* Firmware-Host Command IDs */ +enum MXL_HYDRA_HOST_CMD_ID_E { + /* --Device command IDs-- */ + MXL_HYDRA_DEV_NO_OP_CMD = 0, /* No OP */ + + MXL_HYDRA_DEV_SET_POWER_MODE_CMD = 1, + MXL_HYDRA_DEV_SET_OVERWRITE_DEF_CMD = 2, + + /* Host-used CMD, not used by firmware */ + MXL_HYDRA_DEV_FIRMWARE_DOWNLOAD_CMD = 3, + + /* Additional CONTROL types from DTV */ + MXL_HYDRA_DEV_SET_BROADCAST_PID_STB_ID_CMD = 4, + MXL_HYDRA_DEV_GET_PMM_SLEEP_CMD = 5, + + /* --Tuner command IDs-- */ + MXL_HYDRA_TUNER_TUNE_CMD = 6, + MXL_HYDRA_TUNER_GET_STATUS_CMD = 7, + + /* --Demod command IDs-- */ + MXL_HYDRA_DEMOD_SET_PARAM_CMD = 8, + MXL_HYDRA_DEMOD_GET_STATUS_CMD = 9, + + MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD = 10, + + MXL_HYDRA_DEMOD_SET_PKT_NUM_CMD = 11, + + MXL_HYDRA_DEMOD_SET_IQ_SOURCE_CMD = 12, + MXL_HYDRA_DEMOD_GET_IQ_DATA_CMD = 13, + + MXL_HYDRA_DEMOD_GET_M68HC05_VER_CMD = 14, + + MXL_HYDRA_DEMOD_SET_ERROR_COUNTER_MODE_CMD = 15, + + /* --- ABORT channel tune */ + MXL_HYDRA_ABORT_TUNE_CMD = 16, /* Abort current tune command. */ + + /* --SWM/FSK command IDs-- */ + MXL_HYDRA_FSK_RESET_CMD = 17, + MXL_HYDRA_FSK_MSG_CMD = 18, + MXL_HYDRA_FSK_SET_OP_MODE_CMD = 19, + + /* --DiSeqC command IDs-- */ + MXL_HYDRA_DISEQC_MSG_CMD = 20, + MXL_HYDRA_DISEQC_COPY_MSG_TO_MAILBOX = 21, + MXL_HYDRA_DISEQC_CFG_MSG_CMD = 22, + + /* --- FFT Debug Command IDs-- */ + MXL_HYDRA_REQ_FFT_SPECTRUM_CMD = 23, + + /* -- Demod scramblle code */ + MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD = 24, + + /* ---For host to know how many commands in total */ + MXL_HYDRA_LAST_HOST_CMD = 25, + + MXL_HYDRA_DEMOD_INTR_TYPE_CMD = 47, + MXL_HYDRA_DEV_INTR_CLEAR_CMD = 48, + MXL_HYDRA_TUNER_SPECTRUM_REQ_CMD = 53, + MXL_HYDRA_TUNER_ACTIVATE_CMD = 55, + MXL_HYDRA_DEV_CFG_POWER_MODE_CMD = 56, + MXL_HYDRA_DEV_XTAL_CAP_CMD = 57, + MXL_HYDRA_DEV_CFG_SKU_CMD = 58, + MXL_HYDRA_TUNER_SPECTRUM_MIN_GAIN_CMD = 59, + MXL_HYDRA_DISEQC_CONT_TONE_CFG = 60, + MXL_HYDRA_DEV_RF_WAKE_UP_CMD = 61, + MXL_HYDRA_DEMOD_CFG_EQ_CTRL_PARAM_CMD = 62, + MXL_HYDRA_DEMOD_FREQ_OFFSET_SEARCH_RANGE_CMD = 63, + MXL_HYDRA_DEV_REQ_PWR_FROM_ADCRSSI_CMD = 64, + + MXL_XCPU_PID_FLT_CFG_CMD = 65, + MXL_XCPU_SHMEM_TEST_CMD = 66, + MXL_XCPU_ABORT_TUNE_CMD = 67, + MXL_XCPU_CHAN_TUNE_CMD = 68, + MXL_XCPU_FLT_BOND_HDRS_CMD = 69, + + MXL_HYDRA_DEV_BROADCAST_WAKE_UP_CMD = 70, + MXL_HYDRA_FSK_CFG_FSK_FREQ_CMD = 71, + MXL_HYDRA_FSK_POWER_DOWN_CMD = 72, + MXL_XCPU_CLEAR_CB_STATS_CMD = 73, + MXL_XCPU_CHAN_BOND_RESTART_CMD = 74 +}; + +#define MXL_ENABLE_BIG_ENDIAN (0) + +#define MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH 248 + +#define MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN (248) + +#define MXL_HYDRA_CAP_MIN 10 +#define MXL_HYDRA_CAP_MAX 33 + +#define MXL_HYDRA_PLID_REG_READ 0xFB /* Read register PLID */ +#define MXL_HYDRA_PLID_REG_WRITE 0xFC /* Write register PLID */ + +#define MXL_HYDRA_PLID_CMD_READ 0xFD /* Command Read PLID */ +#define MXL_HYDRA_PLID_CMD_WRITE 0xFE /* Command Write PLID */ + +#define MXL_HYDRA_REG_SIZE_IN_BYTES 4 /* Hydra register size in bytes */ +#define MXL_HYDRA_I2C_HDR_SIZE (2 * sizeof(u8)) /* PLID + LEN(0xFF) */ +#define MXL_HYDRA_CMD_HEADER_SIZE (MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE) + +#define MXL_HYDRA_SKU_ID_581 0 +#define MXL_HYDRA_SKU_ID_584 1 +#define MXL_HYDRA_SKU_ID_585 2 +#define MXL_HYDRA_SKU_ID_544 3 +#define MXL_HYDRA_SKU_ID_561 4 +#define MXL_HYDRA_SKU_ID_582 5 +#define MXL_HYDRA_SKU_ID_568 6 + +/* macro for register write data buffer size + * (PLID + LEN (0xFF) + RegAddr + RegData) + */ +#define MXL_HYDRA_REG_WRITE_LEN (MXL_HYDRA_I2C_HDR_SIZE + (2 * MXL_HYDRA_REG_SIZE_IN_BYTES)) + +/* macro to extract a single byte from 4-byte(32-bit) data */ +#define GET_BYTE(x, n) (((x) >> (8*(n))) & 0xFF) + +#define MAX_CMD_DATA 512 + +#define MXL_GET_REG_MASK_32(lsb_loc, num_of_bits) ((0xFFFFFFFF >> (32 - (num_of_bits))) << (lsb_loc)) + +#define FW_DL_SIGN (0xDEADBEEF) + +#define MBIN_FORMAT_VERSION '1' +#define MBIN_FILE_HEADER_ID 'M' +#define MBIN_SEGMENT_HEADER_ID 'S' +#define MBIN_MAX_FILE_LENGTH (1<<23) + +struct MBIN_FILE_HEADER_T { + u8 id; + u8 fmt_version; + u8 header_len; + u8 num_segments; + u8 entry_address[4]; + u8 image_size24[3]; + u8 image_checksum; + u8 reserved[4]; +}; + +struct MBIN_FILE_T { + struct MBIN_FILE_HEADER_T header; + u8 data[1]; +}; + +struct MBIN_SEGMENT_HEADER_T { + u8 id; + u8 len24[3]; + u8 address[4]; +}; + +struct MBIN_SEGMENT_T { + struct MBIN_SEGMENT_HEADER_T header; + u8 data[1]; +}; + +enum MXL_CMD_TYPE_E { MXL_CMD_WRITE = 0, MXL_CMD_READ }; + +#define BUILD_HYDRA_CMD(cmd_id, req_type, size, data_ptr, cmd_buff) \ + do { \ + cmd_buff[0] = ((req_type == MXL_CMD_WRITE) ? MXL_HYDRA_PLID_CMD_WRITE : MXL_HYDRA_PLID_CMD_READ); \ + cmd_buff[1] = (size > 251) ? 0xff : (u8) (size + 4); \ + cmd_buff[2] = size; \ + cmd_buff[3] = cmd_id; \ + cmd_buff[4] = 0x00; \ + cmd_buff[5] = 0x00; \ + convert_endian(MXL_ENABLE_BIG_ENDIAN, size, (u8 *)data_ptr); \ + memcpy((void *)&cmd_buff[6], data_ptr, size); \ + } while (0) + +struct MXL_REG_FIELD_T { + u32 reg_addr; + u8 lsb_pos; + u8 num_of_bits; +}; + +struct MXL_DEV_CMD_DATA_T { + u32 data_size; + u8 data[MAX_CMD_DATA]; +}; + +enum MXL_HYDRA_SKU_TYPE_E { + MXL_HYDRA_SKU_TYPE_MIN = 0x00, + MXL_HYDRA_SKU_TYPE_581 = 0x00, + MXL_HYDRA_SKU_TYPE_584 = 0x01, + MXL_HYDRA_SKU_TYPE_585 = 0x02, + MXL_HYDRA_SKU_TYPE_544 = 0x03, + MXL_HYDRA_SKU_TYPE_561 = 0x04, + MXL_HYDRA_SKU_TYPE_5XX = 0x05, + MXL_HYDRA_SKU_TYPE_5YY = 0x06, + MXL_HYDRA_SKU_TYPE_511 = 0x07, + MXL_HYDRA_SKU_TYPE_561_DE = 0x08, + MXL_HYDRA_SKU_TYPE_582 = 0x09, + MXL_HYDRA_SKU_TYPE_541 = 0x0A, + MXL_HYDRA_SKU_TYPE_568 = 0x0B, + MXL_HYDRA_SKU_TYPE_542 = 0x0C, + MXL_HYDRA_SKU_TYPE_MAX = 0x0D, +}; + +struct MXL_HYDRA_SKU_COMMAND_T { + enum MXL_HYDRA_SKU_TYPE_E sku_type; +}; + +enum MXL_HYDRA_DEMOD_ID_E { + MXL_HYDRA_DEMOD_ID_0 = 0, + MXL_HYDRA_DEMOD_ID_1, + MXL_HYDRA_DEMOD_ID_2, + MXL_HYDRA_DEMOD_ID_3, + MXL_HYDRA_DEMOD_ID_4, + MXL_HYDRA_DEMOD_ID_5, + MXL_HYDRA_DEMOD_ID_6, + MXL_HYDRA_DEMOD_ID_7, + MXL_HYDRA_DEMOD_MAX +}; + +#define MXL_DEMOD_SCRAMBLE_SEQ_LEN 12 + +#define MAX_STEP_SIZE_24_XTAL_102_05_KHZ 195 +#define MAX_STEP_SIZE_24_XTAL_204_10_KHZ 215 +#define MAX_STEP_SIZE_24_XTAL_306_15_KHZ 203 +#define MAX_STEP_SIZE_24_XTAL_408_20_KHZ 177 + +#define MAX_STEP_SIZE_27_XTAL_102_05_KHZ 195 +#define MAX_STEP_SIZE_27_XTAL_204_10_KHZ 215 +#define MAX_STEP_SIZE_27_XTAL_306_15_KHZ 203 +#define MAX_STEP_SIZE_27_XTAL_408_20_KHZ 177 + +#define MXL_HYDRA_SPECTRUM_MIN_FREQ_KHZ 300000 +#define MXL_HYDRA_SPECTRUM_MAX_FREQ_KHZ 2350000 + +enum MXL_DEMOD_CHAN_PARAMS_OFFSET_E { + DMD_STANDARD_ADDR = 0, + DMD_SPECTRUM_INVERSION_ADDR, + DMD_SPECTRUM_ROLL_OFF_ADDR, + DMD_SYMBOL_RATE_ADDR, + DMD_MODULATION_SCHEME_ADDR, + DMD_FEC_CODE_RATE_ADDR, + DMD_SNR_ADDR, + DMD_FREQ_OFFSET_ADDR, + DMD_CTL_FREQ_OFFSET_ADDR, + DMD_STR_FREQ_OFFSET_ADDR, + DMD_FTL_FREQ_OFFSET_ADDR, + DMD_STR_NBC_SYNC_LOCK_ADDR, + DMD_CYCLE_SLIP_COUNT_ADDR, + DMD_DISPLAY_IQ_ADDR, + DMD_DVBS2_CRC_ERRORS_ADDR, + DMD_DVBS2_PER_COUNT_ADDR, + DMD_DVBS2_PER_WINDOW_ADDR, + DMD_DVBS_CORR_RS_ERRORS_ADDR, + DMD_DVBS_UNCORR_RS_ERRORS_ADDR, + DMD_DVBS_BER_COUNT_ADDR, + DMD_DVBS_BER_WINDOW_ADDR, + DMD_TUNER_ID_ADDR, + DMD_DVBS2_PILOT_ON_OFF_ADDR, + DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR, + + MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE, +}; + +enum MXL_HYDRA_TUNER_ID_E { + MXL_HYDRA_TUNER_ID_0 = 0, + MXL_HYDRA_TUNER_ID_1, + MXL_HYDRA_TUNER_ID_2, + MXL_HYDRA_TUNER_ID_3, + MXL_HYDRA_TUNER_MAX +}; + +enum MXL_HYDRA_BCAST_STD_E { + MXL_HYDRA_DSS = 0, + MXL_HYDRA_DVBS, + MXL_HYDRA_DVBS2, +}; + +enum MXL_HYDRA_FEC_E { + MXL_HYDRA_FEC_AUTO = 0, + MXL_HYDRA_FEC_1_2, + MXL_HYDRA_FEC_3_5, + MXL_HYDRA_FEC_2_3, + MXL_HYDRA_FEC_3_4, + MXL_HYDRA_FEC_4_5, + MXL_HYDRA_FEC_5_6, + MXL_HYDRA_FEC_6_7, + MXL_HYDRA_FEC_7_8, + MXL_HYDRA_FEC_8_9, + MXL_HYDRA_FEC_9_10, +}; + +enum MXL_HYDRA_MODULATION_E { + MXL_HYDRA_MOD_AUTO = 0, + MXL_HYDRA_MOD_QPSK, + MXL_HYDRA_MOD_8PSK +}; + +enum MXL_HYDRA_SPECTRUM_E { + MXL_HYDRA_SPECTRUM_AUTO = 0, + MXL_HYDRA_SPECTRUM_INVERTED, + MXL_HYDRA_SPECTRUM_NON_INVERTED, +}; + +enum MXL_HYDRA_ROLLOFF_E { + MXL_HYDRA_ROLLOFF_AUTO = 0, + MXL_HYDRA_ROLLOFF_0_20, + MXL_HYDRA_ROLLOFF_0_25, + MXL_HYDRA_ROLLOFF_0_35 +}; + +enum MXL_HYDRA_PILOTS_E { + MXL_HYDRA_PILOTS_OFF = 0, + MXL_HYDRA_PILOTS_ON, + MXL_HYDRA_PILOTS_AUTO +}; + +enum MXL_HYDRA_CONSTELLATION_SRC_E { + MXL_HYDRA_FORMATTER = 0, + MXL_HYDRA_LEGACY_FEC, + MXL_HYDRA_FREQ_RECOVERY, + MXL_HYDRA_NBC, + MXL_HYDRA_CTL, + MXL_HYDRA_EQ, +}; + +struct MXL_HYDRA_DEMOD_LOCK_T { + int agc_lock; /* AGC lock info */ + int fec_lock; /* Demod FEC block lock info */ +}; + +struct MXL_HYDRA_DEMOD_STATUS_DVBS_T { + u32 rs_errors; /* RS decoder err counter */ + u32 ber_window; /* Ber Windows */ + u32 ber_count; /* BER count */ + u32 ber_window_iter1; /* Ber Windows - post viterbi */ + u32 ber_count_iter1; /* BER count - post viterbi */ +}; + +struct MXL_HYDRA_DEMOD_STATUS_DSS_T { + u32 rs_errors; /* RS decoder err counter */ + u32 ber_window; /* Ber Windows */ + u32 ber_count; /* BER count */ +}; + +struct MXL_HYDRA_DEMOD_STATUS_DVBS2_T { + u32 crc_errors; /* CRC error counter */ + u32 packet_error_count; /* Number of packet errors */ + u32 total_packets; /* Total packets */ +}; + +struct MXL_HYDRA_DEMOD_STATUS_T { + enum MXL_HYDRA_BCAST_STD_E standard_mask; /* Standard DVB-S, DVB-S2 or DSS */ + + union { + struct MXL_HYDRA_DEMOD_STATUS_DVBS_T demod_status_dvbs; /* DVB-S demod status */ + struct MXL_HYDRA_DEMOD_STATUS_DVBS2_T demod_status_dvbs2; /* DVB-S2 demod status */ + struct MXL_HYDRA_DEMOD_STATUS_DSS_T demod_status_dss; /* DSS demod status */ + } u; +}; + +struct MXL_HYDRA_DEMOD_SIG_OFFSET_INFO_T { + s32 carrier_offset_in_hz; /* CRL offset info */ + s32 symbol_offset_in_symbol; /* SRL offset info */ +}; + +struct MXL_HYDRA_DEMOD_SCRAMBLE_INFO_T { + u8 scramble_sequence[MXL_DEMOD_SCRAMBLE_SEQ_LEN]; /* scramble sequence */ + u32 scramble_code; /* scramble gold code */ +}; + +enum MXL_HYDRA_SPECTRUM_STEP_SIZE_E { + MXL_HYDRA_STEP_SIZE_24_XTAL_102_05KHZ, /* 102.05 KHz for 24 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_24_XTAL_204_10KHZ, /* 204.10 KHz for 24 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_24_XTAL_306_15KHZ, /* 306.15 KHz for 24 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_24_XTAL_408_20KHZ, /* 408.20 KHz for 24 MHz XTAL */ + + MXL_HYDRA_STEP_SIZE_27_XTAL_102_05KHZ, /* 102.05 KHz for 27 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_27_XTAL_204_35KHZ, /* 204.35 KHz for 27 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_27_XTAL_306_52KHZ, /* 306.52 KHz for 27 MHz XTAL */ + MXL_HYDRA_STEP_SIZE_27_XTAL_408_69KHZ, /* 408.69 KHz for 27 MHz XTAL */ +}; + +enum MXL_HYDRA_SPECTRUM_RESOLUTION_E { + MXL_HYDRA_SPECTRUM_RESOLUTION_00_1_DB, /* 0.1 dB */ + MXL_HYDRA_SPECTRUM_RESOLUTION_01_0_DB, /* 1.0 dB */ + MXL_HYDRA_SPECTRUM_RESOLUTION_05_0_DB, /* 5.0 dB */ + MXL_HYDRA_SPECTRUM_RESOLUTION_10_0_DB, /* 10 dB */ +}; + +enum MXL_HYDRA_SPECTRUM_ERROR_CODE_E { + MXL_SPECTRUM_NO_ERROR, + MXL_SPECTRUM_INVALID_PARAMETER, + MXL_SPECTRUM_INVALID_STEP_SIZE, + MXL_SPECTRUM_BW_CANNOT_BE_COVERED, + MXL_SPECTRUM_DEMOD_BUSY, + MXL_SPECTRUM_TUNER_NOT_ENABLED, +}; + +struct MXL_HYDRA_SPECTRUM_REQ_T { + u32 tuner_index; /* TUNER Ctrl: one of MXL58x_TUNER_ID_E */ + u32 demod_index; /* DEMOD Ctrl: one of MXL58x_DEMOD_ID_E */ + enum MXL_HYDRA_SPECTRUM_STEP_SIZE_E step_size_in_khz; + u32 starting_freq_ink_hz; + u32 total_steps; + enum MXL_HYDRA_SPECTRUM_RESOLUTION_E spectrum_division; +}; + +enum MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E { + MXL_HYDRA_SEARCH_MAX_OFFSET = 0, /* DMD searches for max freq offset (i.e. 5MHz) */ + MXL_HYDRA_SEARCH_BW_PLUS_ROLLOFF, /* DMD searches for BW + ROLLOFF/2 */ +}; + +struct MXL58X_CFG_FREQ_OFF_SEARCH_RANGE_T { + u32 demod_index; + enum MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E search_type; +}; + +/* there are two slices + * slice0 - TS0, TS1, TS2 & TS3 + * slice1 - TS4, TS5, TS6 & TS7 + */ +#define MXL_HYDRA_TS_SLICE_MAX 2 + +#define MAX_FIXED_PID_NUM 32 + +#define MXL_HYDRA_NCO_CLK 418 /* 418 MHz */ + +#define MXL_HYDRA_MAX_TS_CLOCK 139 /* 139 MHz */ + +#define MXL_HYDRA_TS_FIXED_PID_FILT_SIZE 32 + +#define MXL_HYDRA_SHARED_PID_FILT_SIZE_DEFAULT 33 /* Shared PID filter size in 1-1 mux mode */ +#define MXL_HYDRA_SHARED_PID_FILT_SIZE_2_TO_1 66 /* Shared PID filter size in 2-1 mux mode */ +#define MXL_HYDRA_SHARED_PID_FILT_SIZE_4_TO_1 132 /* Shared PID filter size in 4-1 mux mode */ + +enum MXL_HYDRA_PID_BANK_TYPE_E { + MXL_HYDRA_SOFTWARE_PID_BANK = 0, + MXL_HYDRA_HARDWARE_PID_BANK, +}; + +enum MXL_HYDRA_TS_MUX_MODE_E { + MXL_HYDRA_TS_MUX_PID_REMAP = 0, + MXL_HYDRA_TS_MUX_PREFIX_EXTRA_HEADER = 1, +}; + +enum MXL_HYDRA_TS_MUX_TYPE_E { + MXL_HYDRA_TS_MUX_DISABLE = 0, /* No Mux ( 1 TSIF to 1 TSIF) */ + MXL_HYDRA_TS_MUX_2_TO_1, /* Mux 2 TSIF to 1 TSIF */ + MXL_HYDRA_TS_MUX_4_TO_1, /* Mux 4 TSIF to 1 TSIF */ +}; + +enum MXL_HYDRA_TS_GROUP_E { + MXL_HYDRA_TS_GROUP_0_3 = 0, /* TS group 0 to 3 (TS0, TS1, TS2 & TS3) */ + MXL_HYDRA_TS_GROUP_4_7, /* TS group 0 to 3 (TS4, TS5, TS6 & TS7) */ +}; + +enum MXL_HYDRA_TS_PID_FLT_CTRL_E { + MXL_HYDRA_TS_PIDS_ALLOW_ALL = 0, /* Allow all pids */ + MXL_HYDRA_TS_PIDS_DROP_ALL, /* Drop all pids */ + MXL_HYDRA_TS_INVALIDATE_PID_FILTER, /* Delete current PD filter in the device */ +}; + +enum MXL_HYDRA_TS_PID_TYPE_E { + MXL_HYDRA_TS_PID_FIXED = 0, + MXL_HYDRA_TS_PID_REGULAR, +}; + +struct MXL_HYDRA_TS_PID_T { + u16 original_pid; /* pid from TS */ + u16 remapped_pid; /* remapped pid */ + enum MXL_BOOL_E enable; /* enable or disable pid */ + enum MXL_BOOL_E allow_or_drop; /* allow or drop pid */ + enum MXL_BOOL_E enable_pid_remap; /* enable or disable pid remap */ + u8 bond_id; /* Bond ID in A0 always 0 - Only for 568 Sku */ + u8 dest_id; /* Output port ID for the PID - Only for 568 Sku */ +}; + +struct MXL_HYDRA_TS_MUX_PREFIX_HEADER_T { + enum MXL_BOOL_E enable; + u8 num_byte; + u8 header[12]; +}; + +enum MXL_HYDRA_PID_FILTER_BANK_E { + MXL_HYDRA_PID_BANK_A = 0, + MXL_HYDRA_PID_BANK_B, +}; + +enum MXL_HYDRA_MPEG_DATA_FMT_E { + MXL_HYDRA_MPEG_SERIAL_MSB_1ST = 0, + MXL_HYDRA_MPEG_SERIAL_LSB_1ST, + + MXL_HYDRA_MPEG_SYNC_WIDTH_BIT = 0, + MXL_HYDRA_MPEG_SYNC_WIDTH_BYTE +}; + +enum MXL_HYDRA_MPEG_MODE_E { + MXL_HYDRA_MPEG_MODE_SERIAL_4_WIRE = 0, /* MPEG 4 Wire serial mode */ + MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE, /* MPEG 3 Wire serial mode */ + MXL_HYDRA_MPEG_MODE_SERIAL_2_WIRE, /* MPEG 2 Wire serial mode */ + MXL_HYDRA_MPEG_MODE_PARALLEL /* MPEG parallel mode - valid only for MxL581 */ +}; + +enum MXL_HYDRA_MPEG_CLK_TYPE_E { + MXL_HYDRA_MPEG_CLK_CONTINUOUS = 0, /* Continuous MPEG clock */ + MXL_HYDRA_MPEG_CLK_GAPPED, /* Gapped (gated) MPEG clock */ +}; + +enum MXL_HYDRA_MPEG_CLK_FMT_E { + MXL_HYDRA_MPEG_ACTIVE_LOW = 0, + MXL_HYDRA_MPEG_ACTIVE_HIGH, + + MXL_HYDRA_MPEG_CLK_NEGATIVE = 0, + MXL_HYDRA_MPEG_CLK_POSITIVE, + + MXL_HYDRA_MPEG_CLK_IN_PHASE = 0, + MXL_HYDRA_MPEG_CLK_INVERTED, +}; + +enum MXL_HYDRA_MPEG_CLK_PHASE_E { + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG = 0, + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_90_DEG, + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG, + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_270_DEG +}; + +enum MXL_HYDRA_MPEG_ERR_INDICATION_E { + MXL_HYDRA_MPEG_ERR_REPLACE_SYNC = 0, + MXL_HYDRA_MPEG_ERR_REPLACE_VALID, + MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED +}; + +struct MXL_HYDRA_MPEGOUT_PARAM_T { + int enable; /* Enable or Disable MPEG OUT */ + enum MXL_HYDRA_MPEG_CLK_TYPE_E mpeg_clk_type; /* Continuous or gapped */ + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_clk_pol; /* MPEG Clk polarity */ + u8 max_mpeg_clk_rate; /* Max MPEG Clk rate (0 - 104 MHz, 139 MHz) */ + enum MXL_HYDRA_MPEG_CLK_PHASE_E mpeg_clk_phase; /* MPEG Clk phase */ + enum MXL_HYDRA_MPEG_DATA_FMT_E lsb_or_msb_first; /* LSB first or MSB first in TS transmission */ + enum MXL_HYDRA_MPEG_DATA_FMT_E mpeg_sync_pulse_width; /* MPEG SYNC pulse width (1-bit or 1-byte) */ + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_valid_pol; /* MPEG VALID polarity */ + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_sync_pol; /* MPEG SYNC polarity */ + enum MXL_HYDRA_MPEG_MODE_E mpeg_mode; /* config 4/3/2-wire serial or parallel TS out */ + enum MXL_HYDRA_MPEG_ERR_INDICATION_E mpeg_error_indication; /* Enable or Disable MPEG error indication */ +}; + +enum MXL_HYDRA_EXT_TS_IN_ID_E { + MXL_HYDRA_EXT_TS_IN_0 = 0, + MXL_HYDRA_EXT_TS_IN_1, + MXL_HYDRA_EXT_TS_IN_2, + MXL_HYDRA_EXT_TS_IN_3, + MXL_HYDRA_EXT_TS_IN_MAX +}; + +enum MXL_HYDRA_TS_OUT_ID_E { + MXL_HYDRA_TS_OUT_0 = 0, + MXL_HYDRA_TS_OUT_1, + MXL_HYDRA_TS_OUT_2, + MXL_HYDRA_TS_OUT_3, + MXL_HYDRA_TS_OUT_4, + MXL_HYDRA_TS_OUT_5, + MXL_HYDRA_TS_OUT_6, + MXL_HYDRA_TS_OUT_7, + MXL_HYDRA_TS_OUT_MAX +}; + +enum MXL_HYDRA_TS_DRIVE_STRENGTH_E { + MXL_HYDRA_TS_DRIVE_STRENGTH_1X = 0, + MXL_HYDRA_TS_DRIVE_STRENGTH_2X, + MXL_HYDRA_TS_DRIVE_STRENGTH_3X, + MXL_HYDRA_TS_DRIVE_STRENGTH_4X, + MXL_HYDRA_TS_DRIVE_STRENGTH_5X, + MXL_HYDRA_TS_DRIVE_STRENGTH_6X, + MXL_HYDRA_TS_DRIVE_STRENGTH_7X, + MXL_HYDRA_TS_DRIVE_STRENGTH_8X +}; + +enum MXL_HYDRA_DEVICE_E { + MXL_HYDRA_DEVICE_581 = 0, + MXL_HYDRA_DEVICE_584, + MXL_HYDRA_DEVICE_585, + MXL_HYDRA_DEVICE_544, + MXL_HYDRA_DEVICE_561, + MXL_HYDRA_DEVICE_TEST, + MXL_HYDRA_DEVICE_582, + MXL_HYDRA_DEVICE_541, + MXL_HYDRA_DEVICE_568, + MXL_HYDRA_DEVICE_542, + MXL_HYDRA_DEVICE_541S, + MXL_HYDRA_DEVICE_561S, + MXL_HYDRA_DEVICE_581S, + MXL_HYDRA_DEVICE_MAX +}; + +/* Demod IQ data */ +struct MXL_HYDRA_DEMOD_IQ_SRC_T { + u32 demod_id; + u32 source_of_iq; /* == 0, it means I/Q comes from Formatter + * == 1, Legacy FEC + * == 2, Frequency Recovery + * == 3, NBC + * == 4, CTL + * == 5, EQ + * == 6, FPGA + */ +}; + +struct MXL_HYDRA_DEMOD_ABORT_TUNE_T { + u32 demod_id; +}; + +struct MXL_HYDRA_TUNER_CMD { + u8 tuner_id; + u8 enable; +}; + +/* Demod Para for Channel Tune */ +struct MXL_HYDRA_DEMOD_PARAM_T { + u32 tuner_index; + u32 demod_index; + u32 frequency_in_hz; /* Frequency */ + u32 standard; /* one of MXL_HYDRA_BCAST_STD_E */ + u32 spectrum_inversion; /* Input : Spectrum inversion. */ + u32 roll_off; /* rollOff (alpha) factor */ + u32 symbol_rate_in_hz; /* Symbol rate */ + u32 pilots; /* TRUE = pilots enabled */ + u32 modulation_scheme; /* Input : Modulation Scheme is one of MXL_HYDRA_MODULATION_E */ + u32 fec_code_rate; /* Input : Forward error correction rate. Is one of MXL_HYDRA_FEC_E */ + u32 max_carrier_offset_in_mhz; /* Maximum carrier freq offset in MHz. Same as freqSearchRangeKHz, but in unit of MHz. */ +}; + +struct MXL_HYDRA_DEMOD_SCRAMBLE_CODE_T { + u32 demod_index; + u8 scramble_sequence[12]; /* scramble sequence */ + u32 scramble_code; /* scramble gold code */ +}; + +struct MXL_INTR_CFG_T { + u32 intr_type; + u32 intr_duration_in_nano_secs; + u32 intr_mask; +}; + +struct MXL_HYDRA_POWER_MODE_CMD { + u8 power_mode; /* enumeration values are defined in MXL_HYDRA_PWR_MODE_E (device API.h) */ +}; + +struct MXL_HYDRA_RF_WAKEUP_PARAM_T { + u32 time_interval_in_seconds; /* in seconds */ + u32 tuner_index; + s32 rssi_threshold; +}; + +struct MXL_HYDRA_RF_WAKEUP_CFG_T { + u32 tuner_count; + struct MXL_HYDRA_RF_WAKEUP_PARAM_T params; +}; + +enum MXL_HYDRA_AUX_CTRL_MODE_E { + MXL_HYDRA_AUX_CTRL_MODE_FSK = 0, /* Select FSK controller */ + MXL_HYDRA_AUX_CTRL_MODE_DISEQC, /* Select DiSEqC controller */ +}; + +enum MXL_HYDRA_DISEQC_OPMODE_E { + MXL_HYDRA_DISEQC_ENVELOPE_MODE = 0, + MXL_HYDRA_DISEQC_TONE_MODE, +}; + +enum MXL_HYDRA_DISEQC_VER_E { + MXL_HYDRA_DISEQC_1_X = 0, /* Config DiSEqC 1.x mode */ + MXL_HYDRA_DISEQC_2_X, /* Config DiSEqC 2.x mode */ + MXL_HYDRA_DISEQC_DISABLE /* Disable DiSEqC */ +}; + +enum MXL_HYDRA_DISEQC_CARRIER_FREQ_E { + MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ = 0, /* DiSEqC signal frequency of 22 KHz */ + MXL_HYDRA_DISEQC_CARRIER_FREQ_33KHZ, /* DiSEqC signal frequency of 33 KHz */ + MXL_HYDRA_DISEQC_CARRIER_FREQ_44KHZ /* DiSEqC signal frequency of 44 KHz */ +}; + +enum MXL_HYDRA_DISEQC_ID_E { + MXL_HYDRA_DISEQC_ID_0 = 0, + MXL_HYDRA_DISEQC_ID_1, + MXL_HYDRA_DISEQC_ID_2, + MXL_HYDRA_DISEQC_ID_3 +}; + +enum MXL_HYDRA_FSK_OP_MODE_E { + MXL_HYDRA_FSK_CFG_TYPE_39KPBS = 0, /* 39.0kbps */ + MXL_HYDRA_FSK_CFG_TYPE_39_017KPBS, /* 39.017kbps */ + MXL_HYDRA_FSK_CFG_TYPE_115_2KPBS /* 115.2kbps */ +}; + +struct MXL58X_DSQ_OP_MODE_T { + u32 diseqc_id; /* DSQ 0, 1, 2 or 3 */ + u32 op_mode; /* Envelope mode (0) or internal tone mode (1) */ + u32 version; /* 0: 1.0, 1: 1.1, 2: Disable */ + u32 center_freq; /* 0: 22KHz, 1: 33KHz and 2: 44 KHz */ +}; + +struct MXL_HYDRA_DISEQC_CFG_CONT_TONE_T { + u32 diseqc_id; + u32 cont_tone_flag; /* 1: Enable , 0: Disable */ +}; diff --git a/drivers/media/dvb-frontends/mxl5xx_regs.h b/drivers/media/dvb-frontends/mxl5xx_regs.h new file mode 100644 index 000000000000..5001dafe1ba8 --- /dev/null +++ b/drivers/media/dvb-frontends/mxl5xx_regs.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved + * + * License type: GPLv2 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * This program may alternatively be licensed under a proprietary license from + * MaxLinear, Inc. + * + */ + +#ifndef __MXL58X_REGISTERS_H__ +#define __MXL58X_REGISTERS_H__ + +#define HYDRA_INTR_STATUS_REG 0x80030008 +#define HYDRA_INTR_MASK_REG 0x8003000C + +#define HYDRA_CRYSTAL_SETTING 0x3FFFC5F0 /* 0 - 24 MHz & 1 - 27 MHz */ +#define HYDRA_CRYSTAL_CAP 0x3FFFEDA4 /* 0 - 24 MHz & 1 - 27 MHz */ + +#define HYDRA_CPU_RESET_REG 0x8003003C +#define HYDRA_CPU_RESET_DATA 0x00000400 + +#define HYDRA_RESET_TRANSPORT_FIFO_REG 0x80030028 +#define HYDRA_RESET_TRANSPORT_FIFO_DATA 0x00000000 + +#define HYDRA_RESET_BBAND_REG 0x80030024 +#define HYDRA_RESET_BBAND_DATA 0x00000000 + +#define HYDRA_RESET_XBAR_REG 0x80030020 +#define HYDRA_RESET_XBAR_DATA 0x00000000 + +#define HYDRA_MODULES_CLK_1_REG 0x80030014 +#define HYDRA_DISABLE_CLK_1 0x00000000 + +#define HYDRA_MODULES_CLK_2_REG 0x8003001C +#define HYDRA_DISABLE_CLK_2 0x0000000B + +#define HYDRA_PRCM_ROOT_CLK_REG 0x80030018 +#define HYDRA_PRCM_ROOT_CLK_DISABLE 0x00000000 + +#define HYDRA_CPU_RESET_CHECK_REG 0x80030008 +#define HYDRA_CPU_RESET_CHECK_OFFSET 0x40000000 /* */ + +#define HYDRA_SKU_ID_REG 0x90000190 + +#define FW_DL_SIGN_ADDR 0x3FFFEAE0 + +/* Register to check if FW is running or not */ +#define HYDRA_HEAR_BEAT 0x3FFFEDDC + +/* Firmware version */ +#define HYDRA_FIRMWARE_VERSION 0x3FFFEDB8 +#define HYDRA_FW_RC_VERSION 0x3FFFCFAC + +/* Firmware patch version */ +#define HYDRA_FIRMWARE_PATCH_VERSION 0x3FFFEDC2 + +/* SOC operating temperature in C */ +#define HYDRA_TEMPARATURE 0x3FFFEDB4 + +/* Demod & Tuner status registers */ +/* Demod 0 status base address */ +#define HYDRA_DEMOD_0_BASE_ADDR 0x3FFFC64C + +/* Tuner 0 status base address */ +#define HYDRA_TUNER_0_BASE_ADDR 0x3FFFCE4C + +#define POWER_FROM_ADCRSSI_READBACK 0x3FFFEB6C + +/* Macros to determine base address of respective demod or tuner */ +#define HYDRA_DMD_STATUS_OFFSET(demodID) ((demodID) * 0x100) +#define HYDRA_TUNER_STATUS_OFFSET(tunerID) ((tunerID) * 0x40) + +/* Demod status address offset from respective demod's base address */ +#define HYDRA_DMD_AGC_DIG_LEVEL_ADDR_OFFSET 0x3FFFC64C +#define HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET 0x3FFFC650 +#define HYDRA_DMD_ACQ_STATUS_ADDR_OFFSET 0x3FFFC654 + +#define HYDRA_DMD_STANDARD_ADDR_OFFSET 0x3FFFC658 +#define HYDRA_DMD_SPECTRUM_INVERSION_ADDR_OFFSET 0x3FFFC65C +#define HYDRA_DMD_SPECTRUM_ROLL_OFF_ADDR_OFFSET 0x3FFFC660 +#define HYDRA_DMD_SYMBOL_RATE_ADDR_OFFSET 0x3FFFC664 +#define HYDRA_DMD_MODULATION_SCHEME_ADDR_OFFSET 0x3FFFC668 +#define HYDRA_DMD_FEC_CODE_RATE_ADDR_OFFSET 0x3FFFC66C + +#define HYDRA_DMD_SNR_ADDR_OFFSET 0x3FFFC670 +#define HYDRA_DMD_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC674 +#define HYDRA_DMD_CTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC678 +#define HYDRA_DMD_STR_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC67C +#define HYDRA_DMD_FTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC680 +#define HYDRA_DMD_STR_NBC_SYNC_LOCK_ADDR_OFFSET 0x3FFFC684 +#define HYDRA_DMD_CYCLE_SLIP_COUNT_ADDR_OFFSET 0x3FFFC688 + +#define HYDRA_DMD_DISPLAY_I_ADDR_OFFSET 0x3FFFC68C +#define HYDRA_DMD_DISPLAY_Q_ADDR_OFFSET 0x3FFFC68E + +#define HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET 0x3FFFC690 +#define HYDRA_DMD_DVBS2_PER_COUNT_ADDR_OFFSET 0x3FFFC694 +#define HYDRA_DMD_DVBS2_PER_WINDOW_ADDR_OFFSET 0x3FFFC698 + +#define HYDRA_DMD_DVBS_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC69C +#define HYDRA_DMD_DVBS_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6A0 +#define HYDRA_DMD_DVBS_BER_COUNT_ADDR_OFFSET 0x3FFFC6A4 +#define HYDRA_DMD_DVBS_BER_WINDOW_ADDR_OFFSET 0x3FFFC6A8 + +/* Debug-purpose DVB-S DMD 0 */ +#define HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6C8 /* corrected RS Errors: 1st iteration */ +#define HYDRA_DMD_DVBS_1ST_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6CC /* uncorrected RS Errors: 1st iteration */ +#define HYDRA_DMD_DVBS_BER_COUNT_1ST_ADDR_OFFSET 0x3FFFC6D0 +#define HYDRA_DMD_DVBS_BER_WINDOW_1ST_ADDR_OFFSET 0x3FFFC6D4 + +#define HYDRA_DMD_TUNER_ID_ADDR_OFFSET 0x3FFFC6AC +#define HYDRA_DMD_DVBS2_PILOT_ON_OFF_ADDR_OFFSET 0x3FFFC6B0 +#define HYDRA_DMD_FREQ_SEARCH_RANGE_KHZ_ADDR_OFFSET 0x3FFFC6B4 +#define HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET 0x3FFFC6B8 +#define HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR 0x3FFFC704 +#define HYDRA_DMD_STATUS_INPUT_POWER_ADDR 0x3FFFC708 + +/* DVB-S new scaled_BER_count for a new BER API, see HYDRA-1343 "DVB-S post viterbi information" */ +#define DMD0_STATUS_DVBS_1ST_SCALED_BER_COUNT_ADDR 0x3FFFC710 /* DMD 0: 1st iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR */ +#define DMD0_STATUS_DVBS_SCALED_BER_COUNT_ADDR 0x3FFFC714 /* DMD 0: 2nd iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR */ + +#define DMD0_SPECTRUM_MIN_GAIN_STATUS 0x3FFFC73C +#define DMD0_SPECTRUM_MIN_GAIN_WB_SAGC_VALUE 0x3FFFC740 +#define DMD0_SPECTRUM_MIN_GAIN_NB_SAGC_VALUE 0x3FFFC744 + +#define HYDRA_DMD_STATUS_END_ADDR_OFFSET 0x3FFFC748 + +/* Tuner status address offset from respective tuners's base address */ +#define HYDRA_TUNER_DEMOD_ID_ADDR_OFFSET 0x3FFFCE4C +#define HYDRA_TUNER_AGC_LOCK_OFFSET 0x3FFFCE50 +#define HYDRA_TUNER_SPECTRUM_STATUS_OFFSET 0x3FFFCE54 +#define HYDRA_TUNER_SPECTRUM_BIN_SIZE_OFFSET 0x3FFFCE58 +#define HYDRA_TUNER_SPECTRUM_ADDRESS_OFFSET 0x3FFFCE5C +#define HYDRA_TUNER_ENABLE_COMPLETE 0x3FFFEB78 + +#define HYDRA_DEMOD_STATUS_LOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_YES) +#define HYDRA_DEMOD_STATUS_UNLOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_NO) + +#define HYDRA_VERSION 0x3FFFEDB8 +#define HYDRA_DEMOD0_VERSION 0x3FFFEDBC +#define HYDRA_DEMOD1_VERSION 0x3FFFEDC0 +#define HYDRA_DEMOD2_VERSION 0x3FFFEDC4 +#define HYDRA_DEMOD3_VERSION 0x3FFFEDC8 +#define HYDRA_DEMOD4_VERSION 0x3FFFEDCC +#define HYDRA_DEMOD5_VERSION 0x3FFFEDD0 +#define HYDRA_DEMOD6_VERSION 0x3FFFEDD4 +#define HYDRA_DEMOD7_VERSION 0x3FFFEDD8 +#define HYDRA_HEAR_BEAT 0x3FFFEDDC +#define HYDRA_SKU_MGMT 0x3FFFEBC0 + +#define MXL_HYDRA_FPGA_A_ADDRESS 0x91C00000 +#define MXL_HYDRA_FPGA_B_ADDRESS 0x91D00000 + +/* TS control base address */ +#define HYDRA_TS_CTRL_BASE_ADDR 0x90700000 + +#define MPEG_MUX_MODE_SLICE0_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x08) + +#define MPEG_MUX_MODE_SLICE1_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x08) + +#define PID_BANK_SEL_SLICE0_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) +#define PID_BANK_SEL_SLICE1_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) + +#define MPEG_CLK_GATED_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x20) + +#define MPEG_CLK_ALWAYS_ON_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1D4) + +#define HYDRA_REGULAR_PID_BANK_A_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) + +#define HYDRA_FIXED_PID_BANK_A_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) + +#define HYDRA_REGULAR_PID_BANK_B_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) + +#define HYDRA_FIXED_PID_BANK_B_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) + +#define FIXED_PID_TBL_REG_ADDRESS_0 (HYDRA_TS_CTRL_BASE_ADDR + 0x9000) +#define FIXED_PID_TBL_REG_ADDRESS_1 (HYDRA_TS_CTRL_BASE_ADDR + 0x9100) +#define FIXED_PID_TBL_REG_ADDRESS_2 (HYDRA_TS_CTRL_BASE_ADDR + 0x9200) +#define FIXED_PID_TBL_REG_ADDRESS_3 (HYDRA_TS_CTRL_BASE_ADDR + 0x9300) + +#define FIXED_PID_TBL_REG_ADDRESS_4 (HYDRA_TS_CTRL_BASE_ADDR + 0xB000) +#define FIXED_PID_TBL_REG_ADDRESS_5 (HYDRA_TS_CTRL_BASE_ADDR + 0xB100) +#define FIXED_PID_TBL_REG_ADDRESS_6 (HYDRA_TS_CTRL_BASE_ADDR + 0xB200) +#define FIXED_PID_TBL_REG_ADDRESS_7 (HYDRA_TS_CTRL_BASE_ADDR + 0xB300) + +#define REGULAR_PID_TBL_REG_ADDRESS_0 (HYDRA_TS_CTRL_BASE_ADDR + 0x8000) +#define REGULAR_PID_TBL_REG_ADDRESS_1 (HYDRA_TS_CTRL_BASE_ADDR + 0x8200) +#define REGULAR_PID_TBL_REG_ADDRESS_2 (HYDRA_TS_CTRL_BASE_ADDR + 0x8400) +#define REGULAR_PID_TBL_REG_ADDRESS_3 (HYDRA_TS_CTRL_BASE_ADDR + 0x8600) + +#define REGULAR_PID_TBL_REG_ADDRESS_4 (HYDRA_TS_CTRL_BASE_ADDR + 0xA000) +#define REGULAR_PID_TBL_REG_ADDRESS_5 (HYDRA_TS_CTRL_BASE_ADDR + 0xA200) +#define REGULAR_PID_TBL_REG_ADDRESS_6 (HYDRA_TS_CTRL_BASE_ADDR + 0xA400) +#define REGULAR_PID_TBL_REG_ADDRESS_7 (HYDRA_TS_CTRL_BASE_ADDR + 0xA600) + +/***************************************************************************/ + +#define PAD_MUX_GPIO_00_SYNC_BASEADDR 0x90000188 + + +#define PAD_MUX_UART_RX_C_PINMUX_BASEADDR 0x9000001C + +#define XPT_PACKET_GAP_MIN_BASEADDR 0x90700044 +#define XPT_NCO_COUNT_BASEADDR 0x90700238 + +#define XPT_NCO_COUNT_BASEADDR1 0x9070023C + +/* V2 DigRF status register */ + +#define XPT_PID_BASEADDR 0x90708000 + +#define XPT_PID_REMAP_BASEADDR 0x90708004 + +#define XPT_KNOWN_PID_BASEADDR 0x90709000 + +#define XPT_PID_BASEADDR1 0x9070A000 + +#define XPT_PID_REMAP_BASEADDR1 0x9070A004 + +#define XPT_KNOWN_PID_BASEADDR1 0x9070B000 + +#define XPT_BERT_LOCK_BASEADDR 0x907000B8 + +#define XPT_BERT_BASEADDR 0x907000BC + +#define XPT_BERT_INVERT_BASEADDR 0x907000C0 + +#define XPT_BERT_HEADER_BASEADDR 0x907000C4 + +#define XPT_BERT_BASEADDR1 0x907000C8 + +#define XPT_BERT_BIT_COUNT0_BASEADDR 0x907000CC + +#define XPT_BERT_BIT_COUNT0_BASEADDR1 0x907000D0 + +#define XPT_BERT_BIT_COUNT1_BASEADDR 0x907000D4 + +#define XPT_BERT_BIT_COUNT1_BASEADDR1 0x907000D8 + +#define XPT_BERT_BIT_COUNT2_BASEADDR 0x907000DC + +#define XPT_BERT_BIT_COUNT2_BASEADDR1 0x907000E0 + +#define XPT_BERT_BIT_COUNT3_BASEADDR 0x907000E4 + +#define XPT_BERT_BIT_COUNT3_BASEADDR1 0x907000E8 + +#define XPT_BERT_BIT_COUNT4_BASEADDR 0x907000EC + +#define XPT_BERT_BIT_COUNT4_BASEADDR1 0x907000F0 + +#define XPT_BERT_BIT_COUNT5_BASEADDR 0x907000F4 + +#define XPT_BERT_BIT_COUNT5_BASEADDR1 0x907000F8 + +#define XPT_BERT_BIT_COUNT6_BASEADDR 0x907000FC + +#define XPT_BERT_BIT_COUNT6_BASEADDR1 0x90700100 + +#define XPT_BERT_BIT_COUNT7_BASEADDR 0x90700104 + +#define XPT_BERT_BIT_COUNT7_BASEADDR1 0x90700108 + +#define XPT_BERT_ERR_COUNT0_BASEADDR 0x9070010C + +#define XPT_BERT_ERR_COUNT0_BASEADDR1 0x90700110 + +#define XPT_BERT_ERR_COUNT1_BASEADDR 0x90700114 + +#define XPT_BERT_ERR_COUNT1_BASEADDR1 0x90700118 + +#define XPT_BERT_ERR_COUNT2_BASEADDR 0x9070011C + +#define XPT_BERT_ERR_COUNT2_BASEADDR1 0x90700120 + +#define XPT_BERT_ERR_COUNT3_BASEADDR 0x90700124 + +#define XPT_BERT_ERR_COUNT3_BASEADDR1 0x90700128 + +#define XPT_BERT_ERR_COUNT4_BASEADDR 0x9070012C + +#define XPT_BERT_ERR_COUNT4_BASEADDR1 0x90700130 + +#define XPT_BERT_ERR_COUNT5_BASEADDR 0x90700134 + +#define XPT_BERT_ERR_COUNT5_BASEADDR1 0x90700138 + +#define XPT_BERT_ERR_COUNT6_BASEADDR 0x9070013C + +#define XPT_BERT_ERR_COUNT6_BASEADDR1 0x90700140 + +#define XPT_BERT_ERR_COUNT7_BASEADDR 0x90700144 + +#define XPT_BERT_ERR_COUNT7_BASEADDR1 0x90700148 + +#define XPT_BERT_ERROR_BASEADDR 0x9070014C + +#define XPT_BERT_ANALYZER_BASEADDR 0x90700150 + +#define XPT_BERT_ANALYZER_BASEADDR1 0x90700154 + +#define XPT_BERT_ANALYZER_BASEADDR2 0x90700158 + +#define XPT_BERT_ANALYZER_BASEADDR3 0x9070015C + +#define XPT_BERT_ANALYZER_BASEADDR4 0x90700160 + +#define XPT_BERT_ANALYZER_BASEADDR5 0x90700164 + +#define XPT_BERT_ANALYZER_BASEADDR6 0x90700168 + +#define XPT_BERT_ANALYZER_BASEADDR7 0x9070016C + +#define XPT_BERT_ANALYZER_BASEADDR8 0x90700170 + +#define XPT_BERT_ANALYZER_BASEADDR9 0x90700174 + +#define XPT_DMD0_BASEADDR 0x9070024C + +/* V2 AGC Gain Freeze & step */ +#define DBG_ENABLE_DISABLE_AGC (0x3FFFCF60) /* 1: DISABLE, 0:ENABLE */ +#define WB_DFE0_DFE_FB_RF1_BASEADDR 0x903004A4 + +#define WB_DFE1_DFE_FB_RF1_BASEADDR 0x904004A4 + +#define WB_DFE2_DFE_FB_RF1_BASEADDR 0x905004A4 + +#define WB_DFE3_DFE_FB_RF1_BASEADDR 0x906004A4 + +#define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR 0x90200104 + +#define AFE_REG_AFE_REG_SPARE_BASEADDR 0x902000A0 + +#define AFE_REG_AFE_REG_SPARE_BASEADDR1 0x902000B4 + +#define AFE_REG_AFE_REG_SPARE_BASEADDR2 0x902000C4 + +#define AFE_REG_AFE_REG_SPARE_BASEADDR3 0x902000D4 + +#define WB_DFE0_DFE_FB_AGC_BASEADDR 0x90300498 + +#define WB_DFE1_DFE_FB_AGC_BASEADDR 0x90400498 + +#define WB_DFE2_DFE_FB_AGC_BASEADDR 0x90500498 + +#define WB_DFE3_DFE_FB_AGC_BASEADDR 0x90600498 + +#define WDT_WD_INT_BASEADDR 0x8002000C + +#define FSK_TX_FTM_BASEADDR 0x80090000 + +#define FSK_TX_FTM_TX_CNT_BASEADDR 0x80090018 + +#define AFE_REG_D2A_FSK_BIAS_BASEADDR 0x90200040 + +#define DMD_TEI_BASEADDR 0x3FFFEBE0 + +#endif /* __MXL58X_REGISTERS_H__ */ -- cgit v1.2.3 From bb4cec96e5d7f0ff7f397f4518399be77a2f12db Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 9 Jul 2017 15:42:44 -0400 Subject: media: ddbridge: support MaxLinear MXL5xx based cards (MaxS4/8) This enables MaxS4/S8 and Octopus Max card support in ddbridge by adding glue code into ddbridge-core, having another PCI ID, and have the LNB IC control code (and all other MaxS4/8 related code) in ddbridge-maxs8.c (rather than another ~400 LoC in ddbridge-core.c like it's done in the original vendor driver package). Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/Kconfig | 2 + drivers/media/pci/ddbridge/Makefile | 2 +- drivers/media/pci/ddbridge/ddbridge-core.c | 67 ++++- drivers/media/pci/ddbridge/ddbridge-hw.c | 12 + drivers/media/pci/ddbridge/ddbridge-hw.h | 4 + drivers/media/pci/ddbridge/ddbridge-main.c | 1 + drivers/media/pci/ddbridge/ddbridge-maxs8.c | 443 ++++++++++++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge-maxs8.h | 29 ++ drivers/media/pci/ddbridge/ddbridge-regs.h | 21 ++ drivers/media/pci/ddbridge/ddbridge.h | 11 + 10 files changed, 588 insertions(+), 4 deletions(-) create mode 100644 drivers/media/pci/ddbridge/ddbridge-maxs8.c create mode 100644 drivers/media/pci/ddbridge/ddbridge-maxs8.h (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index 1330b2ecc72a..f43d0b83fc0c 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig @@ -12,6 +12,7 @@ config DVB_DDBRIDGE select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT + select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for cards with the Digital Devices PCI express bridge: - Octopus PCIe Bridge @@ -24,6 +25,7 @@ config DVB_DDBRIDGE - CineCTv7 and DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based) - MaxA8 series - CineS2 V7/V7A and DuoFlex S2 V4 (ST STV0910-based) + - Max S4/8 Say Y if you own such a card and want to use it. diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index 3ef3048a89ac..09703312a3f1 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile @@ -3,7 +3,7 @@ # ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \ - ddbridge-i2c.o + ddbridge-i2c.o ddbridge-maxs8.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index e051a691eb42..c290d3fecc8d 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -37,6 +37,7 @@ #include "ddbridge.h" #include "ddbridge-i2c.h" #include "ddbridge-regs.h" +#include "ddbridge-maxs8.h" #include "ddbridge-io.h" #include "tda18271c2dd.h" @@ -1424,8 +1425,9 @@ static int dvb_input_attach(struct ddb_input *input) dvb->fe = dvb->fe2 = NULL; switch (port->type) { case DDB_TUNER_MXL5XX: - dev_notice(port->dev->dev, "MaxLinear MxL5xx not supported\n"); - return -ENODEV; + if (fe_attach_mxl5xx(input) < 0) + return -ENODEV; + break; case DDB_TUNER_DVBS_ST: if (demod_attach_stv0900(input, 0) < 0) return -ENODEV; @@ -1770,6 +1772,17 @@ static void ddb_port_probe(struct ddb_port *port) return; } + if (dev->link[l].info->type == DDB_OCTOPUS_MAX) { + port->name = "DUAL DVB-S2 MAX"; + port->type_name = "MXL5XX"; + port->class = DDB_PORT_TUNER; + port->type = DDB_TUNER_MXL5XX; + if (port->i2c) + ddbwritel(dev, I2C_SPEED_400, + port->i2c->regs + I2C_TIMING); + return; + } + if (port->nr > 1 && dev->link[l].info->type == DDB_OCTOPUS_CI) { port->name = "CI internal"; port->type_name = "INTERNAL"; @@ -2531,6 +2544,20 @@ static int ddb_port_match_i2c(struct ddb_port *port) return 0; } +static int ddb_port_match_link_i2c(struct ddb_port *port) +{ + struct ddb *dev = port->dev; + u32 i; + + for (i = 0; i < dev->i2c_num; i++) { + if (dev->i2c[i].link == port->lnr) { + port->i2c = &dev->i2c[i]; + return 1; + } + } + return 0; +} + void ddb_ports_init(struct ddb *dev) { u32 i, l, p; @@ -2555,7 +2582,11 @@ void ddb_ports_init(struct ddb *dev) port->obr = ci_bitrate; mutex_init(&port->i2c_gate_lock); - ddb_port_match_i2c(port); + if (!ddb_port_match_i2c(port)) { + if (info->type == DDB_OCTOPUS_MAX) + ddb_port_match_link_i2c(port); + } + ddb_port_probe(port); port->dvb[0].adap = &dev->adap[2 * p]; @@ -2603,6 +2634,7 @@ void ddb_ports_init(struct ddb *dev) ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1); ddb_output_init(port, i); break; + case DDB_OCTOPUS_MAX: case DDB_OCTOPUS_MAX_CT: ddb_input_init(port, 2 * i, 0, 2 * p); ddb_input_init(port, 2 * i + 1, 1, 2 * p + 1); @@ -3202,6 +3234,15 @@ static ssize_t regmap_show(struct device *device, return sprintf(buf, "0x%08X\n", dev->link[0].ids.regmapid); } +static ssize_t fmode_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + int num = attr->attr.name[5] - 0x30; + struct ddb *dev = dev_get_drvdata(device); + + return sprintf(buf, "%u\n", dev->link[num].lnb.fmode); +} + static ssize_t devid_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -3211,6 +3252,21 @@ static ssize_t devid_show(struct device *device, return sprintf(buf, "%08x\n", dev->link[num].ids.devid); } +static ssize_t fmode_store(struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ddb *dev = dev_get_drvdata(device); + int num = attr->attr.name[5] - 0x30; + unsigned int val; + + if (sscanf(buf, "%u\n", &val) != 1) + return -EINVAL; + if (val > 3) + return -EINVAL; + lnb_init_fmode(dev, &dev->link[num], val); + return count; +} + static struct device_attribute ddb_attrs[] = { __ATTR_RO(version), __ATTR_RO(ports), @@ -3220,6 +3276,10 @@ static struct device_attribute ddb_attrs[] = { __ATTR(gap1, 0664, gap_show, gap_store), __ATTR(gap2, 0664, gap_show, gap_store), __ATTR(gap3, 0664, gap_show, gap_store), + __ATTR(fmode0, 0664, fmode_show, fmode_store), + __ATTR(fmode1, 0664, fmode_show, fmode_store), + __ATTR(fmode2, 0664, fmode_show, fmode_store), + __ATTR(fmode3, 0664, fmode_show, fmode_store), __ATTR_MRO(devid0, devid_show), __ATTR_MRO(devid1, devid_show), __ATTR_MRO(devid2, devid_show), @@ -3509,6 +3569,7 @@ static int ddb_init_boards(struct ddb *dev) int ddb_init(struct ddb *dev) { + mutex_init(&dev->link[0].lnb.lock); mutex_init(&dev->link[0].flash_mutex); if (no_init) { ddb_device_create(dev); diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c index e35b41e8d860..317dc865e99c 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.c +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -297,3 +297,15 @@ const struct ddb_info ddb_c2t2i_8 = { .ts_quirks = TS_QUIRK_SERIAL, .tempmon_irq = 24, }; + +/****************************************************************************/ + +const struct ddb_info ddb_s2_48 = { + .type = DDB_OCTOPUS_MAX, + .name = "Digital Devices MAX S8 4/8", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 1, + .tempmon_irq = 24, +}; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.h b/drivers/media/pci/ddbridge/ddbridge-hw.h index bd52c083c4a5..d26cd9c977d8 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.h +++ b/drivers/media/pci/ddbridge/ddbridge-hw.h @@ -49,4 +49,8 @@ extern const struct ddb_info ddb_isdbt_8; extern const struct ddb_info ddb_c2t2i_v0_8; extern const struct ddb_info ddb_c2t2i_8; +/****************************************************************************/ + +extern const struct ddb_info ddb_s2_48; + #endif /* _DDBRIDGE_HW_H */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 181d5f17fe91..3cb6bb265172 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -313,6 +313,7 @@ static const struct pci_device_id ddb_id_table[] = { DDB_DEVICE(0x0006, 0x0031, ddb_ctv7), DDB_DEVICE(0x0006, 0x0032, ddb_ctv7), DDB_DEVICE(0x0006, 0x0033, ddb_ctv7), + DDB_DEVICE(0x0007, 0x0023, ddb_s2_48), DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8), DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8), DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8), diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.c b/drivers/media/pci/ddbridge/ddbridge-maxs8.c new file mode 100644 index 000000000000..a9dc5f9754da --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-maxs8.c @@ -0,0 +1,443 @@ +/* + * ddbridge-maxs8.c: Digital Devices bridge MaxS4/8 support + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ddbridge.h" +#include "ddbridge-regs.h" +#include "ddbridge-io.h" + +#include "ddbridge-maxs8.h" +#include "mxl5xx.h" + +/******************************************************************************/ + +/* MaxS4/8 related modparams */ +static int fmode; +module_param(fmode, int, 0444); +MODULE_PARM_DESC(fmode, "frontend emulation mode"); + +static int fmode_sat = -1; +module_param(fmode_sat, int, 0444); +MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat"); + +static int old_quattro; +module_param(old_quattro, int, 0444); +MODULE_PARM_DESC(old_quattro, "old quattro LNB input order "); + +/******************************************************************************/ + +static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd) +{ + u32 c, v = 0, tag = DDB_LINK_TAG(link); + + v = LNB_TONE & (dev->link[link].lnb.tone << (15 - lnb)); + ddbwritel(dev, cmd | v, tag | LNB_CONTROL(lnb)); + for (c = 0; c < 10; c++) { + v = ddbreadl(dev, tag | LNB_CONTROL(lnb)); + if ((v & LNB_BUSY) == 0) + break; + msleep(20); + } + if (c == 10) + dev_info(dev->dev, "%s lnb = %08x cmd = %08x\n", + __func__, lnb, cmd); + return 0; +} + +static int max_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; + struct ddb *dev = port->dev; + struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; + u32 tag = DDB_LINK_TAG(port->lnr); + int i; + u32 fmode = dev->link[port->lnr].lnb.fmode; + + if (fmode == 2 || fmode == 1) + return 0; + if (dvb->diseqc_send_master_cmd) + dvb->diseqc_send_master_cmd(fe, cmd); + + mutex_lock(&dev->link[port->lnr].lnb.lock); + ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(dvb->input)); + for (i = 0; i < cmd->msg_len; i++) + ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(dvb->input)); + lnb_command(dev, port->lnr, dvb->input, LNB_CMD_DISEQC); + mutex_unlock(&dev->link[port->lnr].lnb.lock); + return 0; +} + +static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input, + struct dvb_diseqc_master_cmd *cmd) +{ + u32 tag = DDB_LINK_TAG(link); + int i; + + ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input)); + for (i = 0; i < cmd->msg_len; i++) + ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input)); + lnb_command(dev, link, input, LNB_CMD_DISEQC); + return 0; +} + +static int lnb_set_sat(struct ddb *dev, u32 link, u32 input, u32 sat, u32 band, + u32 hor) +{ + struct dvb_diseqc_master_cmd cmd = { + .msg = {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, + .msg_len = 4 + }; + cmd.msg[3] = 0xf0 | (((sat << 2) & 0x0c) | (band ? 1 : 0) | + (hor ? 2 : 0)); + return lnb_send_diseqc(dev, link, input, &cmd); +} + +static int lnb_set_tone(struct ddb *dev, u32 link, u32 input, + enum fe_sec_tone_mode tone) +{ + int s = 0; + u32 mask = (1ULL << input); + + switch (tone) { + case SEC_TONE_OFF: + if (!(dev->link[link].lnb.tone & mask)) + return 0; + dev->link[link].lnb.tone &= ~(1ULL << input); + break; + case SEC_TONE_ON: + if (dev->link[link].lnb.tone & mask) + return 0; + dev->link[link].lnb.tone |= (1ULL << input); + break; + default: + s = -EINVAL; + break; + }; + if (!s) + s = lnb_command(dev, link, input, LNB_CMD_NOP); + return s; +} + +static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input, + enum fe_sec_voltage voltage) +{ + int s = 0; + + if (dev->link[link].lnb.oldvoltage[input] == voltage) + return 0; + switch (voltage) { + case SEC_VOLTAGE_OFF: + if (dev->link[link].lnb.voltage[input]) + return 0; + lnb_command(dev, link, input, LNB_CMD_OFF); + break; + case SEC_VOLTAGE_13: + lnb_command(dev, link, input, LNB_CMD_LOW); + break; + case SEC_VOLTAGE_18: + lnb_command(dev, link, input, LNB_CMD_HIGH); + break; + default: + s = -EINVAL; + break; + }; + dev->link[link].lnb.oldvoltage[input] = voltage; + return s; +} + +static int max_set_input_unlocked(struct dvb_frontend *fe, int in) +{ + struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; + struct ddb *dev = port->dev; + struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; + int res = 0; + + if (in > 3) + return -EINVAL; + if (dvb->input != in) { + u32 bit = (1ULL << input->nr); + u32 obit = dev->link[port->lnr].lnb.voltage[dvb->input] & bit; + + dev->link[port->lnr].lnb.voltage[dvb->input] &= ~bit; + dvb->input = in; + dev->link[port->lnr].lnb.voltage[dvb->input] |= obit; + } + res = dvb->set_input(fe, in); + return res; +} + +static int max_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) +{ + struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; + struct ddb *dev = port->dev; + struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; + int tuner = 0; + int res = 0; + u32 fmode = dev->link[port->lnr].lnb.fmode; + + mutex_lock(&dev->link[port->lnr].lnb.lock); + dvb->tone = tone; + switch (fmode) { + default: + case 0: + case 3: + res = lnb_set_tone(dev, port->lnr, dvb->input, tone); + break; + case 1: + case 2: + if (old_quattro) { + if (dvb->tone == SEC_TONE_ON) + tuner |= 2; + if (dvb->voltage == SEC_VOLTAGE_18) + tuner |= 1; + } else { + if (dvb->tone == SEC_TONE_ON) + tuner |= 1; + if (dvb->voltage == SEC_VOLTAGE_18) + tuner |= 2; + } + res = max_set_input_unlocked(fe, tuner); + break; + } + mutex_unlock(&dev->link[port->lnr].lnb.lock); + return res; +} + +static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) +{ + struct ddb_input *input = fe->sec_priv; + struct ddb_port *port = input->port; + struct ddb *dev = port->dev; + struct ddb_dvb *dvb = &port->dvb[input->nr & 1]; + int tuner = 0; + u32 nv, ov = dev->link[port->lnr].lnb.voltages; + int res = 0; + u32 fmode = dev->link[port->lnr].lnb.fmode; + + mutex_lock(&dev->link[port->lnr].lnb.lock); + dvb->voltage = voltage; + + switch (fmode) { + case 3: + default: + case 0: + if (fmode == 3) + max_set_input_unlocked(fe, 0); + if (voltage == SEC_VOLTAGE_OFF) + dev->link[port->lnr].lnb.voltage[dvb->input] &= + ~(1ULL << input->nr); + else + dev->link[port->lnr].lnb.voltage[dvb->input] |= + (1ULL << input->nr); + + res = lnb_set_voltage(dev, port->lnr, dvb->input, voltage); + break; + case 1: + case 2: + if (voltage == SEC_VOLTAGE_OFF) + dev->link[port->lnr].lnb.voltages &= + ~(1ULL << input->nr); + else + dev->link[port->lnr].lnb.voltages |= + (1ULL << input->nr); + + nv = dev->link[port->lnr].lnb.voltages; + + if (old_quattro) { + if (dvb->tone == SEC_TONE_ON) + tuner |= 2; + if (dvb->voltage == SEC_VOLTAGE_18) + tuner |= 1; + } else { + if (dvb->tone == SEC_TONE_ON) + tuner |= 1; + if (dvb->voltage == SEC_VOLTAGE_18) + tuner |= 2; + } + res = max_set_input_unlocked(fe, tuner); + + if (nv != ov) { + if (nv) { + lnb_set_voltage(dev, + port->lnr, 0, SEC_VOLTAGE_13); + if (fmode == 1) { + lnb_set_voltage(dev, port->lnr, + 0, SEC_VOLTAGE_13); + if (old_quattro) { + lnb_set_voltage(dev, port->lnr, + 1, SEC_VOLTAGE_18); + lnb_set_voltage(dev, port->lnr, + 2, SEC_VOLTAGE_13); + } else { + lnb_set_voltage(dev, port->lnr, + 1, SEC_VOLTAGE_13); + lnb_set_voltage(dev, port->lnr, + 2, SEC_VOLTAGE_18); + } + lnb_set_voltage(dev, port->lnr, + 3, SEC_VOLTAGE_18); + } + } else { + lnb_set_voltage(dev, port->lnr, + 0, SEC_VOLTAGE_OFF); + if (fmode == 1) { + lnb_set_voltage(dev, port->lnr, + 1, SEC_VOLTAGE_OFF); + lnb_set_voltage(dev, port->lnr, + 2, SEC_VOLTAGE_OFF); + lnb_set_voltage(dev, port->lnr, + 3, SEC_VOLTAGE_OFF); + } + } + } + break; + } + mutex_unlock(&dev->link[port->lnr].lnb.lock); + return res; +} + +static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) +{ + + return 0; +} + +static int max_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) +{ + return 0; +} + +static int mxl_fw_read(void *priv, u8 *buf, u32 len) +{ + struct ddb_link *link = priv; + struct ddb *dev = link->dev; + + dev_info(dev->dev, "Read mxl_fw from link %u\n", link->nr); + + return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len); +} + +int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm) +{ + u32 l = link->nr; + + if (link->lnb.fmode == fm) + return 0; + dev_info(dev->dev, "Set fmode link %u = %u\n", l, fm); + mutex_lock(&link->lnb.lock); + if (fm == 2 || fm == 1) { + if (fmode_sat >= 0) { + lnb_set_sat(dev, l, 0, fmode_sat, 0, 0); + if (old_quattro) { + lnb_set_sat(dev, l, 1, fmode_sat, 0, 1); + lnb_set_sat(dev, l, 2, fmode_sat, 1, 0); + } else { + lnb_set_sat(dev, l, 1, fmode_sat, 1, 0); + lnb_set_sat(dev, l, 2, fmode_sat, 0, 1); + } + lnb_set_sat(dev, l, 3, fmode_sat, 1, 1); + } + lnb_set_tone(dev, l, 0, SEC_TONE_OFF); + if (old_quattro) { + lnb_set_tone(dev, l, 1, SEC_TONE_OFF); + lnb_set_tone(dev, l, 2, SEC_TONE_ON); + } else { + lnb_set_tone(dev, l, 1, SEC_TONE_ON); + lnb_set_tone(dev, l, 2, SEC_TONE_OFF); + } + lnb_set_tone(dev, l, 3, SEC_TONE_ON); + } + link->lnb.fmode = fm; + mutex_unlock(&link->lnb.lock); + return 0; +} + +static struct mxl5xx_cfg mxl5xx = { + .adr = 0x60, + .type = 0x01, + .clk = 27000000, + .ts_clk = 139, + .cap = 12, + .fw_read = mxl_fw_read, +}; + +int fe_attach_mxl5xx(struct ddb_input *input) +{ + struct ddb *dev = input->port->dev; + struct i2c_adapter *i2c = &input->port->i2c->adap; + struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; + struct ddb_port *port = input->port; + struct ddb_link *link = &dev->link[port->lnr]; + struct mxl5xx_cfg cfg; + int demod, tuner; + + cfg = mxl5xx; + cfg.fw_priv = link; + dvb->set_input = NULL; + + demod = input->nr; + tuner = demod & 3; + if (fmode == 3) + tuner = 0; + + dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, + demod, tuner, &dvb->set_input); + + if (!dvb->fe) { + dev_err(dev->dev, "No MXL5XX found!\n"); + return -ENODEV; + } + + if (!dvb->set_input) { + dev_err(dev->dev, "No mxl5xx_set_input function pointer!\n"); + return -ENODEV; + } + + if (input->nr < 4) { + lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT); + lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF); + } + lnb_init_fmode(dev, link, fmode); + + dvb->fe->ops.set_voltage = max_set_voltage; + dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage; + dvb->fe->ops.set_tone = max_set_tone; + dvb->diseqc_send_master_cmd = dvb->fe->ops.diseqc_send_master_cmd; + dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd; + dvb->fe->ops.diseqc_send_burst = max_send_burst; + dvb->fe->sec_priv = input; + dvb->input = tuner; + return 0; +} diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.h b/drivers/media/pci/ddbridge/ddbridge-maxs8.h new file mode 100644 index 000000000000..bb8884811a46 --- /dev/null +++ b/drivers/media/pci/ddbridge/ddbridge-maxs8.h @@ -0,0 +1,29 @@ +/* + * ddbridge-maxs8.h: Digital Devices bridge MaxS4/8 support + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 only, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DDBRIDGE_MAXS8_H_ +#define _DDBRIDGE_MAXS8_H_ + +#include "ddbridge.h" + +/******************************************************************************/ + +int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm); +int fe_attach_mxl5xx(struct ddb_input *input); + +#endif /* _DDBRIDGE_MAXS8_H */ diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h index 03a34e1ddadf..9d44f8d3af75 100644 --- a/drivers/media/pci/ddbridge/ddbridge-regs.h +++ b/drivers/media/pci/ddbridge/ddbridge-regs.h @@ -133,3 +133,24 @@ #define CI_BUFFER_SIZE (0x0800) #define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) + +/* ------------------------------------------------------------------------- */ +/* LNB commands (mxl5xx / Max S8) */ + +#define LNB_BASE (0x400) +#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00) + +#define LNB_CMD (7ULL << 0) +#define LNB_CMD_NOP 0 +#define LNB_CMD_INIT 1 +#define LNB_CMD_LOW 3 +#define LNB_CMD_HIGH 4 +#define LNB_CMD_OFF 5 +#define LNB_CMD_DISEQC 6 + +#define LNB_BUSY (1ULL << 4) +#define LNB_TONE (1ULL << 15) + +#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10) +#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14) + diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 6deff529e0ba..91b58eff951c 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -115,6 +115,7 @@ struct ddb_info { #define DDB_NONE 0 #define DDB_OCTOPUS 1 #define DDB_OCTOPUS_CI 2 +#define DDB_OCTOPUS_MAX 5 #define DDB_OCTOPUS_MAX_CT 6 char *name; u32 i2c_mask; @@ -295,6 +296,15 @@ struct ddb_port { #define TS_CAPTURE_LEN (4096) +struct ddb_lnb { + struct mutex lock; + u32 tone; + enum fe_sec_voltage oldvoltage[4]; + u32 voltage[4]; + u32 voltages; + u32 fmode; +}; + struct ddb_link { struct ddb *dev; struct ddb_info *info; @@ -302,6 +312,7 @@ struct ddb_link { u32 regs; spinlock_t lock; struct mutex flash_mutex; + struct ddb_lnb lnb; struct tasklet_struct tasklet; struct ddb_ids ids; -- cgit v1.2.3 From b9a92f62c555a37e5676f695e94616a261f9403e Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 9 Jul 2017 15:42:45 -0400 Subject: media: ddbridge: fix buffer overflow in max_set_input_unlocked() Picked up code parts introduced one smatch error: drivers/media/pci/ddbridge/ddbridge-maxs8.c:163 max_set_input_unlocked() error: buffer overflow 'dev->link[port->lnr].lnb.voltage' 4 <= 255 Fix this by clamping the .lnb.voltage array access to 0-3 by "& 3"'ing dvb->input. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-maxs8.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.c b/drivers/media/pci/ddbridge/ddbridge-maxs8.c index a9dc5f9754da..10716ee8cf59 100644 --- a/drivers/media/pci/ddbridge/ddbridge-maxs8.c +++ b/drivers/media/pci/ddbridge/ddbridge-maxs8.c @@ -187,11 +187,12 @@ static int max_set_input_unlocked(struct dvb_frontend *fe, int in) return -EINVAL; if (dvb->input != in) { u32 bit = (1ULL << input->nr); - u32 obit = dev->link[port->lnr].lnb.voltage[dvb->input] & bit; + u32 obit = + dev->link[port->lnr].lnb.voltage[dvb->input & 3] & bit; - dev->link[port->lnr].lnb.voltage[dvb->input] &= ~bit; + dev->link[port->lnr].lnb.voltage[dvb->input & 3] &= ~bit; dvb->input = in; - dev->link[port->lnr].lnb.voltage[dvb->input] |= obit; + dev->link[port->lnr].lnb.voltage[dvb->input & 3] |= obit; } res = dvb->set_input(fe, in); return res; -- cgit v1.2.3 From f0e72c29fd063aca325afee25a6f9bcc22871837 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:29:14 -0400 Subject: media: dvb-frontends/stv0910: fix FE_HAS_LOCK check order in tune() It should first read the status and then check if FE has lock. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 45d94c3a29f2..e87a3ee6155c 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1581,13 +1581,15 @@ static int tune(struct dvb_frontend *fe, bool re_tune, return r; state->tune_time = jiffies; } - if (*status & FE_HAS_LOCK) - return 0; - *delay = HZ; r = read_status(fe, status); if (r) return r; + + if (*status & FE_HAS_LOCK) + return 0; + *delay = HZ; + return 0; } -- cgit v1.2.3 From 0758ecdbd888289a783d16122dc24be4c5f1c222 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:29:15 -0400 Subject: media: dvb-frontends/stv0910: fix mask for scramblingcode setup The scrambling code has 4 bits. Fix the mask accordingly. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index e87a3ee6155c..d0a8ed36b899 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1021,7 +1021,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p) write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff, (scrambling_code >> 8) & 0xff); write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff, - (scrambling_code >> 16) & 0x07); + (scrambling_code >> 16) & 0x0f); state->cur_scrambling_code = scrambling_code; } -- cgit v1.2.3 From bae7c75b1155eab295fbe0d504e7cc25a57c0223 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:09 -0400 Subject: media: ddbridge: fix gap handling Force gap setting if given by attribute and enable gap for older regmaps. Also, setting a gap value of 128 via sysfs will now disable gap. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index c290d3fecc8d..98a12c644e44 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -336,6 +336,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) if (output->port->gap != 0xffffffff) { flags |= 1; gap = output->port->gap; + max_bitrate = 0; } if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) { *con = 0x10c; @@ -372,6 +373,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) *con |= 0x810; /* 96 MBit/s and gap */ max_bitrate = 96000; } + *con |= 0x10; /* enable gap */ } } if (max_bitrate > 0) { @@ -3203,8 +3205,10 @@ static ssize_t gap_store(struct device *device, struct device_attribute *attr, if (sscanf(buf, "%u\n", &val) != 1) return -EINVAL; - if (val > 20) + if (val > 128) return -EINVAL; + if (val == 128) + val = 0xffffffff; dev->port[num].gap = val; return count; } -- cgit v1.2.3 From 66cc3d98ea6daa64735d6e72737d8eac0b6e5182 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:11 -0400 Subject: media: ddbridge: move device ID table to ddbridge-hw This further cleans up ddbridge-main from hardware-related data and moves the exact card type determination into ddbridge-hw.c:get_ddb_info(), right to the hardware maps/structs. Also, const'ify more structs and pointers. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 8 ++-- drivers/media/pci/ddbridge/ddbridge-hw.c | 65 ++++++++++++++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge-hw.h | 19 +++++++++ drivers/media/pci/ddbridge/ddbridge-main.c | 47 ++++----------------- drivers/media/pci/ddbridge/ddbridge.h | 2 +- 5 files changed, 96 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 98a12c644e44..c80e1d8498d3 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2430,7 +2430,7 @@ static void output_handler(unsigned long data) static struct ddb_regmap *io_regmap(struct ddb_io *io, int link) { - struct ddb_info *info; + const struct ddb_info *info; if (link) info = io->port->dev->link[io->port->lnr].info; @@ -2564,7 +2564,7 @@ void ddb_ports_init(struct ddb *dev) { u32 i, l, p; struct ddb_port *port; - struct ddb_info *info; + const struct ddb_info *info; struct ddb_regmap *rm; for (p = l = 0; l < DDB_MAX_LINK; l++) { @@ -3527,7 +3527,7 @@ static int tempmon_init(struct ddb_link *link, int first_time) static int ddb_init_tempmon(struct ddb_link *link) { - struct ddb_info *info = link->info; + const struct ddb_info *info = link->info; if (!info->tempmon_irq) return 0; @@ -3545,7 +3545,7 @@ static int ddb_init_tempmon(struct ddb_link *link) static int ddb_init_boards(struct ddb *dev) { - struct ddb_info *info; + const struct ddb_info *info; struct ddb_link *link; u32 l; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c index 317dc865e99c..3b208d5bf4ad 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.c +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -17,6 +17,7 @@ */ #include "ddbridge.h" +#include "ddbridge-hw.h" /******************************************************************************/ @@ -309,3 +310,67 @@ const struct ddb_info ddb_s2_48 = { .board_control = 1, .tempmon_irq = 24, }; + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +#define DDB_DEVID(_device, _subdevice, _info) { \ + .vendor = DDVID, \ + .device = _device, \ + .subvendor = DDVID, \ + .subdevice = _subdevice, \ + .info = &_info } + +static const struct ddb_device_id ddb_device_ids[] = { + /* PCIe devices */ + DDB_DEVID(0x0002, 0x0001, ddb_octopus), + DDB_DEVID(0x0003, 0x0001, ddb_octopus), + DDB_DEVID(0x0005, 0x0004, ddb_octopusv3), + DDB_DEVID(0x0003, 0x0002, ddb_octopus_le), + DDB_DEVID(0x0003, 0x0003, ddb_octopus_oem), + DDB_DEVID(0x0003, 0x0010, ddb_octopus_mini), + DDB_DEVID(0x0005, 0x0011, ddb_octopus_mini), + DDB_DEVID(0x0003, 0x0020, ddb_v6), + DDB_DEVID(0x0003, 0x0021, ddb_v6_5), + DDB_DEVID(0x0006, 0x0022, ddb_v7), + DDB_DEVID(0x0006, 0x0024, ddb_v7a), + DDB_DEVID(0x0003, 0x0030, ddb_dvbct), + DDB_DEVID(0x0003, 0xdb03, ddb_satixS2v3), + DDB_DEVID(0x0006, 0x0031, ddb_ctv7), + DDB_DEVID(0x0006, 0x0032, ddb_ctv7), + DDB_DEVID(0x0006, 0x0033, ddb_ctv7), + DDB_DEVID(0x0007, 0x0023, ddb_s2_48), + DDB_DEVID(0x0008, 0x0034, ddb_ct2_8), + DDB_DEVID(0x0008, 0x0035, ddb_c2t2_8), + DDB_DEVID(0x0008, 0x0036, ddb_isdbt_8), + DDB_DEVID(0x0008, 0x0037, ddb_c2t2i_v0_8), + DDB_DEVID(0x0008, 0x0038, ddb_c2t2i_8), + DDB_DEVID(0x0006, 0x0039, ddb_ctv7), + DDB_DEVID(0x0011, 0x0040, ddb_ci), + DDB_DEVID(0x0011, 0x0041, ddb_cis), + DDB_DEVID(0x0012, 0x0042, ddb_ci), + DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro), + DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a), +}; + +/****************************************************************************/ + +const struct ddb_info *get_ddb_info(u16 vendor, u16 device, + u16 subvendor, u16 subdevice) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ddb_device_ids); i++) { + const struct ddb_device_id *id = &ddb_device_ids[i]; + + if (vendor == id->vendor && + device == id->device && + subvendor == id->subvendor && + ((subdevice == id->subdevice) || + (id->subdevice == 0xffff))) + return id->info; + } + + return &ddb_none; +} diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.h b/drivers/media/pci/ddbridge/ddbridge-hw.h index d26cd9c977d8..1a985d0a1a97 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.h +++ b/drivers/media/pci/ddbridge/ddbridge-hw.h @@ -23,6 +23,20 @@ /******************************************************************************/ +#define DDVID 0xdd01 /* Digital Devices Vendor ID */ + +/******************************************************************************/ + +struct ddb_device_id { + u16 vendor; + u16 device; + u16 subvendor; + u16 subdevice; + const struct ddb_info *info; +}; + +/******************************************************************************/ + extern const struct ddb_info ddb_none; extern const struct ddb_info ddb_octopus; extern const struct ddb_info ddb_octopusv3; @@ -53,4 +67,9 @@ extern const struct ddb_info ddb_c2t2i_8; extern const struct ddb_info ddb_s2_48; +/****************************************************************************/ + +const struct ddb_info *get_ddb_info(u16 vendor, u16 device, + u16 subvendor, u16 subdevice); + #endif /* _DDBRIDGE_HW_H */ diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index 3cb6bb265172..ec608c496b69 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -231,10 +231,12 @@ static int ddb_probe(struct pci_dev *pdev, dev->link[0].ids.vendor = id->vendor; dev->link[0].ids.device = id->device; dev->link[0].ids.subvendor = id->subvendor; - dev->link[0].ids.subdevice = id->subdevice; + dev->link[0].ids.subdevice = pdev->subsystem_device; dev->link[0].dev = dev; - dev->link[0].info = (struct ddb_info *) id->driver_data; + dev->link[0].info = get_ddb_info(id->vendor, id->device, + id->subvendor, pdev->subsystem_device); + dev_info(&pdev->dev, "detected %s\n", dev->link[0].info->name); dev->regs_len = pci_resource_len(dev->pdev, 0); @@ -286,46 +288,11 @@ fail: /****************************************************************************/ /****************************************************************************/ -#define DDVID 0xdd01 /* Digital Devices Vendor ID */ - -#define DDB_DEVICE(_device, _subdevice, _driver_data) { \ - PCI_DEVICE_SUB(DDVID, _device, DDVID, _subdevice), \ - .driver_data = (kernel_ulong_t) &_driver_data } - -#define DDB_DEVICE_ANY(_device) { \ - PCI_DEVICE_SUB(DDVID, _device, DDVID, PCI_ANY_ID), \ - .driver_data = (kernel_ulong_t) &ddb_none } +#define DDB_DEVICE_ANY(_device) \ + { PCI_DEVICE_SUB(DDVID, _device, DDVID, PCI_ANY_ID) } static const struct pci_device_id ddb_id_table[] = { - DDB_DEVICE(0x0002, 0x0001, ddb_octopus), - DDB_DEVICE(0x0003, 0x0001, ddb_octopus), - DDB_DEVICE(0x0005, 0x0004, ddb_octopusv3), - DDB_DEVICE(0x0003, 0x0002, ddb_octopus_le), - DDB_DEVICE(0x0003, 0x0003, ddb_octopus_oem), - DDB_DEVICE(0x0003, 0x0010, ddb_octopus_mini), - DDB_DEVICE(0x0005, 0x0011, ddb_octopus_mini), - DDB_DEVICE(0x0003, 0x0020, ddb_v6), - DDB_DEVICE(0x0003, 0x0021, ddb_v6_5), - DDB_DEVICE(0x0006, 0x0022, ddb_v7), - DDB_DEVICE(0x0006, 0x0024, ddb_v7a), - DDB_DEVICE(0x0003, 0x0030, ddb_dvbct), - DDB_DEVICE(0x0003, 0xdb03, ddb_satixS2v3), - DDB_DEVICE(0x0006, 0x0031, ddb_ctv7), - DDB_DEVICE(0x0006, 0x0032, ddb_ctv7), - DDB_DEVICE(0x0006, 0x0033, ddb_ctv7), - DDB_DEVICE(0x0007, 0x0023, ddb_s2_48), - DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8), - DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8), - DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8), - DDB_DEVICE(0x0008, 0x0037, ddb_c2t2i_v0_8), - DDB_DEVICE(0x0008, 0x0038, ddb_c2t2i_8), - DDB_DEVICE(0x0006, 0x0039, ddb_ctv7), - DDB_DEVICE(0x0011, 0x0040, ddb_ci), - DDB_DEVICE(0x0011, 0x0041, ddb_cis), - DDB_DEVICE(0x0012, 0x0042, ddb_ci), - DDB_DEVICE(0x0013, 0x0043, ddb_ci_s2_pro), - DDB_DEVICE(0x0013, 0x0044, ddb_ci_s2_pro_a), - /* in case sub-ids got deleted in flash */ + DDB_DEVICE_ANY(0x0002), DDB_DEVICE_ANY(0x0003), DDB_DEVICE_ANY(0x0005), DDB_DEVICE_ANY(0x0006), diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 91b58eff951c..60fe5ec93f3d 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -307,7 +307,7 @@ struct ddb_lnb { struct ddb_link { struct ddb *dev; - struct ddb_info *info; + const struct ddb_info *info; u32 nr; u32 regs; spinlock_t lock; -- cgit v1.2.3 From 8e4eef225c3e5fc70c1656822dd40cb17ee9d2f6 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:10 -0400 Subject: media: ddbridge: move ddb_unmap(), cleanup modparams adapter_alloc is only used from within ddbridge-core, so move it there, this removes the need for prototyping/referencing the variable. While at it, msi isn't needed outside of ddbridge-main, so don't extref that one aswell. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 18 ++++++++++++++++++ drivers/media/pci/ddbridge/ddbridge-main.c | 20 ++------------------ drivers/media/pci/ddbridge/ddbridge.h | 3 +-- 3 files changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index c80e1d8498d3..5f6367fee586 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -58,10 +58,21 @@ #define DDB_MAX_ADAPTER 64 +/****************************************************************************/ + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +static int adapter_alloc; +module_param(adapter_alloc, int, 0444); +MODULE_PARM_DESC(adapter_alloc, + "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); + +/****************************************************************************/ + DEFINE_MUTEX(redirect_lock); +struct workqueue_struct *ddb_wq; + static struct ddb *ddbs[DDB_MAX_ADAPTER]; /****************************************************************************/ @@ -3612,3 +3623,10 @@ fail: dev_err(dev->dev, "fail1\n"); return -1; } + +void ddb_unmap(struct ddb *dev) +{ + if (dev->regs) + iounmap(dev->regs); + vfree(dev); +} diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c index ec608c496b69..ccac7fe31336 100644 --- a/drivers/media/pci/ddbridge/ddbridge-main.c +++ b/drivers/media/pci/ddbridge/ddbridge-main.c @@ -41,16 +41,11 @@ /****************************************************************************/ /* module parameters */ -int adapter_alloc; -module_param(adapter_alloc, int, 0444); -MODULE_PARM_DESC(adapter_alloc, - "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); - #ifdef CONFIG_PCI_MSI #ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE -int msi = 1; +static int msi = 1; #else -int msi; +static int msi; #endif module_param(msi, int, 0444); #ifdef CONFIG_DVB_DDBRIDGE_MSIENABLE @@ -88,21 +83,10 @@ int stv0910_single; module_param(stv0910_single, int, 0444); MODULE_PARM_DESC(stv0910_single, "use stv0910 cards as single demods"); -/****************************************************************************/ - -struct workqueue_struct *ddb_wq; - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ -static void ddb_unmap(struct ddb *dev) -{ - if (dev->regs) - iounmap(dev->regs); - vfree(dev); -} - static void ddb_irq_disable(struct ddb *dev) { ddbwritel(dev, 0, INTERRUPT_ENABLE); diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 60fe5ec93f3d..d890400dc1c3 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -369,8 +369,6 @@ int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len); /****************************************************************************/ /* ddbridge-main.c (modparams) */ -extern int adapter_alloc; -extern int msi; extern int ci_bitrate; extern int ts_loop; extern int xo2_speed; @@ -394,5 +392,6 @@ int ddb_device_create(struct ddb *dev); int ddb_class_create(void); void ddb_class_destroy(void); int ddb_init(struct ddb *dev); +void ddb_unmap(struct ddb *dev); #endif /* DDBRIDGE_H */ -- cgit v1.2.3 From ae30a0dbdb5781231c28299be6d48a6443574f02 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:12 -0400 Subject: media: ddbridge: remove ddb_info's from the global scope Since the DD hardware info and maps aren't needed anymore outside of ddbridge-hw.c (they're returned via get_ddb_info() now), mark them static and remove all refs from ddbridge-hw.h. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-hw.c | 46 ++++++++++++++++---------------- drivers/media/pci/ddbridge/ddbridge-hw.h | 32 ---------------------- 2 files changed, 23 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c index 3b208d5bf4ad..1c25e86c189e 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.c +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -87,13 +87,13 @@ static struct ddb_regmap octopus_map = { /****************************************************************************/ -const struct ddb_info ddb_none = { +static const struct ddb_info ddb_none = { .type = DDB_NONE, .name = "unknown Digital Devices PCIe card, install newer driver", .regmap = &octopus_map, }; -const struct ddb_info ddb_octopus = { +static const struct ddb_info ddb_octopus = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus DVB adapter", .regmap = &octopus_map, @@ -101,7 +101,7 @@ const struct ddb_info ddb_octopus = { .i2c_mask = 0x0f, }; -const struct ddb_info ddb_octopusv3 = { +static const struct ddb_info ddb_octopusv3 = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus V3 DVB adapter", .regmap = &octopus_map, @@ -109,7 +109,7 @@ const struct ddb_info ddb_octopusv3 = { .i2c_mask = 0x0f, }; -const struct ddb_info ddb_octopus_le = { +static const struct ddb_info ddb_octopus_le = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus LE DVB adapter", .regmap = &octopus_map, @@ -117,7 +117,7 @@ const struct ddb_info ddb_octopus_le = { .i2c_mask = 0x03, }; -const struct ddb_info ddb_octopus_oem = { +static const struct ddb_info ddb_octopus_oem = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus OEM", .regmap = &octopus_map, @@ -129,7 +129,7 @@ const struct ddb_info ddb_octopus_oem = { .temp_bus = 0, }; -const struct ddb_info ddb_octopus_mini = { +static const struct ddb_info ddb_octopus_mini = { .type = DDB_OCTOPUS, .name = "Digital Devices Octopus Mini", .regmap = &octopus_map, @@ -137,7 +137,7 @@ const struct ddb_info ddb_octopus_mini = { .i2c_mask = 0x0f, }; -const struct ddb_info ddb_v6 = { +static const struct ddb_info ddb_v6 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V6 DVB adapter", .regmap = &octopus_map, @@ -145,7 +145,7 @@ const struct ddb_info ddb_v6 = { .i2c_mask = 0x07, }; -const struct ddb_info ddb_v6_5 = { +static const struct ddb_info ddb_v6_5 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V6.5 DVB adapter", .regmap = &octopus_map, @@ -153,7 +153,7 @@ const struct ddb_info ddb_v6_5 = { .i2c_mask = 0x0f, }; -const struct ddb_info ddb_v7 = { +static const struct ddb_info ddb_v7 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V7 DVB adapter", .regmap = &octopus_map, @@ -164,7 +164,7 @@ const struct ddb_info ddb_v7 = { .ts_quirks = TS_QUIRK_REVERSED, }; -const struct ddb_info ddb_v7a = { +static const struct ddb_info ddb_v7a = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", .regmap = &octopus_map, @@ -175,7 +175,7 @@ const struct ddb_info ddb_v7a = { .ts_quirks = TS_QUIRK_REVERSED, }; -const struct ddb_info ddb_ctv7 = { +static const struct ddb_info ddb_ctv7 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine CT V7 DVB adapter", .regmap = &octopus_map, @@ -185,7 +185,7 @@ const struct ddb_info ddb_ctv7 = { .board_control_2 = 4, }; -const struct ddb_info ddb_satixS2v3 = { +static const struct ddb_info ddb_satixS2v3 = { .type = DDB_OCTOPUS, .name = "Mystique SaTiX-S2 V3 DVB adapter", .regmap = &octopus_map, @@ -193,7 +193,7 @@ const struct ddb_info ddb_satixS2v3 = { .i2c_mask = 0x07, }; -const struct ddb_info ddb_ci = { +static const struct ddb_info ddb_ci = { .type = DDB_OCTOPUS_CI, .name = "Digital Devices Octopus CI", .regmap = &octopus_map, @@ -201,7 +201,7 @@ const struct ddb_info ddb_ci = { .i2c_mask = 0x03, }; -const struct ddb_info ddb_cis = { +static const struct ddb_info ddb_cis = { .type = DDB_OCTOPUS_CI, .name = "Digital Devices Octopus CI single", .regmap = &octopus_map, @@ -209,7 +209,7 @@ const struct ddb_info ddb_cis = { .i2c_mask = 0x03, }; -const struct ddb_info ddb_ci_s2_pro = { +static const struct ddb_info ddb_ci_s2_pro = { .type = DDB_OCTOPUS_CI, .name = "Digital Devices Octopus CI S2 Pro", .regmap = &octopus_map, @@ -219,7 +219,7 @@ const struct ddb_info ddb_ci_s2_pro = { .board_control_2 = 4, }; -const struct ddb_info ddb_ci_s2_pro_a = { +static const struct ddb_info ddb_ci_s2_pro_a = { .type = DDB_OCTOPUS_CI, .name = "Digital Devices Octopus CI S2 Pro Advanced", .regmap = &octopus_map, @@ -229,7 +229,7 @@ const struct ddb_info ddb_ci_s2_pro_a = { .board_control_2 = 4, }; -const struct ddb_info ddb_dvbct = { +static const struct ddb_info ddb_dvbct = { .type = DDB_OCTOPUS, .name = "Digital Devices DVBCT V6.1 DVB adapter", .regmap = &octopus_map, @@ -239,7 +239,7 @@ const struct ddb_info ddb_dvbct = { /****************************************************************************/ -const struct ddb_info ddb_ct2_8 = { +static const struct ddb_info ddb_ct2_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 CT2", .regmap = &octopus_map, @@ -251,7 +251,7 @@ const struct ddb_info ddb_ct2_8 = { .tempmon_irq = 24, }; -const struct ddb_info ddb_c2t2_8 = { +static const struct ddb_info ddb_c2t2_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2", .regmap = &octopus_map, @@ -263,7 +263,7 @@ const struct ddb_info ddb_c2t2_8 = { .tempmon_irq = 24, }; -const struct ddb_info ddb_isdbt_8 = { +static const struct ddb_info ddb_isdbt_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 ISDBT", .regmap = &octopus_map, @@ -275,7 +275,7 @@ const struct ddb_info ddb_isdbt_8 = { .tempmon_irq = 24, }; -const struct ddb_info ddb_c2t2i_v0_8 = { +static const struct ddb_info ddb_c2t2i_v0_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2I V0", .regmap = &octopus_map, @@ -287,7 +287,7 @@ const struct ddb_info ddb_c2t2i_v0_8 = { .tempmon_irq = 24, }; -const struct ddb_info ddb_c2t2i_8 = { +static const struct ddb_info ddb_c2t2i_8 = { .type = DDB_OCTOPUS_MAX_CT, .name = "Digital Devices MAX A8 C2T2I", .regmap = &octopus_map, @@ -301,7 +301,7 @@ const struct ddb_info ddb_c2t2i_8 = { /****************************************************************************/ -const struct ddb_info ddb_s2_48 = { +static const struct ddb_info ddb_s2_48 = { .type = DDB_OCTOPUS_MAX, .name = "Digital Devices MAX S8 4/8", .regmap = &octopus_map, diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.h b/drivers/media/pci/ddbridge/ddbridge-hw.h index 1a985d0a1a97..7c142419419c 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.h +++ b/drivers/media/pci/ddbridge/ddbridge-hw.h @@ -37,38 +37,6 @@ struct ddb_device_id { /******************************************************************************/ -extern const struct ddb_info ddb_none; -extern const struct ddb_info ddb_octopus; -extern const struct ddb_info ddb_octopusv3; -extern const struct ddb_info ddb_octopus_le; -extern const struct ddb_info ddb_octopus_oem; -extern const struct ddb_info ddb_octopus_mini; -extern const struct ddb_info ddb_v6; -extern const struct ddb_info ddb_v6_5; -extern const struct ddb_info ddb_v7; -extern const struct ddb_info ddb_v7a; -extern const struct ddb_info ddb_ctv7; -extern const struct ddb_info ddb_satixS2v3; -extern const struct ddb_info ddb_ci; -extern const struct ddb_info ddb_cis; -extern const struct ddb_info ddb_ci_s2_pro; -extern const struct ddb_info ddb_ci_s2_pro_a; -extern const struct ddb_info ddb_dvbct; - -/****************************************************************************/ - -extern const struct ddb_info ddb_ct2_8; -extern const struct ddb_info ddb_c2t2_8; -extern const struct ddb_info ddb_isdbt_8; -extern const struct ddb_info ddb_c2t2i_v0_8; -extern const struct ddb_info ddb_c2t2i_8; - -/****************************************************************************/ - -extern const struct ddb_info ddb_s2_48; - -/****************************************************************************/ - const struct ddb_info *get_ddb_info(u16 vendor, u16 device, u16 subvendor, u16 subdevice); -- cgit v1.2.3 From 4f376d54aa7fed072100663aaa73c1b65c14fd19 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:14 -0400 Subject: media: ddbridge: bump version string to 0.9.31intermediate-integrated Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index d890400dc1c3..f10683678217 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -63,7 +63,7 @@ #include "dvb_ca_en50221.h" #include "dvb_net.h" -#define DDBRIDGE_VERSION "0.9.29-integrated" +#define DDBRIDGE_VERSION "0.9.31intermediate-integrated" #define DDB_MAX_I2C 32 #define DDB_MAX_PORT 32 -- cgit v1.2.3 From 0937e7e712074cc09b9d148f5fbf148717e0c3eb Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 06:41:13 -0400 Subject: media: ddbridge: const'ify all ddb_info, ddb_regmap et al All data is accessed RO, so mark everything const. Some vars in several functions aswell as function signatures also require the const keyword now, they're also added by this commit. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 14 +++++++------- drivers/media/pci/ddbridge/ddbridge-hw.c | 18 +++++++++--------- drivers/media/pci/ddbridge/ddbridge-i2c.c | 5 +++-- drivers/media/pci/ddbridge/ddbridge.h | 20 ++++++++++---------- 4 files changed, 29 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 5f6367fee586..a14031ac45cf 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -2439,7 +2439,7 @@ static void output_handler(unsigned long data) /****************************************************************************/ /****************************************************************************/ -static struct ddb_regmap *io_regmap(struct ddb_io *io, int link) +static const struct ddb_regmap *io_regmap(struct ddb_io *io, int link) { const struct ddb_info *info; @@ -2457,7 +2457,7 @@ static struct ddb_regmap *io_regmap(struct ddb_io *io, int link) static void ddb_dma_init(struct ddb_io *io, int nr, int out) { struct ddb_dma *dma; - struct ddb_regmap *rm = io_regmap(io, 0); + const struct ddb_regmap *rm = io_regmap(io, 0); dma = out ? &io->port->dev->odma[nr] : &io->port->dev->idma[nr]; io->dma = dma; @@ -2488,7 +2488,7 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) { struct ddb *dev = port->dev; struct ddb_input *input = &dev->input[anr]; - struct ddb_regmap *rm; + const struct ddb_regmap *rm; port->input[pnr] = input; input->nr = nr; @@ -2500,7 +2500,7 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) port->lnr, nr, input->regs); if (dev->has_dma) { - struct ddb_regmap *rm0 = io_regmap(input, 0); + const struct ddb_regmap *rm0 = io_regmap(input, 0); u32 base = rm0->irq_base_idma; u32 dma_nr = nr; @@ -2520,7 +2520,7 @@ static void ddb_output_init(struct ddb_port *port, int nr) { struct ddb *dev = port->dev; struct ddb_output *output = &dev->output[nr]; - struct ddb_regmap *rm; + const struct ddb_regmap *rm; port->output = output; output->nr = nr; @@ -2533,7 +2533,7 @@ static void ddb_output_init(struct ddb_port *port, int nr) port->lnr, nr, output->regs); if (dev->has_dma) { - struct ddb_regmap *rm0 = io_regmap(output, 0); + const struct ddb_regmap *rm0 = io_regmap(output, 0); u32 base = rm0->irq_base_odma; dev->handler[0][nr + base] = output_handler; @@ -2576,7 +2576,7 @@ void ddb_ports_init(struct ddb *dev) u32 i, l, p; struct ddb_port *port; const struct ddb_info *info; - struct ddb_regmap *rm; + const struct ddb_regmap *rm; for (p = l = 0; l < DDB_MAX_LINK; l++) { info = dev->link[l].info; diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c index 1c25e86c189e..48248bcd59c2 100644 --- a/drivers/media/pci/ddbridge/ddbridge-hw.c +++ b/drivers/media/pci/ddbridge/ddbridge-hw.c @@ -21,49 +21,49 @@ /******************************************************************************/ -static struct ddb_regset octopus_input = { +static const struct ddb_regset octopus_input = { .base = 0x200, .num = 0x08, .size = 0x10, }; -static struct ddb_regset octopus_output = { +static const struct ddb_regset octopus_output = { .base = 0x280, .num = 0x08, .size = 0x10, }; -static struct ddb_regset octopus_idma = { +static const struct ddb_regset octopus_idma = { .base = 0x300, .num = 0x08, .size = 0x10, }; -static struct ddb_regset octopus_idma_buf = { +static const struct ddb_regset octopus_idma_buf = { .base = 0x2000, .num = 0x08, .size = 0x100, }; -static struct ddb_regset octopus_odma = { +static const struct ddb_regset octopus_odma = { .base = 0x380, .num = 0x04, .size = 0x10, }; -static struct ddb_regset octopus_odma_buf = { +static const struct ddb_regset octopus_odma_buf = { .base = 0x2800, .num = 0x04, .size = 0x100, }; -static struct ddb_regset octopus_i2c = { +static const struct ddb_regset octopus_i2c = { .base = 0x80, .num = 0x04, .size = 0x20, }; -static struct ddb_regset octopus_i2c_buf = { +static const struct ddb_regset octopus_i2c_buf = { .base = 0x1000, .num = 0x04, .size = 0x200, @@ -71,7 +71,7 @@ static struct ddb_regset octopus_i2c_buf = { /****************************************************************************/ -static struct ddb_regmap octopus_map = { +static const struct ddb_regmap octopus_map = { .irq_base_i2c = 0, .irq_base_idma = 8, .irq_base_odma = 16, diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c index 3d4fafb5db27..e4d39c3270ae 100644 --- a/drivers/media/pci/ddbridge/ddbridge-i2c.c +++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c @@ -155,7 +155,8 @@ static void i2c_handler(unsigned long priv) } static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, - struct ddb_regmap *regmap, int link, int i, int num) + const struct ddb_regmap *regmap, int link, + int i, int num) { struct i2c_adapter *adap; @@ -196,7 +197,7 @@ int ddb_i2c_init(struct ddb *dev) u32 i, j, num = 0, l, base; struct ddb_i2c *i2c; struct i2c_adapter *adap; - struct ddb_regmap *regmap; + const struct ddb_regmap *regmap; for (l = 0; l < DDB_MAX_LINK; l++) { if (!dev->link[l].info) diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index f10683678217..e9afa96bd9df 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h @@ -85,17 +85,17 @@ struct ddb_regmap { u32 irq_base_idma; u32 irq_base_odma; - struct ddb_regset *i2c; - struct ddb_regset *i2c_buf; - struct ddb_regset *idma; - struct ddb_regset *idma_buf; - struct ddb_regset *odma; - struct ddb_regset *odma_buf; + const struct ddb_regset *i2c; + const struct ddb_regset *i2c_buf; + const struct ddb_regset *idma; + const struct ddb_regset *idma_buf; + const struct ddb_regset *odma; + const struct ddb_regset *odma_buf; - struct ddb_regset *input; - struct ddb_regset *output; + const struct ddb_regset *input; + const struct ddb_regset *output; - struct ddb_regset *channel; + const struct ddb_regset *channel; }; struct ddb_ids { @@ -133,7 +133,7 @@ struct ddb_info { #define TS_QUIRK_REVERSED 2 #define TS_QUIRK_ALT_OSC 8 u32 tempmon_irq; - struct ddb_regmap *regmap; + const struct ddb_regmap *regmap; }; /* DMA_SIZE MUST be smaller than 256k and -- cgit v1.2.3 From e6db389d8040c23c2bdb0c99a8d7b83222a4a010 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Aug 2017 13:15:12 -0400 Subject: media: ddbridge: constify stv0910_p and lnbh25_cfg These structures are only copied into other structures, so they can be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index a14031ac45cf..fb378cd9893d 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1152,14 +1152,14 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) return 0; } -static struct stv0910_cfg stv0910_p = { +static const struct stv0910_cfg stv0910_p = { .adr = 0x68, .parallel = 1, .rptlvl = 4, .clk = 30000000, }; -static struct lnbh25_config lnbh25_cfg = { +static const struct lnbh25_config lnbh25_cfg = { .i2c_address = 0x0c << 1, .data2_config = LNBH25_TEN }; -- cgit v1.2.3 From 381a28be485f66e70c5296963caf9c116bdef42c Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 23 Jul 2017 10:45:09 -0400 Subject: media: dvb-frontends/cxd2841er: update moddesc wrt new chip support Since the driver now recognizes and supports more chip variants, reflect this fact in the module description accordingly. Signed-off-by: Daniel Scheller Acked-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cxd2841er.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index 0ab1fc845927..48ee9bc00c06 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -3999,6 +3999,6 @@ static struct dvb_frontend_ops cxd2841er_t_c_ops = { .get_frontend_algo = cxd2841er_get_algo }; -MODULE_DESCRIPTION("Sony CXD2841ER/CXD2854ER DVB-C/C2/T/T2/S/S2 demodulator driver"); +MODULE_DESCRIPTION("Sony CXD2837/38/41/43/54ER DVB-C/C2/T/T2/S/S2 demodulator driver"); MODULE_AUTHOR("Sergey Kozlov , Abylay Ospan "); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 89cd4d229fe9afe93283a1d5325bc1a7127f6a76 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Aug 2017 07:45:41 -0400 Subject: media: ddbridge: get rid of fall though gcc 7.1 warnings drivers/media/pci/ddbridge/ddbridge-core.c: In function 'ddb_port_attach': drivers/media/pci/ddbridge/ddbridge-core.c:2261:6: warning: this statement may fall through [-Wimplicit-fallthrough=] if (ret < 0) ^ drivers/media/pci/ddbridge/ddbridge-core.c:2263:2: note: here case DDB_PORT_LOOP: ^~~~ drivers/media/pci/ddbridge/ddbridge-core.c: In function 'dvb_input_attach': drivers/media/pci/ddbridge/ddbridge-core.c:1492:6: warning: this statement may fall through [-Wimplicit-fallthrough=] if (input->port->dev->link[input->port->lnr].info->ts_quirks & ^ drivers/media/pci/ddbridge/ddbridge-core.c:1497:2: note: here case DDB_TUNER_DVBCT2_SONY_P: ^~~~ drivers/media/pci/ddbridge/ddbridge-core.c:1516:9: warning: this statement may fall through [-Wimplicit-fallthrough=] osc24 = 1; ~~~~~~^~~ drivers/media/pci/ddbridge/ddbridge-core.c:1517:2: note: here case DDB_TUNER_DVBCT2_SONY: ^~~~ Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index fb378cd9893d..2464bde1c432 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1494,6 +1494,7 @@ static int dvb_input_attach(struct ddb_input *input) osc24 = 0; else osc24 = 1; + /* fall-through */ case DDB_TUNER_DVBCT2_SONY_P: case DDB_TUNER_DVBC2T2_SONY_P: case DDB_TUNER_ISDBT_SONY_P: @@ -1514,6 +1515,7 @@ static int dvb_input_attach(struct ddb_input *input) break; case DDB_TUNER_DVBC2T2I_SONY: osc24 = 1; + /* fall-through */ case DDB_TUNER_DVBCT2_SONY: case DDB_TUNER_DVBC2T2_SONY: case DDB_TUNER_ISDBT_SONY: @@ -2260,6 +2262,7 @@ static int ddb_port_attach(struct ddb_port *port) ret = ddb_ci_attach(port); if (ret < 0) break; + /* fall-through */ case DDB_PORT_LOOP: ret = dvb_register_device(port->dvb[0].adap, &port->dvb[0].dev, -- cgit v1.2.3 From 65d5c96dd8c1c87003a073f3d0dd67ac09d28766 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Fri, 11 Aug 2017 07:50:00 -0400 Subject: media: s5p-jpeg: don't overwrite result's "size" member Originally the "size" member was modified in a local variable passed to s5p_jpeg_parse_hdr() but the member was not used by the caller, so it did not matter. After applying patch "media: s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue" the unnecessary assignment started overwriting already assigned "size" member of the passed structure with an incorrect value. Fixes: 14a2de14dc0619bf9 ("media: s5p-jpeg: Don't use temporary structure in s5p_jpeg_buf_queue") Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 4cef4b8c6584..c00e3a19d7f5 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1264,7 +1264,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, } result->sof = sof; result->sof_len = sof_len; - result->size = result->components = components; + result->components = components; return true; } -- cgit v1.2.3 From 19dc3e08663767545181e32d4386d2bf3fd13ef8 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Fri, 11 Aug 2017 07:50:01 -0400 Subject: media: s5p-jpeg: set w/h when encoding q_data w/h must be set when encoding. Fixes: 1c84e7f9d5dc596be (media: s5p-jpeg: Add support for resolution change event) Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index c00e3a19d7f5..e1babb88b7b7 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -1634,6 +1634,12 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE; q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); + if (ct->mode == S5P_JPEG_ENCODE || + (ct->mode == S5P_JPEG_DECODE && + q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)) { + q_data->w = pix->width; + q_data->h = pix->height; + } if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { /* * During encoding Exynos4x12 SoCs access wider memory area @@ -1641,8 +1647,6 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu * page fault calculate proper buffer size in such a case. */ - q_data->w = pix->width; - q_data->h = pix->height; if (ct->jpeg->variant->hw_ex4_compat && f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE) q_data->size = exynos4_jpeg_get_output_buffer_size(ct, -- cgit v1.2.3 From e28e6f75667d68cd36f1ef312c3d988795fee331 Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Tue, 8 Aug 2017 07:27:04 -0400 Subject: media: s5p-jpeg: Fix crash in jpeg isr due to multiple interrupts In case of corrupt images, multiple interrupts may occur due to different error scenarios. Since we are removing the src and dest buffers in the first interrupt itself, crash occurs in the second error interrupts. Disable the global interrupt before we start processing the interrupt to avoid the crash. Disable System interrupt in isr to avoid the crash below. Unable to handle kernel NULL pointer dereference at virtual address 000000c8 pgd = ffffffc0007db000 [000000c8] *pgd=00000000fb006003, *pud=00000000fb006003, *pmd=00000000fb007003, *pte=0060000011001707 Internal error: Oops: 96000007 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-next-20141210+ #22 Hardware name: Samsung Exynos7 Espresso board based on EXYNOS7 (DT) task: ffffffc00075e5c0 ti: ffffffc00074c000 task.ti: ffffffc00074c000 PC is at exynos4_jpeg_irq+0x30/0x15c LR is at exynos4_jpeg_irq+0x2c/0x15c pc : [] lr : [] pstate: 800001c5 sp : ffffffc00074fc60 x29: ffffffc00074fc60 x28: 0000004040000000 x27: ffffffc000673928 x26: ffffffc000673940 x25: ffffffc0007a030c x24: ffffffc0bb20a400 x23: 0000000000000030 x22: ffffffc0ba56ba40 x21: 0000000000000000 x20: 0000000000000000 x19: ffffffc0ba56ba18 x18: 0000000000000000 x17: 0000000000000000 x16: ffffffc00018b508 x15: 0000000000000000 x14: 0000000000000000 x13: 0098968000000000 x12: 0000000000989680 x11: 0000000000000004 x10: 0101010101010101 x9 : 00000020a285a9ea x8 : ffffffc0007af880 x7 : ffffffc0bac001a8 x6 : ffffffc0bac00000 x5 : 00000000fffffffa x4 : ffffffc00040870c x3 : 0000000000000003 x2 : 0000000000010003 x1 : 0000000000010002 x0 : 0000000000000000 Process swapper/0 (pid: 0, stack limit = 0xffffffc00074c058) Stack: (0xffffffc00074fc60 to 0xffffffc000750000) fc60: 0074fca0 ffffffc0 000e4508 ffffffc0 bb225300 ffffffc0 bb20a494 ffffffc0 fc80: 00000000 00000000 00000000 00000000 00000030 00000000 000f8c6c ffffffc0 fca0: 0074fd00 ffffffc0 000e4644 ffffffc0 bb20a400 ffffffc0 bb20a494 ffffffc0 fcc0: 00776a00 ffffffc0 00670da8 ffffffc0 00000000 00000000 00000001 00000000 fce0: bb008000 ffffffc0 407db000 00000000 00081230 ffffffc0 000e4638 ffffffc0 fd00: 0074fd40 ffffffc0 000e7338 ffffffc0 bb20a400 ffffffc0 bb20a494 ffffffc0 fd20: 00776a00 ffffffc0 000e7280 ffffffc0 bb225300 ffffffc0 000e72e0 ffffffc0 fd40: 0074fd70 ffffffc0 000e3d60 ffffffc0 00000030 00000000 00743000 ffffffc0 fd60: 0066e000 ffffffc0 006c2000 ffffffc0 0074fd90 ffffffc0 000e3e90 ffffffc0 fd80: 007437c8 ffffffc0 000e3e6c ffffffc0 0074fdf0 ffffffc0 00082404 ffffffc0 fda0: 0074fe20 ffffffc0 0075a000 ffffffc0 0000200c ffffff80 00002010 ffffff80 fdc0: 60000145 00000000 00672cc8 ffffffc0 407d9000 00000000 befb9b40 ffffffc0 fde0: 0074fe20 ffffffc0 000001d2 00000000 0074ff40 ffffffc0 00085da8 ffffffc0 fe00: 00758584 ffffffc0 0052c000 ffffffc0 0074ff40 ffffffc0 00087114 ffffffc0 fe20: 00000000 00000000 0074ff50 ffffffc0 0067d760 ffffffc0 befb9adc ffffffc0 fe40: 00000001 00000000 d4414200 00000020 d6a39c00 00000020 007a6a18 ffffffc0 fe60: 0075eb00 ffffffc0 0074fd60 ffffffc0 ffffc185 00000000 00000020 00000000 fe80: 0052d340 ffffffc0 00000030 00000000 fffffffe 0fffffff 00000000 00000000 fea0: 0018b508 ffffffc0 00000000 00000000 00000000 00000000 00758584 ffffffc0 fec0: 0052c000 ffffffc0 006c24e8 ffffffc0 007a030a ffffffc0 00000001 00000000 fee0: 00672cc8 ffffffc0 407d9000 00000000 407db000 00000000 00081230 ffffffc0 ff00: 40000000 00000040 0074ff40 ffffffc0 00087110 ffffffc0 0074ff40 ffffffc0 ff20: 00087114 ffffffc0 60000145 00000000 00758584 ffffffc0 0052c000 ffffffc0 ff40: 0074ff50 ffffffc0 000db568 ffffffc0 0074ff90 ffffffc0 00515fdc ffffffc0 ff60: 00758000 ffffffc0 007a3000 ffffffc0 007a3000 ffffffc0 befc8940 ffffffc0 ff80: 40760000 00000000 40000000 00000000 0074ffb0 ffffffc0 006ff998 ffffffc0 ffa0: 00000002 00000000 006ff988 ffffffc0 00000000 00000000 400826c0 00000000 ffc0: 8f03a688 00000000 00000e11 00000000 48000000 00000000 410fd030 00000000 ffe0: 0072c250 ffffffc0 00000000 00000000 00000000 00000000 00000000 00000000 Call trace: [] exynos4_jpeg_irq+0x30/0x15c [] handle_irq_event_percpu+0x6c/0x160 [] handle_irq_event+0x48/0x78 [] handle_fasteoi_irq+0xe0/0x198 [] generic_handle_irq+0x24/0x40 [] __handle_domain_irq+0x80/0xf0 [] gic_handle_irq+0x30/0x80 Exception stack(0xffffffc00074fe00 to 0xffffffc00074ff20) fe00: 00758584 ffffffc0 0052c000 ffffffc0 0074ff40 ffffffc0 00087114 ffffffc0 fe20: 00000000 00000000 0074ff50 ffffffc0 0067d760 ffffffc0 befb9adc ffffffc0 fe40: 00000001 00000000 d4414200 00000020 d6a39c00 00000020 007a6a18 ffffffc0 fe60: 0075eb00 ffffffc0 0074fd60 ffffffc0 ffffc185 00000000 00000020 00000000 fe80: 0052d340 ffffffc0 00000030 00000000 fffffffe 0fffffff 00000000 00000000 fea0: 0018b508 ffffffc0 00000000 00000000 00000000 00000000 00758584 ffffffc0 fec0: 0052c000 ffffffc0 006c24e8 ffffffc0 007a030a ffffffc0 00000001 00000000 fee0: 00672cc8 ffffffc0 407d9000 00000000 407db000 00000000 00081230 ffffffc0 ff00: 40000000 00000040 0074ff40 ffffffc0 00087110 ffffffc0 0074ff40 ffffffc0 [] el1_irq+0x64/0xd8 [] cpu_startup_entry+0x118/0x168 [] rest_init+0x7c/0x88 [] start_kernel+0x3a8/0x3bc Code: 94045c34 f9406e60 97ffdc74 aa0003f4 (f9406400) ---[ end trace fa6dc0ea2efad21f ]--- Kernel panic - not syncing: Fatal exception in interrupt ---[ end Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Tony K Nadackal Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index e1babb88b7b7..663b79cb14b0 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2303,6 +2303,7 @@ static void exynos4_jpeg_device_run(void *priv) exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size); } + exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1); exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode); spin_unlock_irqrestore(&jpeg->slock, flags); @@ -2755,6 +2756,8 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv) spin_lock(&jpeg->slock); + exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0); + curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); -- cgit v1.2.3 From 630dde63001dc62be7abcc54101a80209ad6ec38 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 8 Aug 2017 07:27:05 -0400 Subject: media: s5p-jpeg: disable encoder/decoder in exynos4-like hardware after use Clearing the bits turns off the encoder/decoder. If the hardware is not turned off after use, at subsequent uses it does not work in a stable manner, resulting in incorrect interrupt status value being read and e.g. erroneous read of compressed bitstream size. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 2 ++ drivers/media/platform/s5p-jpeg/jpeg-core.h | 1 + drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 663b79cb14b0..917c9629f6b2 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2806,6 +2806,8 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv) if (jpeg->variant->version == SJPEG_EXYNOS4) curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs); + exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE); + spin_unlock(&jpeg->slock); v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 9aa26bd1d46d..a46465e10351 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h @@ -63,6 +63,7 @@ #define S5P_JPEG_ENCODE 0 #define S5P_JPEG_DECODE 1 +#define S5P_JPEG_DISABLE -1 #define FMT_TYPE_OUTPUT 0 #define FMT_TYPE_CAPTURE 1 diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c index a1d823ab0c63..c78403368e5b 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c @@ -38,10 +38,13 @@ void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode) writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | EXYNOS4_DEC_MODE, base + EXYNOS4_JPEG_CNTL_REG); - } else {/* encode */ + } else if (mode == S5P_JPEG_ENCODE) {/* encode */ writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | EXYNOS4_ENC_MODE, base + EXYNOS4_JPEG_CNTL_REG); + } else { /* disable both */ + writel(reg & EXYNOS4_ENC_DEC_MODE_MASK, + base + EXYNOS4_JPEG_CNTL_REG); } } -- cgit v1.2.3 From 787d8620912a42b32a72ef241b48466e63d3d266 Mon Sep 17 00:00:00 2001 From: Tony K Nadackal Date: Tue, 8 Aug 2017 07:27:06 -0400 Subject: media: s5p-jpeg: Clear JPEG_CODEC_ON bits in sw reset function Bits EXYNOS4_DEC_MODE and EXYNOS4_ENC_MODE do not get cleared on software reset. These bits need to be cleared explicitly. Even though the bits in question are already cleared in interrupt service routine, the reset should also clear them in case when e.g. bootloader uses the codec and leaves it in a bad state. [Updated commit message] Signed-off-by: Tony K Nadackal Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c index c78403368e5b..c72789bae6ed 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c @@ -20,6 +20,10 @@ void exynos4_jpeg_sw_reset(void __iomem *base) { unsigned int reg; + reg = readl(base + EXYNOS4_JPEG_CNTL_REG); + writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE), + base + EXYNOS4_JPEG_CNTL_REG); + reg = readl(base + EXYNOS4_JPEG_CNTL_REG); writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); -- cgit v1.2.3 From 6c83c1d8e7058a22840b22f54f3b1acad2c2207c Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 8 Aug 2017 07:27:07 -0400 Subject: media: s5p-jpeg: fix number of components macro The value to be processed must be first masked and then shifted, not the other way round. Fixes: 6c96dbbc2aa9f5b4a ("[media] s5p-jpeg: add support for 5433") Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h index 1870400468b2..df790b10140c 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h @@ -371,7 +371,7 @@ #define EXYNOS4_NF_SHIFT 16 #define EXYNOS4_NF_MASK 0xff #define EXYNOS4_NF(x) \ - (((x) << EXYNOS4_NF_SHIFT) & EXYNOS4_NF_MASK) + (((x) & EXYNOS4_NF_MASK) << EXYNOS4_NF_SHIFT) /* JPEG quantizer table register */ #define EXYNOS4_QTBL_CONTENT(n) (0x100 + (n) * 0x40) -- cgit v1.2.3 From 4d7be605e0998e1e7a6151028f1ddbb83cbe8fdb Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 8 Aug 2017 07:27:08 -0400 Subject: media: s5p-jpeg: directly use parsed subsampling on exynos5433 On exynos5433 variant JPEG data is parsed by hardware only from SOS marker, so subsampling is parsed by software. As such, its value need not to be translated from hardware-specific encoding to V4L2 encoding. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 917c9629f6b2..faac8161b683 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -628,11 +628,12 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) return V4L2_JPEG_CHROMA_SUBSAMPLING_411; return exynos3250_decoded_subsampling[ctx->subsampling]; case SJPEG_EXYNOS4: - case SJPEG_EXYNOS5433: WARN_ON(ctx->subsampling > 3); if (ctx->subsampling > 2) return V4L2_JPEG_CHROMA_SUBSAMPLING_420; return exynos4x12_decoded_subsampling[ctx->subsampling]; + case SJPEG_EXYNOS5433: + return ctx->subsampling; /* parsed from header */ default: WARN_ON(ctx->subsampling > 3); return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; -- cgit v1.2.3 From c236323dfc876be3c45ec3176813e253d713f237 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 5 Aug 2017 06:47:09 -0400 Subject: media: davinci: vpbe: constify vb2_ops structures These vb2_ops structures are only stored in the ops field of a vb2_queue structure, which is declared as const. Thus the vb2_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index ca2adfa565f6..13d027031ff0 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -355,7 +355,7 @@ static void vpbe_stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&disp->dma_queue_lock, flags); } -static struct vb2_ops video_qops = { +static const struct vb2_ops video_qops = { .queue_setup = vpbe_buffer_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, -- cgit v1.2.3 From 22f438889f5edc873dbd4181e75acc6a04c2c689 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 5 Aug 2017 06:47:10 -0400 Subject: media: staging: media: davinci_vpfe: constify vb2_ops structures These vb2_ops structures are only stored in the ops field of a vb2_queue structure, which is declared as const. Thus the vb2_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/davinci_vpfe/vpfe_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 8b2117ee0f60..155e8c758e4b 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1304,7 +1304,7 @@ static void vpfe_buf_cleanup(struct vb2_buffer *vb) list_del_init(&buf->list); } -static struct vb2_ops video_qops = { +static const struct vb2_ops video_qops = { .queue_setup = vpfe_buffer_queue_setup, .buf_init = vpfe_buffer_init, .buf_prepare = vpfe_buffer_prepare, -- cgit v1.2.3 From ea3b08cdb1adf05cf3ab83deb6b6035c79c0d015 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 5 Aug 2017 06:47:11 -0400 Subject: media: blackfin: bfin_capture: constify vb2_ops structures These vb2_ops structures are only stored in the ops field of a vb2_queue structure, which is declared as const. Thus the vb2_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/blackfin/bfin_capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 294d696c4a3b..41f179117fb0 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c @@ -375,7 +375,7 @@ static void bcap_stop_streaming(struct vb2_queue *vq) } } -static struct vb2_ops bcap_video_qops = { +static const struct vb2_ops bcap_video_qops = { .queue_setup = bcap_queue_setup, .buf_prepare = bcap_buffer_prepare, .buf_cleanup = bcap_buffer_cleanup, -- cgit v1.2.3 From 00f992af585b6e0ec0aa2f173b480a42ada80869 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 5 Aug 2017 06:47:13 -0400 Subject: media: imx: capture: constify vb2_ops structures These vb2_ops structures are only stored in the ops field of a vb2_queue structure, which is declared as const. Thus the vb2_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct vb2_ops i@p = { ... }; @ok@ identifier r.i; struct vb2_queue e; position p; @@ e.ops = &i@p; @bad@ position p != {r.p,ok.p}; identifier r.i; struct vb2_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct vb2_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-media-capture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index ddab4c249da2..ea145bafb880 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c @@ -62,7 +62,7 @@ struct capture_priv { /* In bytes, per queue */ #define VID_MEM_LIMIT SZ_64M -static struct vb2_ops capture_qops; +static const struct vb2_ops capture_qops; /* * Video ioctls follow @@ -503,7 +503,7 @@ static void capture_stop_streaming(struct vb2_queue *vq) spin_unlock_irqrestore(&priv->q_lock, flags); } -static struct vb2_ops capture_qops = { +static const struct vb2_ops capture_qops = { .queue_setup = capture_queue_setup, .buf_init = capture_buf_init, .buf_prepare = capture_buf_prepare, -- cgit v1.2.3 From 8751ac288ee46c9e17d05245f4b8fe10a72bbe61 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:10 -0400 Subject: media: st-delta: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/delta/delta-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c index ff9850ea3ed7..b2dc3d223a9c 100644 --- a/drivers/media/platform/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/sti/delta/delta-v4l2.c @@ -1095,7 +1095,7 @@ static int delta_job_ready(void *priv) } /* mem-to-mem ops */ -static struct v4l2_m2m_ops delta_m2m_ops = { +static const struct v4l2_m2m_ops delta_m2m_ops = { .device_run = delta_device_run, .job_ready = delta_job_ready, .job_abort = delta_job_abort, -- cgit v1.2.3 From 42f310d385b88eab5337cb62bd1d345643106175 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:11 -0400 Subject: media: ti-vpe: vpe: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/vpe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index c47151495b6f..2873c225e5d6 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2430,7 +2430,7 @@ static struct video_device vpe_videodev = { .vfl_dir = VFL_DIR_M2M, }; -static struct v4l2_m2m_ops m2m_ops = { +static const struct v4l2_m2m_ops m2m_ops = { .device_run = device_run, .job_ready = job_ready, .job_abort = job_abort, -- cgit v1.2.3 From 65d371af81aefedc55124621a4664d0d66d0b585 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:12 -0400 Subject: media: s5p-g2d: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Reviewed-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-g2d/g2d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 81ed5cd5cd5d..bd655b564f54 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -611,7 +611,7 @@ static struct video_device g2d_videodev = { .vfl_dir = VFL_DIR_M2M, }; -static struct v4l2_m2m_ops g2d_m2m_ops = { +static const struct v4l2_m2m_ops g2d_m2m_ops = { .device_run = device_run, .job_abort = job_abort, }; -- cgit v1.2.3 From 69215373a631de2fba89b7b4398de103a82c4f80 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:13 -0400 Subject: media: V4L2: platform: rcar_jpu: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Acked-by: Ulyanov Mikhail Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_jpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c index d1746ecc645d..070bac36d766 100644 --- a/drivers/media/platform/rcar_jpu.c +++ b/drivers/media/platform/rcar_jpu.c @@ -1506,7 +1506,7 @@ static void jpu_job_abort(void *priv) jpu_cleanup(ctx, true); } -static struct v4l2_m2m_ops jpu_m2m_ops = { +static const struct v4l2_m2m_ops jpu_m2m_ops = { .device_run = jpu_device_run, .job_ready = jpu_job_ready, .job_abort = jpu_job_abort, -- cgit v1.2.3 From 5003a83139be0d4226717ed1d960234516043c86 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:14 -0400 Subject: media: vcodec: mediatek: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Acked-by: Rick Chang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index f17a86b2f917..226f90886484 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -865,7 +865,7 @@ static void mtk_jpeg_job_abort(void *priv) { } -static struct v4l2_m2m_ops mtk_jpeg_m2m_ops = { +static const struct v4l2_m2m_ops mtk_jpeg_m2m_ops = { .device_run = mtk_jpeg_device_run, .job_ready = mtk_jpeg_job_ready, .job_abort = mtk_jpeg_job_abort, -- cgit v1.2.3 From 729ce68c3e41dd92a5938410a282acce14e3f8c9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:15 -0400 Subject: media: exynos-gsc: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Reviewed-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index 33611a46ce35..2a2994ef15d5 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -747,7 +747,7 @@ static const struct v4l2_file_operations gsc_m2m_fops = { .mmap = gsc_m2m_mmap, }; -static struct v4l2_m2m_ops gsc_m2m_ops = { +static const struct v4l2_m2m_ops gsc_m2m_ops = { .device_run = gsc_m2m_device_run, .job_abort = gsc_m2m_job_abort, }; -- cgit v1.2.3 From fdd488dffd598ef831a781446f8d56e68f0dcd37 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:16 -0400 Subject: media: bdisp: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 7918b928f058..939da6da7644 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -360,7 +360,7 @@ out: bdisp_job_finish(ctx, VB2_BUF_STATE_ERROR); } -static struct v4l2_m2m_ops bdisp_m2m_ops = { +static const struct v4l2_m2m_ops bdisp_m2m_ops = { .device_run = bdisp_device_run, .job_abort = bdisp_job_abort, }; -- cgit v1.2.3 From 92afad2d145873481eb5eb395d0c9e43bdec2a04 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:17 -0400 Subject: media: m2m-deinterlace: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/m2m-deinterlace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index 980066b8d32a..98f6db27b97e 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -988,7 +988,7 @@ static struct video_device deinterlace_videodev = { .vfl_dir = VFL_DIR_M2M, }; -static struct v4l2_m2m_ops m2m_ops = { +static const struct v4l2_m2m_ops m2m_ops = { .device_run = deinterlace_device_run, .job_ready = deinterlace_job_ready, .job_abort = deinterlace_job_abort, -- cgit v1.2.3 From c3f6ddfe88d15f507f9d7a9a808600b039c9d456 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:18 -0400 Subject: media: mx2-emmaprp: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mx2_emmaprp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 03e47e0f778d..7fd209e51140 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -882,7 +882,7 @@ static struct video_device emmaprp_videodev = { .vfl_dir = VFL_DIR_M2M, }; -static struct v4l2_m2m_ops m2m_ops = { +static const struct v4l2_m2m_ops m2m_ops = { .device_run = emmaprp_device_run, .job_abort = emmaprp_job_abort, .lock = emmaprp_lock, -- cgit v1.2.3 From 86ab0b1c42b735bf6ae273ffba7b423dcc0c6de4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:19 -0400 Subject: media: vim2m: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vim2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 970b9b6dab25..afbaa35ab205 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -983,7 +983,7 @@ static struct video_device vim2m_videodev = { .release = video_device_release_empty, }; -static struct v4l2_m2m_ops m2m_ops = { +static const struct v4l2_m2m_ops m2m_ops = { .device_run = device_run, .job_ready = job_ready, .job_abort = job_abort, -- cgit v1.2.3 From 040ffe12e88afd1b7cb01bae7f77efb959a52c2f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:20 -0400 Subject: media: exynos4-is: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Reviewed-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-m2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index d8724fe9e9da..9027d0b0d2bd 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -704,7 +704,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct v4l2_m2m_ops m2m_ops = { +static const struct v4l2_m2m_ops m2m_ops = { .device_run = fimc_device_run, .job_abort = fimc_job_abort, }; -- cgit v1.2.3 From 46014f61daf81581da1440dbe6be9173f8bb8588 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 6 Aug 2017 04:25:21 -0400 Subject: media: mtk-mdp: constify v4l2_m2m_ops structures The v4l2_m2m_ops structures are only passed as the only argument to v4l2_m2m_init, which is declared as const. Thus the v4l2_m2m_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct v4l2_m2m_ops i@p = { ... }; @ok1@ identifier r.i; position p; @@ v4l2_m2m_init(&i@p) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct v4l2_m2m_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct v4l2_m2m_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index 3038d62ba735..583d47724ee8 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -1225,7 +1225,7 @@ static const struct v4l2_file_operations mtk_mdp_m2m_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct v4l2_m2m_ops mtk_mdp_m2m_ops = { +static const struct v4l2_m2m_ops mtk_mdp_m2m_ops = { .device_run = mtk_mdp_m2m_device_run, .job_abort = mtk_mdp_m2m_job_abort, }; -- cgit v1.2.3 From ebf7a6488eed7544dc53c757133663a465bb812d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 06:58:28 -0400 Subject: media: vimc: constify video_subdev structures These structures are all only stored in fields of v4l2_subdev_ops structures, all of which are const, so these structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vimc/vimc-debayer.c | 2 +- drivers/media/platform/vimc/vimc-scaler.c | 2 +- drivers/media/platform/vimc/vimc-sensor.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 033a131f67af..4d663e89d33f 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -373,7 +373,7 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static struct v4l2_subdev_video_ops vimc_deb_video_ops = { +static const struct v4l2_subdev_video_ops vimc_deb_video_ops = { .s_stream = vimc_deb_s_stream, }; diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index 0a3e086e12f3..e1602e0bc230 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -267,7 +267,7 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static struct v4l2_subdev_video_ops vimc_sca_video_ops = { +static const struct v4l2_subdev_video_ops vimc_sca_video_ops = { .s_stream = vimc_sca_s_stream, }; diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 615c2b18dcfc..02e68c8fc02b 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -282,7 +282,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static struct v4l2_subdev_video_ops vimc_sen_video_ops = { +static const struct v4l2_subdev_video_ops vimc_sen_video_ops = { .s_stream = vimc_sen_s_stream, }; -- cgit v1.2.3 From a3b215ea6000c108133784702e24d0b79d4d7a01 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 06:58:31 -0400 Subject: media: exynos4-is: constify video_subdev structures The v4l2_subdev_ops structures are only passed as the second argument of v4l2_subdev_init, which is const, so the v4l2_subdev_ops structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-isp.c | 2 +- drivers/media/platform/exynos4-is/fimc-lite.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 8efe9160ab34..fd793d3ac072 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -433,7 +433,7 @@ static const struct v4l2_subdev_core_ops fimc_is_core_ops = { .s_power = fimc_isp_subdev_s_power, }; -static struct v4l2_subdev_ops fimc_is_subdev_ops = { +static const struct v4l2_subdev_ops fimc_is_subdev_ops = { .core = &fimc_is_core_ops, .video = &fimc_is_subdev_video_ops, .pad = &fimc_is_subdev_pad_ops, diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 7d3ec5cc6608..30282c512e23 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1361,7 +1361,7 @@ static const struct v4l2_subdev_core_ops fimc_lite_core_ops = { .log_status = fimc_lite_log_status, }; -static struct v4l2_subdev_ops fimc_lite_subdev_ops = { +static const struct v4l2_subdev_ops fimc_lite_subdev_ops = { .core = &fimc_lite_core_ops, .video = &fimc_lite_subdev_video_ops, .pad = &fimc_lite_subdev_pad_ops, -- cgit v1.2.3 From 7fb2e072d41b1da5ddf29a1ba62f0e380d94a855 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 13 Aug 2017 04:54:43 -0400 Subject: media: usb: constify usb_device_id usb_device_id are not supposed to change at runtime. All functions working with usb_device_id provided by work with const usb_device_id. So mark the non-const structs as const. 'drivers/media/usb/b2c2/flexcop-usb.c' Fix checkpatch.pl error: ERROR: space prohibited before open square bracket '['. Signed-off-by: Arvind Yadav Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/airspy/airspy.c | 2 +- drivers/media/usb/as102/as102_usb_drv.c | 2 +- drivers/media/usb/b2c2/flexcop-usb.c | 2 +- drivers/media/usb/cpia2/cpia2_usb.c | 2 +- drivers/media/usb/dvb-usb-v2/az6007.c | 2 +- drivers/media/usb/hackrf/hackrf.c | 2 +- drivers/media/usb/hdpvr/hdpvr-core.c | 2 +- drivers/media/usb/msi2500/msi2500.c | 2 +- drivers/media/usb/s2255/s2255drv.c | 2 +- drivers/media/usb/stk1160/stk1160-core.c | 2 +- drivers/media/usb/stkwebcam/stk-webcam.c | 2 +- drivers/media/usb/tm6000/tm6000-cards.c | 2 +- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 2 +- drivers/media/usb/ttusb-dec/ttusb_dec.c | 2 +- drivers/media/usb/usbtv/usbtv-core.c | 2 +- drivers/media/usb/uvc/uvc_driver.c | 2 +- drivers/media/usb/zr364xx/zr364xx.c | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index 8251942bcd12..07f3f4e7144a 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -1087,7 +1087,7 @@ err_free_mem: } /* USB device ID list */ -static struct usb_device_id airspy_id_table[] = { +static const struct usb_device_id airspy_id_table[] = { { USB_DEVICE(0x1d50, 0x60a1) }, /* AirSpy */ { } }; diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c index 68c3a80ce349..ea57859aee77 100644 --- a/drivers/media/usb/as102/as102_usb_drv.c +++ b/drivers/media/usb/as102/as102_usb_drv.c @@ -33,7 +33,7 @@ static void as102_usb_stop_stream(struct as102_dev_t *dev); static int as102_open(struct inode *inode, struct file *file); static int as102_release(struct inode *inode, struct file *file); -static struct usb_device_id as102_usb_id_table[] = { +static const struct usb_device_id as102_usb_id_table[] = { { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) }, { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) }, { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) }, diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c index 788c73803138..a8f3169e30b3 100644 --- a/drivers/media/usb/b2c2/flexcop-usb.c +++ b/drivers/media/usb/b2c2/flexcop-usb.c @@ -596,7 +596,7 @@ static void flexcop_usb_disconnect(struct usb_interface *intf) info("%s successfully deinitialized and disconnected.", DRIVER_NAME); } -static struct usb_device_id flexcop_usb_table [] = { +static const struct usb_device_id flexcop_usb_table[] = { { USB_DEVICE(0x0af7, 0x0101) }, { } }; diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 1c7e16e5d88b..6089036049d9 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -60,7 +60,7 @@ static int submit_urbs(struct camera_data *cam); static int set_alternate(struct camera_data *cam, unsigned int alt); static int configure_transfer_mode(struct camera_data *cam, unsigned int alt); -static struct usb_device_id cpia2_id_table[] = { +static const struct usb_device_id cpia2_id_table[] = { {USB_DEVICE(0x0553, 0x0100)}, {USB_DEVICE(0x0553, 0x0140)}, {USB_DEVICE(0x0553, 0x0151)}, /* STV0676 */ diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 50c07fe7dacb..72f26300c236 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -933,7 +933,7 @@ static struct dvb_usb_device_properties az6007_cablestar_hdci_props = { } }; -static struct usb_device_id az6007_usb_table[] = { +static const struct usb_device_id az6007_usb_table[] = { {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007, &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)}, {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7, diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index d9a525260511..a41b305c55d4 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c @@ -1545,7 +1545,7 @@ err: } /* USB device ID list */ -static struct usb_device_id hackrf_id_table[] = { +static const struct usb_device_id hackrf_id_table[] = { { USB_DEVICE(0x1d50, 0x6089) }, /* HackRF One */ { } }; diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 15f016ad5b89..dbe29c6c4d8b 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -53,7 +53,7 @@ MODULE_PARM_DESC(boost_audio, "boost the audio signal"); /* table of devices that work with this driver */ -static struct usb_device_id hdpvr_table[] = { +static const struct usb_device_id hdpvr_table[] = { { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) }, { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) }, { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) }, diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index bb3d31e2a0b5..79bfd2dbe649 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -1308,7 +1308,7 @@ err: } /* USB device ID list */ -static struct usb_device_id msi2500_id_table[] = { +static const struct usb_device_id msi2500_id_table[] = { {USB_DEVICE(0x1df7, 0x2500)}, /* Mirics MSi3101 SDR Dongle */ {USB_DEVICE(0x2040, 0xd300)}, /* Hauppauge WinTV 133559 LF */ {} diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 6a88b1dbb3a0..23f606e7cd73 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -381,7 +381,7 @@ MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1"); /* USB device table */ #define USB_SENSORAY_VID 0x1943 -static struct usb_device_id s2255_table[] = { +static const struct usb_device_id s2255_table[] = { {USB_DEVICE(USB_SENSORAY_VID, 0x2255)}, {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/ { } /* Terminating entry */ diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c index c86eb6164713..bea8bbbb84fb 100644 --- a/drivers/media/usb/stk1160/stk1160-core.c +++ b/drivers/media/usb/stk1160/stk1160-core.c @@ -47,7 +47,7 @@ MODULE_AUTHOR("Ezequiel Garcia"); MODULE_DESCRIPTION("STK1160 driver"); /* Devices supported by this driver */ -static struct usb_device_id stk1160_id_table[] = { +static const struct usb_device_id stk1160_id_table[] = { { USB_DEVICE(0x05e1, 0x0408) }, { } }; diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 93330be8cc54..39abb58c65dd 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -55,7 +55,7 @@ MODULE_AUTHOR("Jaime Velasco Juan and Nicolas VIVIEN"); MODULE_DESCRIPTION("Syntek DC1125 webcam driver"); /* Some cameras have audio interfaces, we aren't interested in those */ -static struct usb_device_id stkwebcam_table[] = { +static const struct usb_device_id stkwebcam_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x174f, 0xa311, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(0x05e1, 0x0501, 0xff, 0xff, 0xff) }, { } diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index b293dea6554f..2537643a1808 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c @@ -613,7 +613,7 @@ static struct tm6000_board tm6000_boards[] = { }; /* table of devices that work with this driver */ -static struct usb_device_id tm6000_id_table[] = { +static const struct usb_device_id tm6000_id_table[] = { { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC }, { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC }, { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV }, diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index 22a488d3749d..b842f367249f 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -1795,7 +1795,7 @@ static void ttusb_disconnect(struct usb_interface *intf) dprintk("%s: TTUSB DVB disconnected\n", __func__); } -static struct usb_device_id ttusb_table[] = { +static const struct usb_device_id ttusb_table[] = { {USB_DEVICE(0xb48, 0x1003)}, {USB_DEVICE(0xb48, 0x1004)}, {USB_DEVICE(0xb48, 0x1005)}, diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 01c7e6d4481c..cdefb5dfbbdc 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1791,7 +1791,7 @@ static void ttusb_dec_set_model(struct ttusb_dec *dec, } } -static struct usb_device_id ttusb_dec_table[] = { +static const struct usb_device_id ttusb_dec_table[] = { {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */ /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */ {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */ diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index ceb953be0770..f06f09a0876e 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -142,7 +142,7 @@ static void usbtv_disconnect(struct usb_interface *intf) v4l2_device_put(&usbtv->v4l2_dev); } -static struct usb_device_id usbtv_id_table[] = { +static const struct usb_device_id usbtv_id_table[] = { { USB_DEVICE(0x1b71, 0x3002) }, {} }; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 4f463bf2b877..c6feda8e55d3 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2283,7 +2283,7 @@ MODULE_PARM_DESC(timeout, "Streaming control requests timeout"); * VENDOR_SPEC because they don't announce themselves as UVC devices, even * though they are compliant. */ -static struct usb_device_id uvc_ids[] = { +static const struct usb_device_id uvc_ids[] = { /* LogiLink Wireless Webcam */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index efdcd5bd6a4c..25fa81c631c6 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -93,7 +93,7 @@ MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480"); /* Devices supported by this driver * .driver_info contains the init method used by the camera */ -static struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 }, {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 }, {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 }, -- cgit v1.2.3 From 1ab2234eefe5c6faa7d49ff5d2f21ac4204a8ca8 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 13 Aug 2017 04:54:45 -0400 Subject: media: radio: constify usb_device_id usb_device_id are not supposed to change at runtime. All functions working with usb_device_id provided by work with const usb_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 2 +- drivers/media/radio/radio-keene.c | 2 +- drivers/media/radio/radio-ma901.c | 2 +- drivers/media/radio/radio-mr800.c | 2 +- drivers/media/radio/radio-raremono.c | 2 +- drivers/media/radio/radio-shark.c | 2 +- drivers/media/radio/radio-shark2.c | 2 +- drivers/media/radio/si470x/radio-si470x-usb.c | 2 +- drivers/media/radio/si4713/radio-usb-si4713.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 53bc8c010035..8521bb2825e8 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -408,7 +408,7 @@ err_reg_dev: return retval; } -static struct usb_device_id usb_dsbr100_device_table[] = { +static const struct usb_device_id usb_dsbr100_device_table[] = { { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, { } /* Terminating entry */ }; diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index 53a7c2e87762..f2ea8bc5f5ee 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c @@ -45,7 +45,7 @@ MODULE_LICENSE("GPL"); #define FREQ_MUL 16000U /* USB Device ID List */ -static struct usb_device_id usb_keene_device_table[] = { +static const struct usb_device_id usb_keene_device_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR, USB_KEENE_PRODUCT, USB_CLASS_HID, 0, 0) }, { } /* Terminating entry */ diff --git a/drivers/media/radio/radio-ma901.c b/drivers/media/radio/radio-ma901.c index c2010a905a47..fdc481257efd 100644 --- a/drivers/media/radio/radio-ma901.c +++ b/drivers/media/radio/radio-ma901.c @@ -444,7 +444,7 @@ err: } /* USB Device ID List */ -static struct usb_device_id usb_ma901radio_device_table[] = { +static const struct usb_device_id usb_ma901radio_device_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(USB_MA901_VENDOR, USB_MA901_PRODUCT, USB_CLASS_HID, 0, 0) }, { } /* Terminating entry */ diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 95c12532e87a..c9f59129af79 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -587,7 +587,7 @@ err: } /* USB Device ID List */ -static struct usb_device_id usb_amradio_device_table[] = { +static const struct usb_device_id usb_amradio_device_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT, USB_CLASS_HID, 0, 0) }, { } /* Terminating entry */ diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c index bfb3a6d051ba..3c0a22a54113 100644 --- a/drivers/media/radio/radio-raremono.c +++ b/drivers/media/radio/radio-raremono.c @@ -58,7 +58,7 @@ MODULE_LICENSE("GPL v2"); */ /* USB Device ID List */ -static struct usb_device_id usb_raremono_device_table[] = { +static const struct usb_device_id usb_raremono_device_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, { } /* Terminating entry */ }; diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index 23971f5502a8..22f3466af2b1 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c @@ -392,7 +392,7 @@ static int usb_shark_resume(struct usb_interface *intf) #endif /* Specify the bcdDevice value, as the radioSHARK and radioSHARK2 share ids */ -static struct usb_device_id usb_shark_device_table[] = { +static const struct usb_device_id usb_shark_device_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION | USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = 0x077d, diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index b50638ec5f09..4d1a4b3d669c 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c @@ -358,7 +358,7 @@ static int usb_shark_resume(struct usb_interface *intf) #endif /* Specify the bcdDevice value, as the radioSHARK and radioSHARK2 share ids */ -static struct usb_device_id usb_shark_device_table[] = { +static const struct usb_device_id usb_shark_device_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION | USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = 0x077d, diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 571f29a34bf8..c311f9951d80 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -38,7 +38,7 @@ /* USB Device ID List */ -static struct usb_device_id si470x_usb_driver_id_table[] = { +static const struct usb_device_id si470x_usb_driver_id_table[] = { /* Silicon Labs USB FM Radio Reference Design */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c index e5e5a1672bdb..febc9c1e78ff 100644 --- a/drivers/media/radio/si4713/radio-usb-si4713.c +++ b/drivers/media/radio/si4713/radio-usb-si4713.c @@ -49,7 +49,7 @@ MODULE_LICENSE("GPL v2"); #define USB_RESP_TIMEOUT 50000 /* USB Device ID List */ -static struct usb_device_id usb_si4713_usb_device_table[] = { +static const struct usb_device_id usb_si4713_usb_device_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_SI4713_VENDOR, USB_SI4713_PRODUCT, USB_CLASS_HID, 0, 0) }, { } /* Terminating entry */ -- cgit v1.2.3 From 38c4f03acf92cc6845064f509bdb27c4af2618ea Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sun, 13 Aug 2017 08:43:08 -0400 Subject: media: usb: make snd_pcm_hardware const Make these const as they are only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-audio.c | 2 +- drivers/media/usb/em28xx/em28xx-audio.c | 2 +- drivers/media/usb/go7007/snd-go7007.c | 2 +- drivers/media/usb/tm6000/tm6000-alsa.c | 2 +- drivers/media/usb/usbtv/usbtv-audio.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index a050d125934c..06f10d7fc4b0 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -403,7 +403,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, return 0; } -static struct snd_pcm_hardware snd_cx231xx_hw_capture = { +static const struct snd_pcm_hardware snd_cx231xx_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index ffad7f1af166..261620a57420 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -216,7 +216,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, return 0; } -static struct snd_pcm_hardware snd_em28xx_hw_capture = { +static const struct snd_pcm_hardware snd_em28xx_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index 070871fb1fc4..c618764480c6 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -52,7 +52,7 @@ struct go7007_snd { int capturing; }; -static struct snd_pcm_hardware go7007_snd_capture_hw = { +static const struct snd_pcm_hardware go7007_snd_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c index 422322541af6..3717a6844ea8 100644 --- a/drivers/media/usb/tm6000/tm6000-alsa.c +++ b/drivers/media/usb/tm6000/tm6000-alsa.c @@ -143,7 +143,7 @@ static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size) */ #define DEFAULT_FIFO_SIZE 4096 -static struct snd_pcm_hardware snd_tm6000_digital_hw = { +static const struct snd_pcm_hardware snd_tm6000_digital_hw = { .info = SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c index 9db31db7d9ac..2c2ca77fa01f 100644 --- a/drivers/media/usb/usbtv/usbtv-audio.c +++ b/drivers/media/usb/usbtv/usbtv-audio.c @@ -43,7 +43,7 @@ #include "usbtv.h" -static struct snd_pcm_hardware snd_usbtv_digital_hw = { +static const struct snd_pcm_hardware snd_usbtv_digital_hw = { .info = SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | -- cgit v1.2.3 From 47f14314b33107d72560fee93bb69e1374c010ab Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sun, 13 Aug 2017 08:43:09 -0400 Subject: media: pci: make snd_pcm_hardware const Make these const as they are only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-alsa-pcm.c | 4 ++-- drivers/media/pci/cx18/cx18-alsa-pcm.c | 2 +- drivers/media/pci/cx23885/cx23885-alsa.c | 2 +- drivers/media/pci/cx25821/cx25821-alsa.c | 2 +- drivers/media/pci/ivtv/ivtv-alsa-pcm.c | 2 +- drivers/media/pci/saa7134/saa7134-alsa.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cobalt/cobalt-alsa-pcm.c b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c index 49013c6b8646..b69b258d39b9 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa-pcm.c +++ b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c @@ -43,7 +43,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm"); pr_info("cobalt-alsa-pcm %s: " fmt, __func__, ##arg); \ } while (0) -static struct snd_pcm_hardware snd_cobalt_hdmi_capture = { +static const struct snd_pcm_hardware snd_cobalt_hdmi_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -64,7 +64,7 @@ static struct snd_pcm_hardware snd_cobalt_hdmi_capture = { .periods_max = 4, }; -static struct snd_pcm_hardware snd_cobalt_playback = { +static const struct snd_pcm_hardware snd_cobalt_playback = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c index f68ee57a9ae2..aadd76466aec 100644 --- a/drivers/media/pci/cx18/cx18-alsa-pcm.c +++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c @@ -44,7 +44,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm"); __func__, ##arg); \ } while (0) -static struct snd_pcm_hardware snd_cx18_hw_capture = { +static const struct snd_pcm_hardware snd_cx18_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index c148f9a4a9ac..d8c3637e492e 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -293,7 +293,7 @@ static int dsp_buffer_free(struct cx23885_audio_dev *chip) */ #define DEFAULT_FIFO_SIZE 4096 -static struct snd_pcm_hardware snd_cx23885_digital_hw = { +static const struct snd_pcm_hardware snd_cx23885_digital_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 519b81c0c837..2b34990e86f2 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -428,7 +428,7 @@ static int dsp_buffer_free(struct cx25821_audio_dev *chip) * Digital hardware definition */ #define DEFAULT_FIFO_SIZE 384 -static struct snd_pcm_hardware snd_cx25821_digital_hw = { +static const struct snd_pcm_hardware snd_cx25821_digital_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c index 417d03da01f0..5326d86fa375 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c @@ -41,7 +41,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm"); pr_info("ivtv-alsa-pcm %s: " fmt, __func__, ##arg); \ } while (0) -static struct snd_pcm_hardware snd_ivtv_hw_capture = { +static const struct snd_pcm_hardware snd_ivtv_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index bf358ec7aca5..c59b69f1af9d 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -627,7 +627,7 @@ snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream) * switching to 32kHz without any frequency translation */ -static struct snd_pcm_hardware snd_card_saa7134_capture = +static const struct snd_pcm_hardware snd_card_saa7134_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | -- cgit v1.2.3 From 92a6882eefda0ee34b9dfc029ee2ed2e91fac277 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sun, 13 Aug 2017 08:43:13 -0400 Subject: media: tuners: make snd_pcm_hardware const Make these const as they are only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/tuners/tda18271-maps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/tuners/tda18271-maps.c b/drivers/media/tuners/tda18271-maps.c index 7d114677b4ca..9679804fd219 100644 --- a/drivers/media/tuners/tda18271-maps.c +++ b/drivers/media/tuners/tda18271-maps.c @@ -1182,7 +1182,7 @@ fail: /*---------------------------------------------------------------------*/ -static struct tda18271_std_map tda18271c1_std_map = { +static const struct tda18271_std_map tda18271c1_std_map = { .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0, .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */ .atv_b = { .if_freq = 6750, .fm_rfn = 0, .agc_mode = 1, .std = 6, @@ -1215,7 +1215,7 @@ static struct tda18271_std_map tda18271c1_std_map = { .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */ }; -static struct tda18271_std_map tda18271c2_std_map = { +static const struct tda18271_std_map tda18271c2_std_map = { .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0, .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */ .atv_b = { .if_freq = 6000, .fm_rfn = 0, .agc_mode = 1, .std = 5, -- cgit v1.2.3 From 8728bddf4bf591517bc1c36854ce0fcb94392fa4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Aug 2017 01:43:56 -0400 Subject: media: v4l2: av7110_v4l: constify v4l2_audio structure This v4l2_audio structure is only copied into other structures, so it can be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/av7110_v4l.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/av7110_v4l.c b/drivers/media/pci/ttpci/av7110_v4l.c index 397fe146dedd..e4cf42c32284 100644 --- a/drivers/media/pci/ttpci/av7110_v4l.c +++ b/drivers/media/pci/ttpci/av7110_v4l.c @@ -218,7 +218,7 @@ static struct saa7146_standard analog_standard[]; static struct saa7146_standard dvb_standard[]; static struct saa7146_standard standard[]; -static struct v4l2_audio msp3400_v4l2_audio = { +static const struct v4l2_audio msp3400_v4l2_audio = { .index = 0, .name = "Television", .capability = V4L2_AUDCAP_STEREO -- cgit v1.2.3 From 2c1630c66b3bcce2e3da530f9a692e548678203a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 14 Aug 2017 01:58:37 -0400 Subject: media: pxa_camera: constify v4l2_clk_ops structure This v4l2_clk_ops structure is only passed as the first argument of v4l2_clk_register, which is const, so the v4l2_clk_ops structure can also be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/pxa_camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 0d4af6d91ffc..4a800a4147ca 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2100,7 +2100,7 @@ static const struct v4l2_ioctl_ops pxa_camera_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct v4l2_clk_ops pxa_camera_mclk_ops = { +static const struct v4l2_clk_ops pxa_camera_mclk_ops = { }; static const struct video_device pxa_camera_videodev_template = { -- cgit v1.2.3 From 6688324841d9fdc53bdb0aef88ab6352a7185513 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 4 Aug 2017 08:09:44 -0400 Subject: media: cx18: constify videobuf_queue_ops structures These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,&i@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-streams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 3c45e0071530..81d06c1a7796 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -240,7 +240,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) list_add_tail(&buf->vb.queue, &s->vb_capture); } -static struct videobuf_queue_ops cx18_videobuf_qops = { +static const struct videobuf_queue_ops cx18_videobuf_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From 177267a9500c2739d0413706f5a32854322ea9aa Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 4 Aug 2017 08:09:46 -0400 Subject: media: cx231xx: constify videobuf_queue_ops structures These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,&i@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // In the first case, there is a second commented call to videobuf_queue_sg_init with the structure as the second argument. If that code will be uncommented, the const will remain correct, because the second parameter of that function is also const. Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-417.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 8d5eb99deacb..d538fa407742 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1490,7 +1490,7 @@ static void bb_buf_release(struct videobuf_queue *q, free_buffer(q, buf); } -static struct videobuf_queue_ops cx231xx_qops = { +static const struct videobuf_queue_ops cx231xx_qops = { .buf_setup = bb_buf_setup, .buf_prepare = bb_buf_prepare, .buf_queue = bb_buf_queue, diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index f67f86876625..179b8481a870 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -859,7 +859,7 @@ static void buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -static struct videobuf_queue_ops cx231xx_video_qops = { +static const struct videobuf_queue_ops cx231xx_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From 63f2ec67fa3be6df8d89b74f211cfefe1a58829a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 4 Aug 2017 08:09:47 -0400 Subject: media: tm6000: constify videobuf_queue_ops structures These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,&i@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/tm6000/tm6000-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index cec1321289df..ec8c4d2534dc 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -801,7 +801,7 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb free_buffer(vq, buf); } -static struct videobuf_queue_ops tm6000_video_qops = { +static const struct videobuf_queue_ops tm6000_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From d8ad94ed9faf77a169bf7d2d44eaf570a63c0add Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 4 Aug 2017 08:09:48 -0400 Subject: media: zr364xx: constify videobuf_queue_ops structures These videobuf_queue_ops structures are only passed as the second argument to videobuf_queue_vmalloc_init, which is declared as const. Thus the videobuf_queue_ops structures themselves can be const. Done with the help of Coccinelle. // @r disable optional_qualifier@ identifier i; position p; @@ static struct videobuf_queue_ops i@p = { ... }; @ok1@ identifier r.i; expression e1; position p; @@ videobuf_queue_vmalloc_init(e1,&i@p,...) @bad@ position p != {r.p,ok1.p}; identifier r.i; struct videobuf_queue_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct videobuf_queue_ops i = { ... }; // Signed-off-by: Julia Lawall Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/zr364xx/zr364xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 25fa81c631c6..d4bb56baad9b 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -439,7 +439,7 @@ static void buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -static struct videobuf_queue_ops zr364xx_video_qops = { +static const struct videobuf_queue_ops zr364xx_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From da6df1c4dcd8e7306bb3cd34c96e19e629b798c2 Mon Sep 17 00:00:00 2001 From: Jim Lin Date: Tue, 8 Aug 2017 08:56:20 -0400 Subject: media: uvcvideo: Fix incorrect timeout for Get Request Section 9.2.6.4 of USB 2.0/3.x specification describes that "device must be able to return the first data packet to host within 500 ms of receipt of the request. For subsequent data packet, if any, the device must be able to return them within 500 ms". This is to fix incorrect timeout and change it from 300 ms to 500 ms to meet the timing specified by specification for Get Request. Signed-off-by: Jim Lin Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvcvideo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 15e415e32c7f..296b69bb3fb2 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -166,7 +166,7 @@ /* Maximum status buffer size in bytes of interrupt URB. */ #define UVC_MAX_STATUS_SIZE 16 -#define UVC_CTRL_CONTROL_TIMEOUT 300 +#define UVC_CTRL_CONTROL_TIMEOUT 500 #define UVC_CTRL_STREAMING_TIMEOUT 5000 /* Maximum allowed number of control mappings per device */ -- cgit v1.2.3 From 7e09f7d5c790278ab98e5f2c22307ebe8ad6e8ba Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 8 Aug 2017 08:56:21 -0400 Subject: media: uvcvideo: Prevent heap overflow when accessing mapped controls The size of uvc_control_mapping is user controlled leading to a potential heap overflow in the uvc driver. This adds a check to verify the user provided size fits within the bounds of the defined buffer size. Originally-from: Richard Simmons Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_ctrl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index c2ee6e39fd0c..20397aba6849 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2002,6 +2002,13 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, goto done; } + /* Validate the user-provided bit-size and offset */ + if (mapping->size > 32 || + mapping->offset + mapping->size > ctrl->info.size * 8) { + ret = -EINVAL; + goto done; + } + list_for_each_entry(map, &ctrl->info.mappings, list) { if (mapping->id == map->id) { uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " -- cgit v1.2.3 From dfa6f2400c1f0bb2183996ac1c74f1fc859fca32 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 8 Aug 2017 08:56:22 -0400 Subject: media: uvcvideo: Fix .queue_setup() to check the number of planes According to documentation of struct vb2_ops the .queue_setup() callback should return an error if the number of planes parameter contains an invalid value on input. Fix this instead of ignoring the value. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_queue.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index aa2199775cb8..c8d78b2f3de4 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -82,9 +82,14 @@ static int uvc_queue_setup(struct vb2_queue *vq, struct uvc_streaming *stream = uvc_queue_to_stream(queue); unsigned size = stream->ctrl.dwMaxVideoFrameSize; - /* Make sure the image size is large enough. */ + /* + * When called with plane sizes, validate them. The driver supports + * single planar formats only, and requires buffers to be large enough + * to store a complete frame. + */ if (*nplanes) - return sizes[0] < size ? -EINVAL : 0; + return *nplanes != 1 || sizes[0] < size ? -EINVAL : 0; + *nplanes = 1; sizes[0] = size; return 0; -- cgit v1.2.3 From 9d15cd958c172c8b02da6ee28638ccbbf7933175 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 8 Aug 2017 08:56:23 -0400 Subject: media: uvcvideo: Convert from using an atomic variable to a reference count When adding support for metadata nodes, we'll have to keep video devices registered until all metadata nodes are closed too. Since this has nothing to do with stream counting, replace the nstreams atomic variable with a reference counter. Signed-off-by: Guennadi Liakhovetski Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 25 +++++++++---------------- drivers/media/usb/uvc/uvcvideo.h | 2 +- 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index c6feda8e55d3..6d22b22cb35b 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1802,8 +1802,9 @@ static int uvc_scan_device(struct uvc_device *dev) * already been canceled by the USB core. There is no need to kill the * interrupt URB manually. */ -static void uvc_delete(struct uvc_device *dev) +static void uvc_delete(struct kref *kref) { + struct uvc_device *dev = container_of(kref, struct uvc_device, ref); struct list_head *p, *n; uvc_status_cleanup(dev); @@ -1854,11 +1855,7 @@ static void uvc_release(struct video_device *vdev) struct uvc_streaming *stream = video_get_drvdata(vdev); struct uvc_device *dev = stream->dev; - /* Decrement the registered streams count and delete the device when it - * reaches zero. - */ - if (atomic_dec_and_test(&dev->nstreams)) - uvc_delete(dev); + kref_put(&dev->ref, uvc_delete); } /* @@ -1870,10 +1867,10 @@ static void uvc_unregister_video(struct uvc_device *dev) /* Unregistering all video devices might result in uvc_delete() being * called from inside the loop if there's no open file handle. To avoid - * that, increment the stream count before iterating over the streams - * and decrement it when done. + * that, increment the refcount before iterating over the streams and + * decrement it when done. */ - atomic_inc(&dev->nstreams); + kref_get(&dev->ref); list_for_each_entry(stream, &dev->streams, list) { if (!video_is_registered(&stream->vdev)) @@ -1884,11 +1881,7 @@ static void uvc_unregister_video(struct uvc_device *dev) uvc_debugfs_cleanup_stream(stream); } - /* Decrement the stream count and call uvc_delete explicitly if there - * are no stream left. - */ - if (atomic_dec_and_test(&dev->nstreams)) - uvc_delete(dev); + kref_put(&dev->ref, uvc_delete); } static int uvc_register_video(struct uvc_device *dev, @@ -1946,7 +1939,7 @@ static int uvc_register_video(struct uvc_device *dev, else stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; - atomic_inc(&dev->nstreams); + kref_get(&dev->ref); return 0; } @@ -2031,7 +2024,7 @@ static int uvc_probe(struct usb_interface *intf, INIT_LIST_HEAD(&dev->entities); INIT_LIST_HEAD(&dev->chains); INIT_LIST_HEAD(&dev->streams); - atomic_set(&dev->nstreams, 0); + kref_init(&dev->ref); atomic_set(&dev->nmappings, 0); mutex_init(&dev->lock); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 296b69bb3fb2..34c7ee6cc9e5 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -575,7 +575,7 @@ struct uvc_device { /* Video Streaming interfaces */ struct list_head streams; - atomic_t nstreams; + struct kref ref; /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; -- cgit v1.2.3 From 54220790149809fd48dfb999f732b345b7097a1a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 08:56:24 -0400 Subject: media: uvcvideo: Constify video_subdev structures uvc_subdev_ops is only passed as the second argument of v4l2_subdev_init, which is const, so uvc_subdev_ops can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index ac386bb547e6..554063c07d7a 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -61,7 +61,7 @@ static int uvc_mc_create_links(struct uvc_video_chain *chain, return 0; } -static struct v4l2_subdev_ops uvc_subdev_ops = { +static const struct v4l2_subdev_ops uvc_subdev_ops = { }; void uvc_mc_cleanup_entity(struct uvc_entity *entity) -- cgit v1.2.3 From 037e0865c2ecbaa4558feba239ece08d7e457ec0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Aug 2017 07:25:06 -0400 Subject: media: v4l2-compat-ioctl32.c: add capabilities field to, v4l2_input32 The v4l2_input32 struct wasn't updated when this field was added. It didn't cause a failure in the compat code, but it is better to keep it in sync with v4l2_input to avoid confusion. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index af8b4c5b0efa..821f2aa299ae 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -630,7 +630,8 @@ struct v4l2_input32 { __u32 tuner; /* Associated tuner */ compat_u64 std; __u32 status; - __u32 reserved[4]; + __u32 capabilities; + __u32 reserved[3]; }; /* The 64-bit v4l2_input struct has extra padding at the end of the struct. -- cgit v1.2.3 From 583352beda86e31af86c89718e9c6762318017c6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Aug 2017 06:41:53 -0400 Subject: media: s5p-cec: use CEC_CAP_DEFAULTS Use the new CEC_CAP_DEFAULTS define in the s5p-cec driver. Signed-off-by: Hans Verkuil Acked-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-cec/s5p_cec.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c index 8e06071a7977..58d200e7c838 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.c +++ b/drivers/media/platform/s5p-cec/s5p_cec.c @@ -219,11 +219,8 @@ static int s5p_cec_probe(struct platform_device *pdev) if (cec->notifier == NULL) return -ENOMEM; - cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, - CEC_NAME, - CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | - CEC_CAP_PASSTHROUGH | CEC_CAP_RC | - (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1); + cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME, + CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; -- cgit v1.2.3 From 9a6b2a87405a5022660022722d4a830b768e8033 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 15 Aug 2017 15:26:25 -0400 Subject: media: cec: rename pin events/function The CEC_EVENT_PIN_LOW/HIGH defines and the cec_queue_pin_event() function did not specify that these were about CEC pin events. Since in the future there will also be HPD pin events it is wise to rename the event defines and function to CEC_EVENT_PIN_CEC_LOW/HIGH and cec_queue_pin_cec_event() now before these become part of the ABI. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst | 2 +- Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 8 ++++---- Documentation/media/uapi/cec/cec-ioc-g-mode.rst | 2 +- drivers/media/cec/cec-adap.c | 7 ++++--- drivers/media/cec/cec-api.c | 4 ++-- drivers/media/cec/cec-pin.c | 5 +++-- include/media/cec.h | 9 +++++---- include/uapi/linux/cec.h | 4 ++-- 8 files changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst index 0a7aa21f24f4..6c1f6efb822e 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst @@ -127,7 +127,7 @@ returns the information to the application. The ioctl never fails. - 0x00000080 - The CEC hardware can monitor CEC pin changes from low to high voltage and vice versa. When in pin monitoring mode the application will - receive ``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events. + receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events. diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 766d8b0ce431..db615e3405c0 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -146,16 +146,16 @@ it is guaranteed that the state did change in between the two events. - 2 - Generated if one or more CEC messages were lost because the application didn't dequeue CEC messages fast enough. - * .. _`CEC-EVENT-PIN-LOW`: + * .. _`CEC-EVENT-PIN-CEC-LOW`: - - ``CEC_EVENT_PIN_LOW`` + - ``CEC_EVENT_PIN_CEC_LOW`` - 3 - Generated if the CEC pin goes from a high voltage to a low voltage. Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` capability set. - * .. _`CEC-EVENT-PIN-HIGH`: + * .. _`CEC-EVENT-PIN-CEC-HIGH`: - - ``CEC_EVENT_PIN_HIGH`` + - ``CEC_EVENT_PIN_CEC_HIGH`` - 4 - Generated if the CEC pin goes from a low voltage to a high voltage. Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst index 494154e9d449..4d8e0647e832 100644 --- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst @@ -159,7 +159,7 @@ Available follower modes are: This mode requires that the :ref:`CEC_CAP_MONITOR_PIN ` capability is set, otherwise the ``EINVAL`` error code is returned. While in pin monitoring mode this file descriptor can receive the - ``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events to see the + ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the low-level CEC pin transitions. This is very useful for debugging. This mode is only allowed if the process has the ``CAP_NET_ADMIN`` capability. If that is not set, then the ``EPERM`` error code is returned. diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 8ac39ddf892c..d9adeb505c09 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -154,10 +154,11 @@ static void cec_queue_event(struct cec_adapter *adap, } /* Notify userspace that the CEC pin changed state at the given time. */ -void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts) +void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts) { struct cec_event ev = { - .event = is_high ? CEC_EVENT_PIN_HIGH : CEC_EVENT_PIN_LOW, + .event = is_high ? CEC_EVENT_PIN_CEC_HIGH : + CEC_EVENT_PIN_CEC_LOW, }; struct cec_fh *fh; @@ -167,7 +168,7 @@ void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts) cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); mutex_unlock(&adap->devnode.lock); } -EXPORT_SYMBOL_GPL(cec_queue_pin_event); +EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event); /* * Queue a new message for this filehandle. diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 00d43d74020f..87649b0c6381 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -449,8 +449,8 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, .flags = CEC_EVENT_FL_INITIAL_STATE, }; - ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_HIGH : - CEC_EVENT_PIN_LOW; + ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_CEC_HIGH : + CEC_EVENT_PIN_CEC_LOW; cec_queue_event_fh(fh, &ev, 0); #endif adap->monitor_pin_cnt++; diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 03f800e5ec1f..31a26d3b8bd8 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -609,8 +609,9 @@ static int cec_pin_thread_func(void *_adap) while (atomic_read(&pin->work_pin_events)) { unsigned int idx = pin->work_pin_events_rd; - cec_queue_pin_event(adap, pin->work_pin_is_high[idx], - pin->work_pin_ts[idx]); + cec_queue_pin_cec_event(adap, + pin->work_pin_is_high[idx], + pin->work_pin_ts[idx]); pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; atomic_dec(&pin->work_pin_events); } diff --git a/include/media/cec.h b/include/media/cec.h index 1bec7bde4792..224359c9941a 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -91,7 +91,7 @@ struct cec_event_entry { }; #define CEC_NUM_CORE_EVENTS 2 -#define CEC_NUM_EVENTS CEC_EVENT_PIN_HIGH +#define CEC_NUM_EVENTS CEC_EVENT_PIN_CEC_HIGH struct cec_fh { struct list_head list; @@ -280,14 +280,15 @@ static inline void cec_received_msg(struct cec_adapter *adap, } /** - * cec_queue_pin_event() - queue a pin event with a given timestamp. + * cec_queue_pin_cec_event() - queue a CEC pin event with a given timestamp. * * @adap: pointer to the cec adapter - * @is_high: when true the pin is high, otherwise it is low + * @is_high: when true the CEC pin is high, otherwise it is low * @ts: the timestamp for this event * */ -void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts); +void cec_queue_pin_cec_event(struct cec_adapter *adap, + bool is_high, ktime_t ts); /** * cec_get_edid_phys_addr() - find and return the physical address diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index d87a67b0bb06..4351c3481aea 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -408,8 +408,8 @@ struct cec_log_addrs { * didn't empty the message queue in time */ #define CEC_EVENT_LOST_MSGS 2 -#define CEC_EVENT_PIN_LOW 3 -#define CEC_EVENT_PIN_HIGH 4 +#define CEC_EVENT_PIN_CEC_LOW 3 +#define CEC_EVENT_PIN_CEC_HIGH 4 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) #define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1) -- cgit v1.2.3 From cb7474949371ba8d7591a62924f05b627a2601d9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 16 Aug 2017 03:13:02 -0400 Subject: media: cec-pin: fix irq handling The free_irq() function could be called from interrupt context, which is invalid. Move this to the thread. In the interrupt handler we just request that the thread disables the irq. This is done through an atomic so we don't need to add any spinlocks. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-pin.c | 34 +++++++++++++++++++++------------- include/media/cec-pin.h | 6 +++++- 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 31a26d3b8bd8..970774de3dcd 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -557,7 +557,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) adap->is_configured || adap->monitor_all_cnt) break; /* Switch to interrupt mode */ - pin->work_enable_irq = true; + atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_ENABLE); pin->state = CEC_ST_RX_IRQ; wake_up_interruptible(&pin->kthread_waitq); return HRTIMER_NORESTART; @@ -591,7 +591,7 @@ static int cec_pin_thread_func(void *_adap) kthread_should_stop() || pin->work_rx_msg.len || pin->work_tx_status || - pin->work_enable_irq || + atomic_read(&pin->work_irq_change) || atomic_read(&pin->work_pin_events)); if (pin->work_rx_msg.len) { @@ -606,6 +606,7 @@ static int cec_pin_thread_func(void *_adap) cec_transmit_attempt_done_ts(adap, tx_status, pin->work_tx_ts); } + while (atomic_read(&pin->work_pin_events)) { unsigned int idx = pin->work_pin_events_rd; @@ -615,14 +616,26 @@ static int cec_pin_thread_func(void *_adap) pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; atomic_dec(&pin->work_pin_events); } - if (pin->work_enable_irq) { - pin->work_enable_irq = false; + + switch (atomic_xchg(&pin->work_irq_change, + CEC_PIN_IRQ_UNCHANGED)) { + case CEC_PIN_IRQ_DISABLE: + pin->ops->disable_irq(adap); + cec_pin_high(pin); + cec_pin_to_idle(pin); + hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); + break; + case CEC_PIN_IRQ_ENABLE: pin->enable_irq_failed = !pin->ops->enable_irq(adap); if (pin->enable_irq_failed) { cec_pin_to_idle(pin); hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); } + break; + default: + break; } + if (kthread_should_stop()) break; } @@ -641,7 +654,7 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) cec_pin_to_idle(pin); pin->tx_msg.len = 0; pin->timer_ts = 0; - pin->work_enable_irq = false; + atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); pin->kthread = kthread_run(cec_pin_thread_func, adap, "cec-pin"); if (IS_ERR(pin->kthread)) { @@ -682,7 +695,7 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, pin->work_tx_status = 0; pin->tx_bit = 0; if (pin->state == CEC_ST_RX_IRQ) { - pin->work_enable_irq = false; + atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); pin->ops->disable_irq(adap); cec_pin_high(pin); cec_pin_to_idle(pin); @@ -745,13 +758,8 @@ void cec_pin_changed(struct cec_adapter *adap, bool value) cec_pin_update(pin, value, false); if (!value && (adap->is_configuring || adap->is_configured || - adap->monitor_all_cnt)) { - pin->work_enable_irq = false; - pin->ops->disable_irq(adap); - cec_pin_high(pin); - cec_pin_to_idle(pin); - hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL); - } + adap->monitor_all_cnt)) + atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); } EXPORT_SYMBOL_GPL(cec_pin_changed); diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h index 44b82d29d480..d28d07fa312e 100644 --- a/include/media/cec-pin.h +++ b/include/media/cec-pin.h @@ -113,6 +113,10 @@ struct cec_pin_ops { #define CEC_NUM_PIN_EVENTS 128 +#define CEC_PIN_IRQ_UNCHANGED 0 +#define CEC_PIN_IRQ_DISABLE 1 +#define CEC_PIN_IRQ_ENABLE 2 + struct cec_pin { struct cec_adapter *adap; const struct cec_pin_ops *ops; @@ -137,8 +141,8 @@ struct cec_pin { struct cec_msg work_rx_msg; u8 work_tx_status; - bool work_enable_irq; ktime_t work_tx_ts; + atomic_t work_irq_change; atomic_t work_pin_events; unsigned int work_pin_events_wr; unsigned int work_pin_events_rd; -- cgit v1.2.3 From 9211434bad302be53a2203db4341fabe29db9197 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 28 Feb 2017 06:38:16 -0500 Subject: media: omap3isp: Parse CSI1 configuration from the device tree Add support for parsing CSI1 configuration. Signed-off-by: Pavel Machek Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Reviewed-by: Sebastian Reichel Tested-by: Laurent Pinchart # on Beagleboard-xM + MPT9P031 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 105 +++++++++++++++++++++-------- drivers/media/platform/omap3isp/omap3isp.h | 1 + 2 files changed, 79 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 79aff6b989a1..6cb1f0495804 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2018,6 +2018,7 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint vep; unsigned int i; int ret; + bool csi1 = false; ret = v4l2_fwnode_endpoint_parse(fwnode, &vep); if (ret) @@ -2047,41 +2048,91 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, case ISP_OF_PHY_CSIPHY1: case ISP_OF_PHY_CSIPHY2: - /* FIXME: always assume CSI-2 for now. */ + switch (vep.bus_type) { + case V4L2_MBUS_CCP2: + case V4L2_MBUS_CSI1: + dev_dbg(dev, "CSI-1/CCP-2 configuration\n"); + csi1 = true; + break; + case V4L2_MBUS_CSI2: + dev_dbg(dev, "CSI-2 configuration\n"); + csi1 = false; + break; + default: + dev_err(dev, "unsupported bus type %u\n", + vep.bus_type); + return -EINVAL; + } + switch (vep.base.port) { case ISP_OF_PHY_CSIPHY1: - buscfg->interface = ISP_INTERFACE_CSI2C_PHY1; + if (csi1) + buscfg->interface = ISP_INTERFACE_CCP2B_PHY1; + else + buscfg->interface = ISP_INTERFACE_CSI2C_PHY1; break; case ISP_OF_PHY_CSIPHY2: - buscfg->interface = ISP_INTERFACE_CSI2A_PHY2; + if (csi1) + buscfg->interface = ISP_INTERFACE_CCP2B_PHY2; + else + buscfg->interface = ISP_INTERFACE_CSI2A_PHY2; break; } - buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane; - buscfg->bus.csi2.lanecfg.clk.pol = - vep.bus.mipi_csi2.lane_polarities[0]; - dev_dbg(dev, "clock lane polarity %u, pos %u\n", - buscfg->bus.csi2.lanecfg.clk.pol, - buscfg->bus.csi2.lanecfg.clk.pos); - - buscfg->bus.csi2.num_data_lanes = - vep.bus.mipi_csi2.num_data_lanes; - - for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { - buscfg->bus.csi2.lanecfg.data[i].pos = - vep.bus.mipi_csi2.data_lanes[i]; - buscfg->bus.csi2.lanecfg.data[i].pol = - vep.bus.mipi_csi2.lane_polarities[i + 1]; + if (csi1) { + buscfg->bus.ccp2.lanecfg.clk.pos = + vep.bus.mipi_csi1.clock_lane; + buscfg->bus.ccp2.lanecfg.clk.pol = + vep.bus.mipi_csi1.lane_polarity[0]; + dev_dbg(dev, "clock lane polarity %u, pos %u\n", + buscfg->bus.ccp2.lanecfg.clk.pol, + buscfg->bus.ccp2.lanecfg.clk.pos); + + buscfg->bus.ccp2.lanecfg.data[0].pos = + vep.bus.mipi_csi1.data_lane; + buscfg->bus.ccp2.lanecfg.data[0].pol = + vep.bus.mipi_csi1.lane_polarity[1]; + dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i, - buscfg->bus.csi2.lanecfg.data[i].pol, - buscfg->bus.csi2.lanecfg.data[i].pos); + buscfg->bus.ccp2.lanecfg.data[0].pol, + buscfg->bus.ccp2.lanecfg.data[0].pos); + + buscfg->bus.ccp2.strobe_clk_pol = + vep.bus.mipi_csi1.clock_inv; + buscfg->bus.ccp2.phy_layer = vep.bus.mipi_csi1.strobe; + buscfg->bus.ccp2.ccp2_mode = + vep.bus_type == V4L2_MBUS_CCP2; + buscfg->bus.ccp2.vp_clk_pol = 1; + + buscfg->bus.ccp2.crc = 1; + } else { + buscfg->bus.csi2.lanecfg.clk.pos = + vep.bus.mipi_csi2.clock_lane; + buscfg->bus.csi2.lanecfg.clk.pol = + vep.bus.mipi_csi2.lane_polarities[0]; + dev_dbg(dev, "clock lane polarity %u, pos %u\n", + buscfg->bus.csi2.lanecfg.clk.pol, + buscfg->bus.csi2.lanecfg.clk.pos); + + buscfg->bus.csi2.num_data_lanes = + vep.bus.mipi_csi2.num_data_lanes; + + for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { + buscfg->bus.csi2.lanecfg.data[i].pos = + vep.bus.mipi_csi2.data_lanes[i]; + buscfg->bus.csi2.lanecfg.data[i].pol = + vep.bus.mipi_csi2.lane_polarities[i + 1]; + dev_dbg(dev, + "data lane %u polarity %u, pos %u\n", i, + buscfg->bus.csi2.lanecfg.data[i].pol, + buscfg->bus.csi2.lanecfg.data[i].pos); + } + /* + * FIXME: now we assume the CRC is always there. + * Implement a way to obtain this information from the + * sensor. Frame descriptors, perhaps? + */ + buscfg->bus.csi2.crc = 1; } - - /* - * FIXME: now we assume the CRC is always there. - * Implement a way to obtain this information from the - * sensor. Frame descriptors, perhaps? - */ - buscfg->bus.csi2.crc = 1; break; default: diff --git a/drivers/media/platform/omap3isp/omap3isp.h b/drivers/media/platform/omap3isp/omap3isp.h index dfd3cbe26ccd..9fb4d5bce004 100644 --- a/drivers/media/platform/omap3isp/omap3isp.h +++ b/drivers/media/platform/omap3isp/omap3isp.h @@ -110,6 +110,7 @@ struct isp_ccp2_cfg { unsigned int ccp2_mode:1; unsigned int phy_layer:1; unsigned int vpclk_div:2; + unsigned int vp_clk_pol:1; struct isp_csiphy_lanes_cfg lanecfg; }; -- cgit v1.2.3 From 37a0c6f92cc5edcf47a705ab908d4f9657554396 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 1 Mar 2017 06:45:46 -0500 Subject: media: omap3isp: Correctly set IO_OUT_SEL and VP_CLK_POL for CCP2 mode ISP CSI1 module needs all the bits correctly set to work. Signed-off-by: Ivaylo Dimitrov Signed-off-by: Pavel Machek Signed-off-by: Sakari Ailus Tested-by: Laurent Pinchart # on Beagleboard-xM + MPT9P031 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccp2.c | 7 +++++-- drivers/media/platform/omap3isp/ispreg.h | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 8b6f7d2e79a0..47210b102bcb 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -213,14 +213,17 @@ static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, struct isp_device *isp = to_isp_device(ccp2); u32 val; - /* CCP2B mode */ val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) | - ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; + ISPCCP2_CTRL_MODE; /* Data/strobe physical layer */ BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, buscfg->phy_layer); + BIT_SET(val, ISPCCP2_CTRL_IO_OUT_SEL_SHIFT, + ISPCCP2_CTRL_IO_OUT_SEL_MASK, buscfg->ccp2_mode); BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, buscfg->strobe_clk_pol); + BIT_SET(val, ISPCCP2_CTRL_VP_CLK_POL_SHIFT, + ISPCCP2_CTRL_VP_CLK_POL_MASK, buscfg->vp_clk_pol); isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); diff --git a/drivers/media/platform/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h index b5ea8da0b904..d08483919a77 100644 --- a/drivers/media/platform/omap3isp/ispreg.h +++ b/drivers/media/platform/omap3isp/ispreg.h @@ -87,6 +87,8 @@ #define ISPCCP2_CTRL_PHY_SEL_MASK 0x1 #define ISPCCP2_CTRL_PHY_SEL_SHIFT 1 #define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2) +#define ISPCCP2_CTRL_IO_OUT_SEL_MASK 0x1 +#define ISPCCP2_CTRL_IO_OUT_SEL_SHIFT 2 #define ISPCCP2_CTRL_MODE (1 << 4) #define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9) #define ISPCCP2_CTRL_INV (1 << 10) @@ -94,6 +96,8 @@ #define ISPCCP2_CTRL_INV_SHIFT 10 #define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11) #define ISPCCP2_CTRL_VP_CLK_POL (1 << 12) +#define ISPCCP2_CTRL_VP_CLK_POL_MASK 0x1 +#define ISPCCP2_CTRL_VP_CLK_POL_SHIFT 12 #define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15 #define ISPCCP2_CTRL_VPCLK_DIV_MASK 0x1ffff /* [31:15] */ #define ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT 8 /* 3430 bits */ -- cgit v1.2.3 From 19be9fd67c2574304717559293f717d7d0328842 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sat, 4 Mar 2017 04:55:48 -0500 Subject: media: omap3isp: Always initialise isp and mutex for csiphy1 The PHY is still relevant for CCP2. Signed-off-by: Sakari Ailus Tested-by: Laurent Pinchart # on Beagleboard-xM + MPT9P031 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispcsiphy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index addc6efbb033..2028bb519108 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -345,13 +345,14 @@ int omap3isp_csiphy_init(struct isp_device *isp) phy2->phy_regs = OMAP3_ISP_IOMEM_CSIPHY2; mutex_init(&phy2->mutex); + phy1->isp = isp; + mutex_init(&phy1->mutex); + if (isp->revision == ISP_REVISION_15_0) { - phy1->isp = isp; phy1->csi2 = &isp->isp_csi2c; phy1->num_data_lanes = ISP_CSIPHY1_NUM_DATA_LANES; phy1->cfg_regs = OMAP3_ISP_IOMEM_CSI2C_REGS1; phy1->phy_regs = OMAP3_ISP_IOMEM_CSIPHY1; - mutex_init(&phy1->mutex); } return 0; -- cgit v1.2.3 From 7e1db599b99655af2b2cbeaf14aab1a07d84fc6d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sat, 4 Mar 2017 04:52:40 -0500 Subject: media: omap3isp: csiphy: Don't assume the CSI receiver is a CSI2 module The CSI PHY is associated with a CSI receiver. The code assumes this receiver is a CSI2 module and relies on the CSI2 module object heavily to access the ISP or pipeline objects. However, the receiver could also be a CSI1/CCP2 module. Pass a new CSI receiver entity pointer to the CSI PHY acquire function, and replace all hardcoded usage of the CSI2 module with that CSI receiver entity. Signed-off-by: Sakari Ailus Tested-by: Laurent Pinchart # on Beagleboard-xM + MPT9P031 Acked-by: Pavel Machek Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 4 +-- drivers/media/platform/omap3isp/ispcsiphy.c | 45 +++++++++++++---------------- drivers/media/platform/omap3isp/ispcsiphy.h | 6 ++-- 4 files changed, 27 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 47210b102bcb..3db8df09cd9a 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -841,7 +841,7 @@ static int ccp2_s_stream(struct v4l2_subdev *sd, int enable) switch (enable) { case ISP_PIPELINE_STREAM_CONTINUOUS: if (ccp2->phy) { - ret = omap3isp_csiphy_acquire(ccp2->phy); + ret = omap3isp_csiphy_acquire(ccp2->phy, &sd->entity); if (ret < 0) return ret; } diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 7dae2fe0d42d..3ec37fed710b 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -490,7 +490,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2) if (!csi2->available) return -ENODEV; - if (csi2->phy->phy_in_use) + if (csi2->phy->entity) return -EBUSY; isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG, @@ -1053,7 +1053,7 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable) switch (enable) { case ISP_PIPELINE_STREAM_CONTINUOUS: - if (omap3isp_csiphy_acquire(csi2->phy) < 0) + if (omap3isp_csiphy_acquire(csi2->phy, &sd->entity) < 0) return -ENODEV; if (csi2->output & CSI2_OUTPUT_MEMORY) omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE); diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 2028bb519108..ed1eb9907ae0 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -164,22 +164,17 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power) static int omap3isp_csiphy_config(struct isp_csiphy *phy) { - struct isp_csi2_device *csi2 = phy->csi2; - struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); - struct isp_bus_cfg *buscfg = pipe->external->host_priv; + struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); + struct isp_async_subdev *isd = + container_of(pipe->external->asd, struct isp_async_subdev, asd); + struct isp_bus_cfg *buscfg = pipe->external->host_priv ? + pipe->external->host_priv : &isd->bus; struct isp_csiphy_lanes_cfg *lanes; int csi2_ddrclk_khz; unsigned int num_data_lanes, used_lanes = 0; unsigned int i; u32 reg; - if (!buscfg) { - struct isp_async_subdev *isd = - container_of(pipe->external->asd, - struct isp_async_subdev, asd); - buscfg = &isd->bus; - } - if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1 || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) { lanes = &buscfg->bus.ccp2.lanecfg; @@ -222,7 +217,7 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) csi2_ddrclk_khz = pipe->external_rate / 1000 / (2 * hweight32(used_lanes)) * pipe->external_width; - reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG0); + reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0); reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK | ISPCSIPHY_REG0_THS_SETTLE_MASK); @@ -233,9 +228,9 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) reg |= (DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3) << ISPCSIPHY_REG0_THS_SETTLE_SHIFT; - isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG0); + isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0); - reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG1); + reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1); reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK | ISPCSIPHY_REG1_TCLK_MISS_MASK | @@ -244,10 +239,10 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) reg |= TCLK_MISS << ISPCSIPHY_REG1_TCLK_MISS_SHIFT; reg |= TCLK_SETTLE << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT; - isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG1); + isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1); /* DPHY lane configuration */ - reg = isp_reg_readl(csi2->isp, phy->cfg_regs, ISPCSI2_PHY_CFG); + reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG); for (i = 0; i < num_data_lanes; i++) { reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) | @@ -263,12 +258,12 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) reg |= lanes->clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT; reg |= lanes->clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT; - isp_reg_writel(csi2->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG); + isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG); return 0; } -int omap3isp_csiphy_acquire(struct isp_csiphy *phy) +int omap3isp_csiphy_acquire(struct isp_csiphy *phy, struct media_entity *entity) { int rval; @@ -288,6 +283,8 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy) if (rval < 0) goto done; + phy->entity = entity; + rval = omap3isp_csiphy_config(phy); if (rval < 0) goto done; @@ -301,10 +298,10 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy) csiphy_power_autoswitch_enable(phy, true); } - - phy->phy_in_use = 1; - done: + if (rval < 0) + phy->entity = NULL; + mutex_unlock(&phy->mutex); return rval; } @@ -312,10 +309,8 @@ done: void omap3isp_csiphy_release(struct isp_csiphy *phy) { mutex_lock(&phy->mutex); - if (phy->phy_in_use) { - struct isp_csi2_device *csi2 = phy->csi2; - struct isp_pipeline *pipe = - to_isp_pipeline(&csi2->subdev.entity); + if (phy->entity) { + struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); struct isp_bus_cfg *buscfg = pipe->external->host_priv; csiphy_routing_cfg(phy, buscfg->interface, false, @@ -325,7 +320,7 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); } regulator_disable(phy->vdd); - phy->phy_in_use = 0; + phy->entity = NULL; } mutex_unlock(&phy->mutex); } diff --git a/drivers/media/platform/omap3isp/ispcsiphy.h b/drivers/media/platform/omap3isp/ispcsiphy.h index 978ca5c80a6c..91543a09b28a 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.h +++ b/drivers/media/platform/omap3isp/ispcsiphy.h @@ -25,9 +25,10 @@ struct regulator; struct isp_csiphy { struct isp_device *isp; struct mutex mutex; /* serialize csiphy configuration */ - u8 phy_in_use; struct isp_csi2_device *csi2; struct regulator *vdd; + /* the entity that acquired the phy */ + struct media_entity *entity; /* mem resources - enums as defined in enum isp_mem_resources */ unsigned int cfg_regs; @@ -36,7 +37,8 @@ struct isp_csiphy { u8 num_data_lanes; /* number of CSI2 Data Lanes supported */ }; -int omap3isp_csiphy_acquire(struct isp_csiphy *phy); +int omap3isp_csiphy_acquire(struct isp_csiphy *phy, + struct media_entity *entity); void omap3isp_csiphy_release(struct isp_csiphy *phy); int omap3isp_csiphy_init(struct isp_device *isp); void omap3isp_csiphy_cleanup(struct isp_device *isp); -- cgit v1.2.3 From 02b1ce92301378ea40568ebff9f26036f6331137 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 15 Aug 2017 06:14:23 -0400 Subject: media: omap3isp: Quit using struct v4l2_subdev.host_priv field struct v4l2_subdev.host_priv is intended to be used by another driver. This is hardly good design but back in the days of platform data was a quick hack to get things done. As the sub-device specific bus information can be stored to the ISP driver specific struct allocated along with v4l2_async_subdev, keep the information there and only there. Signed-off-by: Sakari Ailus Tested-by: Laurent Pinchart Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 29 +++++++---------------------- drivers/media/platform/omap3isp/isp.h | 4 +++- drivers/media/platform/omap3isp/ispccdc.c | 16 +++++++++------- drivers/media/platform/omap3isp/ispccp2.c | 3 ++- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/ispcsiphy.c | 8 +++----- 6 files changed, 25 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 6cb1f0495804..c3014c82d64d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2188,26 +2188,12 @@ error: return -EINVAL; } -static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, - struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd) -{ - struct isp_async_subdev *isd = - container_of(asd, struct isp_async_subdev, asd); - - isd->sd = subdev; - isd->sd->host_priv = &isd->bus; - - return 0; -} - static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); struct v4l2_device *v4l2_dev = &isp->v4l2_dev; struct v4l2_subdev *sd; - struct isp_bus_cfg *bus; int ret; ret = media_entity_enum_init(&isp->crashed, &isp->media_dev); @@ -2215,13 +2201,13 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) return ret; list_for_each_entry(sd, &v4l2_dev->subdevs, list) { - /* Only try to link entities whose interface was set on bound */ - if (sd->host_priv) { - bus = (struct isp_bus_cfg *)sd->host_priv; - ret = isp_link_entity(isp, &sd->entity, bus->interface); - if (ret < 0) - return ret; - } + if (!sd->asd) + continue; + + ret = isp_link_entity(isp, &sd->entity, + v4l2_subdev_to_bus_cfg(sd)->interface); + if (ret < 0) + return ret; } ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); @@ -2399,7 +2385,6 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_register_entities; - isp->notifier.bound = isp_subdev_notifier_bound; isp->notifier.complete = isp_subdev_notifier_complete; ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier); diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index 2f2ae609c548..e528df6efc09 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -226,11 +226,13 @@ struct isp_device { }; struct isp_async_subdev { - struct v4l2_subdev *sd; struct isp_bus_cfg bus; struct v4l2_async_subdev asd; }; +#define v4l2_subdev_to_bus_cfg(sd) \ + (&container_of((sd)->asd, struct isp_async_subdev, asd)->bus) + #define v4l2_dev_to_isp_device(dev) \ container_of(dev, struct isp_device, v4l2_dev) diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 4947876cfadf..b66276ab5765 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1139,8 +1139,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); if (ccdc->input == CCDC_INPUT_PARALLEL) { - parcfg = &((struct isp_bus_cfg *)sensor->host_priv) - ->bus.parallel; + struct v4l2_subdev *sd = + to_isp_pipeline(&ccdc->subdev.entity)->external; + + parcfg = &v4l2_subdev_to_bus_cfg(sd)->bus.parallel; ccdc->bt656 = parcfg->bt656; } @@ -2412,11 +2414,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd, /* We've got a parallel sensor here. */ if (ccdc->input == CCDC_INPUT_PARALLEL) { - struct isp_parallel_cfg *parcfg = - &((struct isp_bus_cfg *) - media_entity_to_v4l2_subdev(link->source->entity) - ->host_priv)->bus.parallel; - parallel_shift = parcfg->data_lane_shift; + struct v4l2_subdev *sd = + media_entity_to_v4l2_subdev(link->source->entity); + struct isp_bus_cfg *bus_cfg = v4l2_subdev_to_bus_cfg(sd); + + parallel_shift = bus_cfg->bus.parallel.data_lane_shift; } else { parallel_shift = 0; } diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 3db8df09cd9a..e062939d0d05 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -350,6 +350,7 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2, */ static int ccp2_if_configure(struct isp_ccp2_device *ccp2) { + struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); const struct isp_bus_cfg *buscfg; struct v4l2_mbus_framefmt *format; struct media_pad *pad; @@ -361,7 +362,7 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2) pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); - buscfg = sensor->host_priv; + buscfg = v4l2_subdev_to_bus_cfg(pipe->external); ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2); if (ret < 0) diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 3ec37fed710b..a4d3d030e81e 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -566,7 +566,7 @@ static int csi2_configure(struct isp_csi2_device *csi2) pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity); - buscfg = sensor->host_priv; + buscfg = v4l2_subdev_to_bus_cfg(pipe->external); csi2->frame_skip = 0; v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index ed1eb9907ae0..a28fb79abaac 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c @@ -165,10 +165,7 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power) static int omap3isp_csiphy_config(struct isp_csiphy *phy) { struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); - struct isp_async_subdev *isd = - container_of(pipe->external->asd, struct isp_async_subdev, asd); - struct isp_bus_cfg *buscfg = pipe->external->host_priv ? - pipe->external->host_priv : &isd->bus; + struct isp_bus_cfg *buscfg = v4l2_subdev_to_bus_cfg(pipe->external); struct isp_csiphy_lanes_cfg *lanes; int csi2_ddrclk_khz; unsigned int num_data_lanes, used_lanes = 0; @@ -311,7 +308,8 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) mutex_lock(&phy->mutex); if (phy->entity) { struct isp_pipeline *pipe = to_isp_pipeline(phy->entity); - struct isp_bus_cfg *buscfg = pipe->external->host_priv; + struct isp_bus_cfg *buscfg = + v4l2_subdev_to_bus_cfg(pipe->external); csiphy_routing_cfg(phy, buscfg->interface, false, buscfg->bus.ccp2.phy_layer); -- cgit v1.2.3 From 68d9c47b1679ec8d55a005d39fc7a958ece82095 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Jul 2017 15:28:33 -0400 Subject: media: Convert to using %pOF instead of full_name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: Niklas Söderlund Acked-by: Laurent Pinchart Reviewed-by: Matthias Brugger Acked-by: Nicolas Ferre Acked-by: Lad, Prabhakar Cc: Kyungmin Park Cc: Andrzej Hajda Cc: Mauro Carvalho Chehab Cc: Songjun Wu Cc: Kukjin Kim Cc: Krzysztof Kozlowski Cc: Javier Martinez Canillas Cc: Minghsiu Tsai Cc: Houlong Wei Cc: Andrew-CT Chen Cc: Guennadi Liakhovetski Cc: Hyun Kwon Cc: Michal Simek Cc: "Sören Brinkmann" Cc: linux-arm-kernel@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-mediatek@lists.infradead.org Cc: linux-renesas-soc@vger.kernel.org Reviewed-by: Sylwester Nawrocki Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 3 +- drivers/media/i2c/s5k5baf.c | 7 ++-- drivers/media/platform/am437x/am437x-vpfe.c | 4 +- drivers/media/platform/atmel/atmel-isc.c | 4 +- drivers/media/platform/davinci/vpif_capture.c | 16 ++++---- drivers/media/platform/exynos4-is/fimc-is.c | 8 ++-- drivers/media/platform/exynos4-is/fimc-lite.c | 3 +- drivers/media/platform/exynos4-is/media-dev.c | 8 ++-- drivers/media/platform/exynos4-is/mipi-csis.c | 4 +- drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 6 +-- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 8 ++-- drivers/media/platform/omap3isp/isp.c | 8 ++-- drivers/media/platform/pxa_camera.c | 2 +- drivers/media/platform/rcar-vin/rcar-core.c | 4 +- drivers/media/platform/soc_camera/soc_camera.c | 6 +-- drivers/media/platform/xilinx/xilinx-vipp.c | 52 +++++++++++++------------- drivers/media/v4l2-core/v4l2-clk.c | 3 +- include/media/v4l2-clk.h | 4 +- 18 files changed, 70 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index f434fb2ee6fc..cdc4f2392ef9 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1635,8 +1635,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) node_ep = of_graph_get_next_endpoint(node, NULL); if (!node_ep) { - dev_warn(dev, "no endpoint defined for node: %s\n", - node->full_name); + dev_warn(dev, "no endpoint defined for node: %pOF\n", node); return 0; } diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index f01722dc04d0..ff46d2c96cea 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1863,8 +1863,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) node_ep = of_graph_get_next_endpoint(node, NULL); if (!node_ep) { - dev_err(dev, "no endpoint defined at node %s\n", - node->full_name); + dev_err(dev, "no endpoint defined at node %pOF\n", node); return -EINVAL; } @@ -1882,8 +1881,8 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev) case V4L2_MBUS_PARALLEL: break; default: - dev_err(dev, "unsupported bus in endpoint defined at node %s\n", - node->full_name); + dev_err(dev, "unsupported bus in endpoint defined at node %pOF\n", + node); return -EINVAL; } diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 466aba8b0e00..dfcc484cab89 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -2490,8 +2490,8 @@ vpfe_get_pdata(struct platform_device *pdev) rem = of_graph_get_remote_port_parent(endpoint); if (!rem) { - dev_err(&pdev->dev, "Remote device at %s not found\n", - endpoint->full_name); + dev_err(&pdev->dev, "Remote device at %pOF not found\n", + endpoint); goto done; } diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index d4df3d4ccd85..d7103c5f92c3 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -1700,8 +1700,8 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) rem = of_graph_get_remote_port_parent(epn); if (!rem) { - dev_notice(dev, "Remote device at %s not found\n", - of_node_full_name(epn)); + dev_notice(dev, "Remote device at %pOF not found\n", + epn); continue; } diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index fe2a5748e554..0ef36cec21d1 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1397,9 +1397,9 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier, vpif_obj.config->chan_config->inputs[i].subdev_name = (char *)to_of_node(subdev->fwnode)->full_name; vpif_dbg(2, debug, - "%s: setting input %d subdev_name = %s\n", + "%s: setting input %d subdev_name = %pOF\n", __func__, i, - to_of_node(subdev->fwnode)->full_name); + to_of_node(subdev->fwnode)); return 0; } } @@ -1557,8 +1557,8 @@ vpif_capture_get_pdata(struct platform_device *pdev) dev_err(&pdev->dev, "Could not parse the endpoint\n"); goto done; } - dev_dbg(&pdev->dev, "Endpoint %s, bus_width = %d\n", - endpoint->full_name, bus_cfg.bus.parallel.bus_width); + dev_dbg(&pdev->dev, "Endpoint %pOF, bus_width = %d\n", + endpoint, bus_cfg.bus.parallel.bus_width); flags = bus_cfg.bus.parallel.flags; if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) @@ -1569,13 +1569,13 @@ vpif_capture_get_pdata(struct platform_device *pdev) rem = of_graph_get_remote_port_parent(endpoint); if (!rem) { - dev_dbg(&pdev->dev, "Remote device at %s not found\n", - endpoint->full_name); + dev_dbg(&pdev->dev, "Remote device at %pOF not found\n", + endpoint); goto done; } - dev_dbg(&pdev->dev, "Remote device %s, %s found\n", - rem->name, rem->full_name); + dev_dbg(&pdev->dev, "Remote device %s, %pOF found\n", + rem->name, rem); sdinfo->name = rem->full_name; pdata->asd[i] = devm_kzalloc(&pdev->dev, diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 340d906db370..5ddb2321e9e4 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -174,8 +174,8 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index, sensor->drvdata = fimc_is_sensor_get_drvdata(node); if (!sensor->drvdata) { - dev_err(&is->pdev->dev, "no driver data found for: %s\n", - node->full_name); + dev_err(&is->pdev->dev, "no driver data found for: %pOF\n", + node); return -EINVAL; } @@ -191,8 +191,8 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index, /* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */ ret = of_property_read_u32(port, "reg", &tmp); if (ret < 0) { - dev_err(&is->pdev->dev, "reg property not found at: %s\n", - port->full_name); + dev_err(&is->pdev->dev, "reg property not found at: %pOF\n", + port); of_node_put(port); return ret; } diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 30282c512e23..4a3c9948ca54 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1493,8 +1493,7 @@ static int fimc_lite_probe(struct platform_device *pdev) if (!drv_data || fimc->index >= drv_data->num_instances || fimc->index < 0) { - dev_err(dev, "Wrong %s node alias\n", - dev->of_node->full_name); + dev_err(dev, "Wrong %pOF node alias\n", dev->of_node); return -EINVAL; } diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 7d1cf78846c4..d4656d5175d7 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -412,8 +412,8 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, rem = of_graph_get_remote_port_parent(ep); of_node_put(ep); if (rem == NULL) { - v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", - ep->full_name); + v4l2_info(&fmd->v4l2_dev, "Remote device at %pOF not found\n", + ep); return 0; } @@ -430,8 +430,8 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, */ pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2; } else { - v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n", - endpoint.base.port, rem->full_name); + v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %pOF\n", + endpoint.base.port, rem); } /* * For FIMC-IS handled sensors, that are placed under i2c-isp device diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 98c89873c2dc..560aadabcb11 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -730,8 +730,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, node = of_graph_get_next_endpoint(node, NULL); if (!node) { - dev_err(&pdev->dev, "No port node at %s\n", - pdev->dev.of_node->full_name); + dev_err(&pdev->dev, "No port node at %pOF\n", + pdev->dev.of_node); return -EINVAL; } /* Get port node and validate MIPI-CSI channel id. */ diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c index aa8f9fd1f1a2..e728d32d9408 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c @@ -134,15 +134,13 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node, larb_node = of_parse_phandle(node, "mediatek,larb", 0); if (!larb_node) { dev_err(dev, - "Missing mediadek,larb phandle in %s node\n", - node->full_name); + "Missing mediadek,larb phandle in %pOF node\n", node); return -EINVAL; } larb_pdev = of_find_device_by_node(larb_node); if (!larb_pdev) { - dev_warn(dev, "Waiting for larb device %s\n", - larb_node->full_name); + dev_warn(dev, "Waiting for larb device %pOF\n", larb_node); of_node_put(larb_node); return -EPROBE_DEFER; } diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index 81347558b24a..bbb24fb95b95 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -137,16 +137,16 @@ static int mtk_mdp_probe(struct platform_device *pdev) continue; if (!of_device_is_available(node)) { - dev_err(dev, "Skipping disabled component %s\n", - node->full_name); + dev_err(dev, "Skipping disabled component %pOF\n", + node); continue; } comp_type = (enum mtk_mdp_comp_type)of_id->data; comp_id = mtk_mdp_comp_get_id(dev, node, comp_type); if (comp_id < 0) { - dev_warn(dev, "Skipping unknown component %s\n", - node->full_name); + dev_warn(dev, "Skipping unknown component %pOF\n", + node); continue; } diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index c3014c82d64d..83aea08b832d 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2024,8 +2024,8 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, if (ret) return ret; - dev_dbg(dev, "parsing endpoint %s, interface %u\n", - to_of_node(fwnode)->full_name, vep.base.port); + dev_dbg(dev, "parsing endpoint %pOF, interface %u\n", + to_of_node(fwnode), vep.base.port); switch (vep.base.port) { case ISP_OF_PHY_PARALLEL: @@ -2136,8 +2136,8 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, break; default: - dev_warn(dev, "%s: invalid interface %u\n", - to_of_node(fwnode)->full_name, vep.base.port); + dev_warn(dev, "%pOF: invalid interface %u\n", + to_of_node(fwnode), vep.base.port); return -EINVAL; } diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 4a800a4147ca..edca993c2b1f 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2331,7 +2331,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, asd->match.fwnode.fwnode = of_fwnode_handle(remote); of_node_put(remote); } else { - dev_notice(dev, "no remote for %s\n", of_node_full_name(np)); + dev_notice(dev, "no remote for %pOF\n", np); } out: diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 77dff047c41c..142de447aaaa 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -222,8 +222,8 @@ static int rvin_digital_graph_init(struct rvin_dev *vin) subdevs[0] = &vin->digital.asd; - vin_dbg(vin, "Found digital subdevice %s\n", - of_node_full_name(to_of_node(subdevs[0]->match.fwnode.fwnode))); + vin_dbg(vin, "Found digital subdevice %pOF\n", + to_of_node(subdevs[0]->match.fwnode.fwnode)); vin->notifier.num_subdevs = 1; vin->notifier.subdevs = subdevs; diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index dd349efae3af..1f3c450c7a69 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1550,8 +1550,7 @@ static int soc_of_bind(struct soc_camera_host *ici, v4l2_clk_name_i2c(clk_name, sizeof(clk_name), client->adapter->nr, client->addr); else - v4l2_clk_name_of(clk_name, sizeof(clk_name), - of_node_full_name(remote)); + v4l2_clk_name_of(clk_name, sizeof(clk_name), remote); icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); if (IS_ERR(icd->clk)) { @@ -1590,8 +1589,7 @@ static void scan_of_host(struct soc_camera_host *ici) ren = of_graph_get_remote_port(epn); if (!ren) { - dev_notice(dev, "no remote for %s\n", - of_node_full_name(epn)); + dev_notice(dev, "no remote for %pOF\n", epn); continue; } diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index ac4704388920..ebfdf334d99c 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -90,12 +90,12 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, of_node_put(ep); ep = next; - dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name); + dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep); ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link); if (ret < 0) { - dev_err(xdev->dev, "failed to parse link for %s\n", - ep->full_name); + dev_err(xdev->dev, "failed to parse link for %pOF\n", + ep); continue; } @@ -103,9 +103,9 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, * the link. */ if (link.local_port >= local->num_pads) { - dev_err(xdev->dev, "invalid port number %u for %s\n", + dev_err(xdev->dev, "invalid port number %u for %pOF\n", link.local_port, - to_of_node(link.local_node)->full_name); + to_of_node(link.local_node)); v4l2_fwnode_put_link(&link); ret = -EINVAL; break; @@ -114,8 +114,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, local_pad = &local->pads[link.local_port]; if (local_pad->flags & MEDIA_PAD_FL_SINK) { - dev_dbg(xdev->dev, "skipping sink port %s:%u\n", - to_of_node(link.local_node)->full_name, + dev_dbg(xdev->dev, "skipping sink port %pOF:%u\n", + to_of_node(link.local_node), link.local_port); v4l2_fwnode_put_link(&link); continue; @@ -123,8 +123,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, /* Skip DMA engines, they will be processed separately. */ if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) { - dev_dbg(xdev->dev, "skipping DMA port %s:%u\n", - to_of_node(link.local_node)->full_name, + dev_dbg(xdev->dev, "skipping DMA port %pOF:%u\n", + to_of_node(link.local_node), link.local_port); v4l2_fwnode_put_link(&link); continue; @@ -134,8 +134,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, ent = xvip_graph_find_entity(xdev, to_of_node(link.remote_node)); if (ent == NULL) { - dev_err(xdev->dev, "no entity found for %s\n", - to_of_node(link.remote_node)->full_name); + dev_err(xdev->dev, "no entity found for %pOF\n", + to_of_node(link.remote_node)); v4l2_fwnode_put_link(&link); ret = -ENODEV; break; @@ -144,9 +144,8 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, remote = ent->entity; if (link.remote_port >= remote->num_pads) { - dev_err(xdev->dev, "invalid port number %u on %s\n", - link.remote_port, - to_of_node(link.remote_node)->full_name); + dev_err(xdev->dev, "invalid port number %u on %pOF\n", + link.remote_port, to_of_node(link.remote_node)); v4l2_fwnode_put_link(&link); ret = -EINVAL; break; @@ -216,12 +215,12 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev) of_node_put(ep); ep = next; - dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name); + dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep); ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link); if (ret < 0) { - dev_err(xdev->dev, "failed to parse link for %s\n", - ep->full_name); + dev_err(xdev->dev, "failed to parse link for %pOF\n", + ep); continue; } @@ -242,17 +241,17 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev) ent = xvip_graph_find_entity(xdev, to_of_node(link.remote_node)); if (ent == NULL) { - dev_err(xdev->dev, "no entity found for %s\n", - to_of_node(link.remote_node)->full_name); + dev_err(xdev->dev, "no entity found for %pOF\n", + to_of_node(link.remote_node)); v4l2_fwnode_put_link(&link); ret = -ENODEV; break; } if (link.remote_port >= ent->entity->num_pads) { - dev_err(xdev->dev, "invalid port number %u on %s\n", + dev_err(xdev->dev, "invalid port number %u on %pOF\n", link.remote_port, - to_of_node(link.remote_node)->full_name); + to_of_node(link.remote_node)); v4l2_fwnode_put_link(&link); ret = -EINVAL; break; @@ -337,8 +336,8 @@ static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, continue; if (entity->subdev) { - dev_err(xdev->dev, "duplicate subdev for node %s\n", - entity->node->full_name); + dev_err(xdev->dev, "duplicate subdev for node %pOF\n", + entity->node); return -EINVAL; } @@ -360,14 +359,14 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev, struct device_node *ep = NULL; int ret = 0; - dev_dbg(xdev->dev, "parsing node %s\n", node->full_name); + dev_dbg(xdev->dev, "parsing node %pOF\n", node); while (1) { ep = of_graph_get_next_endpoint(node, ep); if (ep == NULL) break; - dev_dbg(xdev->dev, "handling endpoint %s\n", ep->full_name); + dev_dbg(xdev->dev, "handling endpoint %pOF\n", ep); remote = of_graph_get_remote_port_parent(ep); if (remote == NULL) { @@ -452,8 +451,7 @@ static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev, ret = xvip_dma_init(xdev, dma, type, index); if (ret < 0) { - dev_err(xdev->dev, "%s initialization failed\n", - node->full_name); + dev_err(xdev->dev, "%pOF initialization failed\n", node); return ret; } diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index 297e10e69898..90628d7a04de 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -61,8 +61,7 @@ struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) /* if dev_name is not found, try use the OF name to find again */ if (PTR_ERR(clk) == -ENODEV && dev->of_node) { - v4l2_clk_name_of(clk_name, sizeof(clk_name), - of_node_full_name(dev->of_node)); + v4l2_clk_name_of(clk_name, sizeof(clk_name), dev->of_node); clk = v4l2_clk_find(clk_name); } diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 2b94662d005c..7ec857f805a6 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -70,7 +70,7 @@ static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id, #define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \ "%d-%04x", adap, client) -#define v4l2_clk_name_of(name, size, of_full_name) snprintf(name, size, \ - "of-%s", of_full_name) +#define v4l2_clk_name_of(name, size, node) snprintf(name, size, \ + "of-%pOF", node) #endif -- cgit v1.2.3 From 8ac9e914a49ffd5ce5877d332c190f24d13725a9 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Tue, 8 Aug 2017 10:49:58 -0400 Subject: media: mtk-mdp: use IS_ERR to check return value of of_clk_get Function of_clk_get() returns an ERR_PTR on failures. In file mtk_mdp_commp.c, its return value is checked against NULL. Such checks cannot prevent from accessing bad memory. This patch replaces the NULL checks with IS_ERR checks. Signed-off-by: Pan Bian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c index e728d32d9408..03aba03a24c8 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c @@ -75,7 +75,7 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp) } for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { - if (!comp->clk[i]) + if (IS_ERR(comp->clk[i])) continue; err = clk_prepare_enable(comp->clk[i]); if (err) @@ -90,7 +90,7 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp) int i; for (i = 0; i < ARRAY_SIZE(comp->clk); i++) { - if (!comp->clk[i]) + if (IS_ERR(comp->clk[i])) continue; clk_disable_unprepare(comp->clk[i]); } -- cgit v1.2.3 From 8219760c0e4131da1ce7f4fd970de60540569bdc Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sun, 13 Aug 2017 08:43:12 -0400 Subject: media: staging: bcm2835-audio: make snd_pcm_hardware const Make these const as they are only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 3637ddf909a4..5f3b5a74c16a 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -20,7 +20,7 @@ #include "bcm2835.h" /* hardware definition */ -static struct snd_pcm_hardware snd_bcm2835_playback_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, @@ -36,7 +36,7 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = { .periods_max = 128, }; -static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_LE, -- cgit v1.2.3 From 89ac34aaf5e6347638146f46c7e9f78c951938a8 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 15 Aug 2017 07:23:40 -0400 Subject: media: coda: constify platform_device_id platform_device_id are not supposed to change at runtime. All functions working with platform_device_id provided by work with const platform_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Acked-by: Philipp Zabel Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 27c613752fbf..15eb5dc4dff9 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2447,7 +2447,7 @@ static const struct coda_devtype coda_devdata[] = { }, }; -static struct platform_device_id coda_platform_ids[] = { +static const struct platform_device_id coda_platform_ids[] = { { .name = "coda-imx27", .driver_data = CODA_IMX27 }, { /* sentinel */ } }; -- cgit v1.2.3 From 44ce8fc4764294db148819830803e440deb5e1a3 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 15 Aug 2017 07:23:41 -0400 Subject: media: davinci: constify platform_device_id platform_device_id are not supposed to change at runtime. All functions working with platform_device_id provided by work with const platform_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Acked-by: Lad, Prabhakar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpbe_osd.c | 2 +- drivers/media/platform/davinci/vpbe_venc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c index df042e84a678..66449791c70c 100644 --- a/drivers/media/platform/davinci/vpbe_osd.c +++ b/drivers/media/platform/davinci/vpbe_osd.c @@ -37,7 +37,7 @@ #define MODULE_NAME "davinci-vpbe-osd" -static struct platform_device_id vpbe_osd_devtype[] = { +static const struct platform_device_id vpbe_osd_devtype[] = { { .name = DM644X_VPBE_OSD_SUBDEV_NAME, .driver_data = VPBE_VERSION_1, diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 8bfe90a24681..3a4e78595149 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -36,7 +36,7 @@ #define MODULE_NAME "davinci-vpbe-venc" -static struct platform_device_id vpbe_venc_devtype[] = { +static const struct platform_device_id vpbe_venc_devtype[] = { { .name = DM644X_VPBE_VENC_SUBDEV_NAME, .driver_data = VPBE_VERSION_1, -- cgit v1.2.3 From db4a8505ff86f6ccbe4880969c1d45c2d0ea7987 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 16 Aug 2017 01:30:10 -0400 Subject: media: radio: constify pnp_device_id pnp_device_id are not supposed to change at runtime. All functions working with pnp_device_id provided by work with const pnp_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-cadet.c | 2 +- drivers/media/radio/radio-gemtek.c | 2 +- drivers/media/radio/radio-sf16fmr2.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index cbaf850f4791..6888b7db449d 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -528,7 +528,7 @@ static const struct v4l2_ctrl_ops cadet_ctrl_ops = { #ifdef CONFIG_PNP -static struct pnp_device_id cadet_pnp_devices[] = { +static const struct pnp_device_id cadet_pnp_devices[] = { /* ADS Cadet AM/FM Radio Card */ {.id = "MSM0c24", .driver_data = 0}, {.id = ""} diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index ca051ccbc3e4..ddc12b16f77c 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -281,7 +281,7 @@ static const struct radio_isa_ops gemtek_ops = { static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; #ifdef CONFIG_PNP -static struct pnp_device_id gemtek_pnp_devices[] = { +static const struct pnp_device_id gemtek_pnp_devices[] = { /* AOpen FX-3D/Pro Radio */ {.id = "ADS7183", .driver_data = 0}, {.id = ""} diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index dc81d422b394..de79d5569c2a 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -197,7 +197,7 @@ static int fmr2_tea_ext_init(struct snd_tea575x *tea) return 0; } -static struct pnp_device_id fmr2_pnp_ids[] = { +static const struct pnp_device_id fmr2_pnp_ids[] = { { .id = "MFRad13" }, /* tuner subdevice of SF16-FMD2 */ { .id = "" } }; -- cgit v1.2.3 From 9a69ae1d46b09bb7fdefb7cf6fc459563123eacc Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 16 Aug 2017 05:17:04 -0400 Subject: media: cx88: make snd_kcontrol_new const Make this const as it only passed as the 1st argument to the function snd_ctl_new1, which is of type const. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index c81fe4681d14..9740326bc93f 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -799,7 +799,7 @@ static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new snd_cx88_alc_switch = { +static const struct snd_kcontrol_new snd_cx88_alc_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Line-In ALC Switch", .info = snd_ctl_boolean_mono_info, -- cgit v1.2.3 From 24a571d1edee3afc167c67460bbb7a06ed499ab1 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 16 Aug 2017 05:17:05 -0400 Subject: media: solo6x10: make snd_kcontrol_new const Make this const as it is only used during a copy operation. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/solo6x10/solo6x10-g723.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c index 3ca947092775..81be1b8df758 100644 --- a/drivers/media/pci/solo6x10/solo6x10-g723.c +++ b/drivers/media/pci/solo6x10/solo6x10-g723.c @@ -319,7 +319,7 @@ static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new snd_solo_capture_volume = { +static const struct snd_kcontrol_new snd_solo_capture_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Volume", .info = snd_solo_capture_volume_info, -- cgit v1.2.3 From b295eef951adc5f19e06ed9b92fb1cd2e775e584 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 16 Aug 2017 10:54:00 -0400 Subject: media: cx18: Fix incompatible type for argument error The first argument of function snd_ctl_new1 is of type const struct snd_kcontrol_new * but in this file the variable is passed by value to this function. This generated ""incompatible type for argument" error. So, pass the variable by reference. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-alsa-mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx18/cx18-alsa-mixer.c b/drivers/media/pci/cx18/cx18-alsa-mixer.c index 06b066bc9301..cb04c3d820e2 100644 --- a/drivers/media/pci/cx18/cx18-alsa-mixer.c +++ b/drivers/media/pci/cx18/cx18-alsa-mixer.c @@ -161,7 +161,7 @@ int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc) strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername)); - ret = snd_ctl_add(sc, snd_ctl_new1(snd_cx18_mixer_tv_vol, cxsc)); + ret = snd_ctl_add(sc, snd_ctl_new1(&snd_cx18_mixer_tv_vol, cxsc)); if (ret) { CX18_ALSA_WARN("%s: failed to add %s control, err %d\n", __func__, snd_cx18_mixer_tv_vol.name, ret); -- cgit v1.2.3 From d088c3107e9718ca3271277693f80a42d4effe51 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 16 Aug 2017 11:37:42 -0400 Subject: media: ivtv: Fix incompatible type for argument error The first argument of function snd_ctl_new1 is of type const struct snd_kcontrol_new * but in this file the variable is passed by value to this function. This generated ""incompatible type for argument" error. So, pass the variable by reference. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/ivtv-alsa-mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/ivtv/ivtv-alsa-mixer.c b/drivers/media/pci/ivtv/ivtv-alsa-mixer.c index ba372a23eb5c..aee453fcff37 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-mixer.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-mixer.c @@ -156,7 +156,7 @@ int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc) strlcpy(sc->mixername, "CX2341[56] Mixer", sizeof(sc->mixername)); - ret = snd_ctl_add(sc, snd_ctl_new1(snd_ivtv_mixer_tv_vol, itvsc)); + ret = snd_ctl_add(sc, snd_ctl_new1(&snd_ivtv_mixer_tv_vol, itvsc)); if (ret) { IVTV_ALSA_WARN("%s: failed to add %s control, err %d\n", __func__, snd_ivtv_mixer_tv_vol.name, ret); -- cgit v1.2.3 From a874aabef9337f26c589858e7ea0ec6a6adbb129 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 16 Aug 2017 20:14:07 -0400 Subject: media: coda/imx-vdoa: Check for platform_get_resource() error platform_get_resource() may fail and in this case a NULL dereference will occur. Prevent this from happening by returning an error on platform_get_resource() failure. Fixes: b0444f18e0b18abce ("[media] coda: add i.MX6 VDOA driver") Signed-off-by: Fabio Estevam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/imx-vdoa.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c index df9b71621420..8eb3e0c05473 100644 --- a/drivers/media/platform/coda/imx-vdoa.c +++ b/drivers/media/platform/coda/imx-vdoa.c @@ -314,6 +314,8 @@ static int vdoa_probe(struct platform_device *pdev) return PTR_ERR(vdoa->regs); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) + return -EINVAL; vdoa->irq = devm_request_threaded_irq(&pdev->dev, res->start, NULL, vdoa_irq_handler, IRQF_ONESHOT, "vdoa", vdoa); -- cgit v1.2.3 From 21b36756fc738251847d7ef19aa31fcb4e44c018 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 17 Aug 2017 07:56:23 -0400 Subject: media: usb: pulse8-cec: constify serio_device_id serio_device_id are not supposed to change at runtime. All functions working with serio_device_id provided by work with const serio_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pulse8-cec/pulse8-cec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index 95f616f94004..50146f263d90 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -731,7 +731,7 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work) mutex_unlock(&pulse8->config_lock); } -static struct serio_device_id pulse8_serio_ids[] = { +static const struct serio_device_id pulse8_serio_ids[] = { { .type = SERIO_RS232, .proto = SERIO_PULSE8_CEC, -- cgit v1.2.3 From 52471f6705b92054e73ee547a871797db076e716 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 17 Aug 2017 07:56:24 -0400 Subject: media: usb: rainshadow-cec: constify serio_device_id serio_device_id are not supposed to change at runtime. All functions working with serio_device_id provided by work with const serio_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index 6f9681c995a4..cecdcbcd400c 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -358,7 +358,7 @@ free_device: return err; } -static struct serio_device_id rain_serio_ids[] = { +static const struct serio_device_id rain_serio_ids[] = { { .type = SERIO_RS232, .proto = SERIO_RAINSHADOW_CEC, -- cgit v1.2.3 From f14253818a7aa096f1f3a650b2d5b73612fbd46f Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Wed, 9 Aug 2017 17:59:48 -0400 Subject: media: ov5670: Fix incorrect frame timing reported to user Previously, pixel-rate/(pixels-per-line * lines-per-frame) was yielding incorrect frame timing for the user. OV sensor is using internal timing and this requires conversion (internal timing -> PPL) for correct HBLANK calculation. Now, change pixels-per-line domain from internal sensor clock to pixels domain. Set HBLANK read-only because fixed PPL is used for all resolutions. And, use more accurate link-frequency 422.4MHz instead of rounding down to 420MHz. Signed-off-by: Chiranjeevi Rapolu Reviewed-by: Tomasz Figa Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5670.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 8d8e16c5c49f..b9d4dd278e14 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -37,7 +37,13 @@ /* horizontal-timings from sensor */ #define OV5670_REG_HTS 0x380c -#define OV5670_DEF_PPL 3360 /* Default pixels per line */ + +/* + * Pixels-per-line(PPL) = Time-per-line * pixel-rate + * In OV5670, Time-per-line = HTS/SCLK. + * HTS is fixed for all resolutions, not recommended to change. + */ +#define OV5670_FIXED_PPL 2724 /* Pixels per line */ /* Exposure controls from sensor */ #define OV5670_REG_EXPOSURE 0x3500 @@ -1705,12 +1711,12 @@ static const char * const ov5670_test_pattern_menu[] = { }; /* Supported link frequencies */ -#define OV5670_LINK_FREQ_420MHZ 420000000 -#define OV5670_LINK_FREQ_420MHZ_INDEX 0 +#define OV5670_LINK_FREQ_422MHZ 422400000 +#define OV5670_LINK_FREQ_422MHZ_INDEX 0 static const struct ov5670_link_freq_config link_freq_configs[] = { { /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ - .pixel_rate = (OV5670_LINK_FREQ_420MHZ * 2 * 2) / 10, + .pixel_rate = (OV5670_LINK_FREQ_422MHZ * 2 * 2) / 10, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_840mbps), .regs = mipi_data_rate_840mbps, @@ -1719,7 +1725,7 @@ static const struct ov5670_link_freq_config link_freq_configs[] = { }; static const s64 link_freq_menu_items[] = { - OV5670_LINK_FREQ_420MHZ + OV5670_LINK_FREQ_422MHZ }; /* @@ -1736,7 +1742,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs), .regs = mode_2592x1944_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 1296, @@ -1746,7 +1752,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_1296x972_regs), .regs = mode_1296x972_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 648, @@ -1756,7 +1762,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_648x486_regs), .regs = mode_648x486_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 2560, @@ -1766,7 +1772,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_2560x1440_regs), .regs = mode_2560x1440_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 1280, @@ -1776,7 +1782,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_1280x720_regs), .regs = mode_1280x720_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 640, @@ -1786,7 +1792,7 @@ static const struct ov5670_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_640x360_regs), .regs = mode_640x360_regs, }, - .link_freq_index = OV5670_LINK_FREQ_420MHZ_INDEX, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, } }; @@ -2016,13 +2022,6 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl) OV5670_REG_VALUE_16BIT, ov5670->cur_mode->height + ctrl->val); break; - case V4L2_CID_HBLANK: - /* Update HTS that meets expected horizontal blanking */ - ret = ov5670_write_reg(ov5670, OV5670_REG_HTS, - OV5670_REG_VALUE_16BIT, - (ov5670->cur_mode->width + - ctrl->val) / 2); - break; case V4L2_CID_TEST_PATTERN: ret = ov5670_enable_test_pattern(ov5670, ctrl->val); break; @@ -2078,9 +2077,11 @@ static int ov5670_init_controls(struct ov5670 *ov5670) ov5670->hblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_HBLANK, - OV5670_DEF_PPL - ov5670->cur_mode->width, - OV5670_DEF_PPL - ov5670->cur_mode->width, 1, - OV5670_DEF_PPL - ov5670->cur_mode->width); + OV5670_FIXED_PPL - ov5670->cur_mode->width, + OV5670_FIXED_PPL - ov5670->cur_mode->width, 1, + OV5670_FIXED_PPL - ov5670->cur_mode->width); + if (ov5670->hblank) + ov5670->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; /* Get min, max, step, default from sensor */ v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, @@ -2247,7 +2248,7 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, OV5670_VTS_MAX - ov5670->cur_mode->height, 1, vblank_def); __v4l2_ctrl_s_ctrl(ov5670->vblank, vblank_def); - h_blank = OV5670_DEF_PPL - ov5670->cur_mode->width; + h_blank = OV5670_FIXED_PPL - ov5670->cur_mode->width; __v4l2_ctrl_modify_range(ov5670->hblank, h_blank, h_blank, 1, h_blank); } -- cgit v1.2.3 From a828d818bf6f48e1f594a19df0594af9065dc5dc Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 06:58:27 -0400 Subject: media: v4l: mt9t001: constify video_subdev structures The v4l2_subdev_ops structure is only passed as the third argument of v4l2_i2c_subdev_init, which is const, so the v4l2_subdev_ops structure can be const as well. The other structures are only stored in the v4l2_subdev_ops structure, all the fields of which are const, so these structures can also be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9t001.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index 842017fa4aab..9d981d9f5686 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c @@ -822,15 +822,15 @@ static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) return mt9t001_set_power(subdev, 0); } -static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = { +static const struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = { .s_power = mt9t001_set_power, }; -static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = { +static const struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = { .s_stream = mt9t001_s_stream, }; -static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = { +static const struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = { .enum_mbus_code = mt9t001_enum_mbus_code, .enum_frame_size = mt9t001_enum_frame_size, .get_fmt = mt9t001_get_format, @@ -839,7 +839,7 @@ static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = { .set_selection = mt9t001_set_selection, }; -static struct v4l2_subdev_ops mt9t001_subdev_ops = { +static const struct v4l2_subdev_ops mt9t001_subdev_ops = { .core = &mt9t001_subdev_core_ops, .video = &mt9t001_subdev_video_ops, .pad = &mt9t001_subdev_pad_ops, -- cgit v1.2.3 From 392296208b952dfa486cfa44db72587efd960714 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 8 Aug 2017 06:58:30 -0400 Subject: media: mt9m111: constify video_subdev structures The v4l2_subdev_ops structure is only passed as the third argument of v4l2_i2c_subdev_init, which is const, so the v4l2_subdev_ops structure can be const as well. The other structures are only stored in the v4l2_subdev_ops structure, all the fields of which are const, so these structures can also be const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m111.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 72e71b762827..99b992e46702 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -835,7 +835,7 @@ static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = { .s_ctrl = mt9m111_s_ctrl, }; -static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { +static const struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { .s_power = mt9m111_s_power, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9m111_g_register, @@ -865,7 +865,7 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, return 0; } -static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { +static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { .g_mbus_config = mt9m111_g_mbus_config, }; @@ -877,7 +877,7 @@ static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { .set_fmt = mt9m111_set_fmt, }; -static struct v4l2_subdev_ops mt9m111_subdev_ops = { +static const struct v4l2_subdev_ops mt9m111_subdev_ops = { .core = &mt9m111_subdev_core_ops, .video = &mt9m111_subdev_video_ops, .pad = &mt9m111_subdev_pad_ops, -- cgit v1.2.3 From 070ed82e32020dd9cc1ab3b5790b6b7d3f788e30 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Aug 2017 03:28:16 -0400 Subject: media: et8ek8: Decrease stack usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The et8ek8 driver combines I²C register writes to a single array that it passes to i2c_transfer(). The maximum number of writes is 48 at once, decrease it to 8 and make more transfers if needed. Signed-off-by: Sakari Ailus Tested-by: Pavel Machek Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/et8ek8/et8ek8_driver.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c index f39f5179dd95..c14f0fd6ded3 100644 --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -43,7 +43,7 @@ #define ET8EK8_NAME "et8ek8" #define ET8EK8_PRIV_MEM_SIZE 128 -#define ET8EK8_MAX_MSG 48 +#define ET8EK8_MAX_MSG 8 struct et8ek8_sensor { struct v4l2_subdev subdev; @@ -220,7 +220,8 @@ static void et8ek8_i2c_create_msg(struct i2c_client *client, u16 len, u16 reg, /* * A buffered write method that puts the wanted register write - * commands in a message list and passes the list to the i2c framework + * commands in smaller number of message lists and passes the lists to + * the i2c framework */ static int et8ek8_i2c_buffered_write_regs(struct i2c_client *client, const struct et8ek8_reg *wnext, @@ -231,11 +232,7 @@ static int et8ek8_i2c_buffered_write_regs(struct i2c_client *client, int wcnt = 0; u16 reg, data_length; u32 val; - - if (WARN_ONCE(cnt > ET8EK8_MAX_MSG, - ET8EK8_NAME ": %s: too many messages.\n", __func__)) { - return -EINVAL; - } + int rval; /* Create new write messages for all writes */ while (wcnt < cnt) { @@ -249,10 +246,21 @@ static int et8ek8_i2c_buffered_write_regs(struct i2c_client *client, /* Update write count */ wcnt++; + + if (wcnt < ET8EK8_MAX_MSG) + continue; + + rval = i2c_transfer(client->adapter, msg, wcnt); + if (rval < 0) + return rval; + + cnt -= wcnt; + wcnt = 0; } - /* Now we send everything ... */ - return i2c_transfer(client->adapter, msg, wcnt); + rval = i2c_transfer(client->adapter, msg, wcnt); + + return rval < 0 ? rval : 0; } /* -- cgit v1.2.3 From ed351ad948dce56c55d6cce7afb351b67a841c83 Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Thu, 17 Aug 2017 18:15:48 -0400 Subject: media: ov5670: Limit vblank to permissible range Previously, vblank range given to user was too big, falling outside of permissible range for a given resolution. Sometimes, too low vblank resulted in errors. Now, limit vblank to only permissible range for a given resolution. This change limits lower-bounds of vblank, doesn't affect upper bounds. Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5670.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index b9d4dd278e14..6f7a1d6d2200 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -33,7 +33,6 @@ #define OV5670_REG_VTS 0x380e #define OV5670_VTS_30FPS 0x0808 /* default for 30 fps */ #define OV5670_VTS_MAX 0xffff -#define OV5670_VBLANK_MIN 56 /* horizontal-timings from sensor */ #define OV5670_REG_HTS 0x380c @@ -100,8 +99,11 @@ struct ov5670_mode { /* Frame height in pixels */ u32 height; - /* Vertical timining size */ - u32 vts; + /* Default vertical timining size */ + u32 vts_def; + + /* Min vertical timining size */ + u32 vts_min; /* Link frequency needed for this resolution */ u32 link_freq_index; @@ -1737,7 +1739,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 2592, .height = 1944, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = OV5670_VTS_30FPS, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs), .regs = mode_2592x1944_regs, @@ -1747,7 +1750,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 1296, .height = 972, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = 996, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1296x972_regs), .regs = mode_1296x972_regs, @@ -1757,7 +1761,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 648, .height = 486, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = 516, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_648x486_regs), .regs = mode_648x486_regs, @@ -1767,7 +1772,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 2560, .height = 1440, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = OV5670_VTS_30FPS, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2560x1440_regs), .regs = mode_2560x1440_regs, @@ -1777,7 +1783,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 1280, .height = 720, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = 1020, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1280x720_regs), .regs = mode_1280x720_regs, @@ -1787,7 +1794,8 @@ static const struct ov5670_mode supported_modes[] = { { .width = 640, .height = 360, - .vts = OV5670_VTS_30FPS, + .vts_def = OV5670_VTS_30FPS, + .vts_min = 510, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_640x360_regs), .regs = mode_640x360_regs, @@ -2046,6 +2054,7 @@ static int ov5670_init_controls(struct ov5670 *ov5670) struct v4l2_ctrl_handler *ctrl_hdlr; s64 vblank_max; s64 vblank_def; + s64 vblank_min; s64 exposure_max; int ret; @@ -2070,9 +2079,10 @@ static int ov5670_init_controls(struct ov5670 *ov5670) link_freq_configs[0].pixel_rate); vblank_max = OV5670_VTS_MAX - ov5670->cur_mode->height; - vblank_def = ov5670->cur_mode->vts - ov5670->cur_mode->height; + vblank_def = ov5670->cur_mode->vts_def - ov5670->cur_mode->height; + vblank_min = ov5670->cur_mode->vts_min - ov5670->cur_mode->height; ov5670->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, - V4L2_CID_VBLANK, OV5670_VBLANK_MIN, + V4L2_CID_VBLANK, vblank_min, vblank_max, 1, vblank_def); ov5670->hblank = v4l2_ctrl_new_std( @@ -2094,7 +2104,7 @@ static int ov5670_init_controls(struct ov5670 *ov5670) OV5670_DGTL_GAIN_STEP, OV5670_DGTL_GAIN_DEFAULT); /* Get min, max, step, default from sensor */ - exposure_max = ov5670->cur_mode->vts - 8; + exposure_max = ov5670->cur_mode->vts_def - 8; ov5670->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, V4L2_CID_EXPOSURE, OV5670_EXPOSURE_MIN, @@ -2242,9 +2252,11 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, ov5670->pixel_rate, link_freq_configs[mode->link_freq_index].pixel_rate); /* Update limits and set FPS to default */ - vblank_def = ov5670->cur_mode->vts - ov5670->cur_mode->height; + vblank_def = ov5670->cur_mode->vts_def - + ov5670->cur_mode->height; __v4l2_ctrl_modify_range( - ov5670->vblank, OV5670_VBLANK_MIN, + ov5670->vblank, + ov5670->cur_mode->vts_min - ov5670->cur_mode->height, OV5670_VTS_MAX - ov5670->cur_mode->height, 1, vblank_def); __v4l2_ctrl_s_ctrl(ov5670->vblank, vblank_def); -- cgit v1.2.3 From 17fcd5f5d0cda2aa269942492b834a009c1cc928 Mon Sep 17 00:00:00 2001 From: Chiranjeevi Rapolu Date: Fri, 18 Aug 2017 00:29:38 -0400 Subject: media: ov13858: Limit vblank to permissible range Previously, vblank range given to user was too big, falling outside of permissible range for a given resolution. Sometimes, too low vblank resulted in errors. Now, limit vblank to only permissible range for a given resolution. This change limits lower-bounds of vblank, doesn't affect upper bounds. Signed-off-by: Chiranjeevi Rapolu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 45c0e96a4cba..af7af0d14c69 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -57,7 +57,6 @@ #define OV13858_VTS_30FPS 0x0c8e /* 30 fps */ #define OV13858_VTS_60FPS 0x0648 /* 60 fps */ #define OV13858_VTS_MAX 0x7fff -#define OV13858_VBLANK_MIN 56 /* HBLANK control - read only */ #define OV13858_PPL_270MHZ 2244 @@ -120,7 +119,8 @@ struct ov13858_mode { u32 height; /* V-timing */ - u32 vts; + u32 vts_def; + u32 vts_min; /* Index of Link frequency config to be used */ u32 link_freq_index; @@ -982,7 +982,8 @@ static const struct ov13858_mode supported_modes[] = { { .width = 4224, .height = 3136, - .vts = OV13858_VTS_30FPS, + .vts_def = OV13858_VTS_30FPS, + .vts_min = OV13858_VTS_30FPS, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_4224x3136_regs), .regs = mode_4224x3136_regs, @@ -992,7 +993,8 @@ static const struct ov13858_mode supported_modes[] = { { .width = 2112, .height = 1568, - .vts = OV13858_VTS_30FPS, + .vts_def = OV13858_VTS_30FPS, + .vts_min = 1608, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2112x1568_regs), .regs = mode_2112x1568_regs, @@ -1002,7 +1004,8 @@ static const struct ov13858_mode supported_modes[] = { { .width = 2112, .height = 1188, - .vts = OV13858_VTS_30FPS, + .vts_def = OV13858_VTS_30FPS, + .vts_min = 1608, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2112x1188_regs), .regs = mode_2112x1188_regs, @@ -1012,7 +1015,8 @@ static const struct ov13858_mode supported_modes[] = { { .width = 1056, .height = 784, - .vts = OV13858_VTS_30FPS, + .vts_def = OV13858_VTS_30FPS, + .vts_min = 804, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1056x784_regs), .regs = mode_1056x784_regs, @@ -1379,6 +1383,7 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, const struct ov13858_mode *mode; struct v4l2_mbus_framefmt *framefmt; s32 vblank_def; + s32 vblank_min; s64 h_blank; mutex_lock(&ov13858->mutex); @@ -1399,9 +1404,12 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, ov13858->pixel_rate, link_freq_configs[mode->link_freq_index].pixel_rate); /* Update limits and set FPS to default */ - vblank_def = ov13858->cur_mode->vts - ov13858->cur_mode->height; + vblank_def = ov13858->cur_mode->vts_def - + ov13858->cur_mode->height; + vblank_min = ov13858->cur_mode->vts_min - + ov13858->cur_mode->height; __v4l2_ctrl_modify_range( - ov13858->vblank, OV13858_VBLANK_MIN, + ov13858->vblank, vblank_min, OV13858_VTS_MAX - ov13858->cur_mode->height, 1, vblank_def); __v4l2_ctrl_s_ctrl(ov13858->vblank, vblank_def); @@ -1607,6 +1615,8 @@ static int ov13858_init_controls(struct ov13858 *ov13858) struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); struct v4l2_ctrl_handler *ctrl_hdlr; s64 exposure_max; + s64 vblank_def; + s64 vblank_min; int ret; ctrl_hdlr = &ov13858->ctrl_handler; @@ -1630,12 +1640,13 @@ static int ov13858_init_controls(struct ov13858 *ov13858) link_freq_configs[0].pixel_rate, 1, link_freq_configs[0].pixel_rate); + vblank_def = ov13858->cur_mode->vts_def - ov13858->cur_mode->height; + vblank_min = ov13858->cur_mode->vts_min - ov13858->cur_mode->height; ov13858->vblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VBLANK, - OV13858_VBLANK_MIN, + vblank_min, OV13858_VTS_MAX - ov13858->cur_mode->height, 1, - ov13858->cur_mode->vts - - ov13858->cur_mode->height); + vblank_def); ov13858->hblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK, @@ -1645,7 +1656,7 @@ static int ov13858_init_controls(struct ov13858 *ov13858) OV13858_PPL_540MHZ - ov13858->cur_mode->width); ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - exposure_max = ov13858->cur_mode->vts - 8; + exposure_max = ov13858->cur_mode->vts_def - 8; ov13858->exposure = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN, -- cgit v1.2.3 From 372b2b0399fc99ae0d6f3b3c7f8997a061207305 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:38 -0400 Subject: media: v4l: vsp1: Release buffers in start_streaming error path Presently any received buffers are only released back to vb2 if vsp1_video_stop_streaming() is called. If vsp1_video_start_streaming() encounters an error, we will be warned by the vb2 handlers that buffers have not been returned. Move the buffer cleanup code to its own function to prevent duplication and call from both vsp1_video_stop_streaming() and the error path in vsp1_video_start_streaming(). Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_video.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 5af3486afe07..fdb135e45fea 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -822,6 +822,20 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) return 0; } +static void vsp1_video_cleanup_pipeline(struct vsp1_pipeline *pipe) +{ + struct vsp1_video *video = pipe->output->video; + struct vsp1_vb2_buffer *buffer; + unsigned long flags; + + /* Remove all buffers from the IRQ queue. */ + spin_lock_irqsave(&video->irqlock, flags); + list_for_each_entry(buffer, &video->irqqueue, queue) + vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR); + INIT_LIST_HEAD(&video->irqqueue); + spin_unlock_irqrestore(&video->irqlock, flags); +} + static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vsp1_video *video = vb2_get_drv_priv(vq); @@ -835,6 +849,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) ret = vsp1_video_setup_pipeline(pipe); if (ret < 0) { mutex_unlock(&pipe->lock); + vsp1_video_cleanup_pipeline(pipe); return ret; } @@ -866,7 +881,6 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) { struct vsp1_video *video = vb2_get_drv_priv(vq); struct vsp1_pipeline *pipe = video->rwpf->pipe; - struct vsp1_vb2_buffer *buffer; unsigned long flags; int ret; @@ -891,14 +905,8 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) mutex_unlock(&pipe->lock); media_pipeline_stop(&video->video.entity); + vsp1_video_cleanup_pipeline(pipe); vsp1_video_pipeline_put(pipe); - - /* Remove all buffers from the IRQ queue. */ - spin_lock_irqsave(&video->irqlock, flags); - list_for_each_entry(buffer, &video->irqqueue, queue) - vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR); - INIT_LIST_HEAD(&video->irqqueue); - spin_unlock_irqrestore(&video->irqlock, flags); } static const struct vb2_ops vsp1_video_queue_qops = { -- cgit v1.2.3 From 801c6a17784217dbc36216b6050ffc0f2208c5a2 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:39 -0400 Subject: media: v4l: vsp1: Move vsp1_video_pipeline_setup_partitions() function Separate the code change from the function move so that code changes can be clearly identified. This commit has no functional change. The partition algorithm functions will be changed, and vsp1_video_pipeline_setup_partitions() will call vsp1_video_partition(). To prepare for that, move the function without any code change. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_video.c | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index fdb135e45fea..e4c0bfa0f864 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -182,43 +182,6 @@ static int __vsp1_video_try_format(struct vsp1_video *video, * VSP1 Partition Algorithm support */ -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) -{ - struct vsp1_device *vsp1 = pipe->output->entity.vsp1; - const struct v4l2_mbus_framefmt *format; - struct vsp1_entity *entity; - unsigned int div_size; - - /* - * Partitions are computed on the size before rotation, use the format - * at the WPF sink. - */ - format = vsp1_entity_get_pad_format(&pipe->output->entity, - pipe->output->entity.config, - RWPF_PAD_SINK); - div_size = format->width; - - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } - - list_for_each_entry(entity, &pipe->entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; - - if (entity->ops->max_width) { - entity_max = entity->ops->max_width(entity, pipe); - if (entity_max) - div_size = min(div_size, entity_max); - } - } - - pipe->div_size = div_size; - pipe->partitions = DIV_ROUND_UP(format->width, div_size); -} - /** * vsp1_video_partition - Calculate the active partition output window * @@ -293,6 +256,43 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } +static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +{ + struct vsp1_device *vsp1 = pipe->output->entity.vsp1; + const struct v4l2_mbus_framefmt *format; + struct vsp1_entity *entity; + unsigned int div_size; + + /* + * Partitions are computed on the size before rotation, use the format + * at the WPF sink. + */ + format = vsp1_entity_get_pad_format(&pipe->output->entity, + pipe->output->entity.config, + RWPF_PAD_SINK); + div_size = format->width; + + /* Gen2 hardware doesn't require image partitioning. */ + if (vsp1->info->gen == 2) { + pipe->div_size = div_size; + pipe->partitions = 1; + return; + } + + list_for_each_entry(entity, &pipe->entities, list_pipe) { + unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + + if (entity->ops->max_width) { + entity_max = entity->ops->max_width(entity, pipe); + if (entity_max) + div_size = min(div_size, entity_max); + } + } + + pipe->div_size = div_size; + pipe->partitions = DIV_ROUND_UP(format->width, div_size); +} + /* ----------------------------------------------------------------------------- * Pipeline Management */ -- cgit v1.2.3 From 25b6beabd0f918c38d4f830c5a60feda2e146e43 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:40 -0400 Subject: media: v4l: vsp1: Calculate partition sizes at stream start Previously the active window and partition sizes for each partition were calculated for each partition every frame. This data is constant and only needs to be calculated once at the start of the stream. Extend the vsp1_pipe object to dynamically store the number of partitions required and pre-calculate the partition sizes into this table. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_pipe.h | 3 +++ drivers/media/platform/vsp1/vsp1_video.c | 44 ++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 91a784a13422..0cfd07a187a2 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -82,7 +82,9 @@ enum vsp1_pipeline_state { * @dl: display list associated with the pipeline * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame + * @partition: The current partition for configuration to process * @current_partition: The partition number currently being configured + * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { struct media_pipeline pipe; @@ -117,6 +119,7 @@ struct vsp1_pipeline { unsigned int partitions; struct v4l2_rect partition; unsigned int current_partition; + struct v4l2_rect *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index e4c0bfa0f864..2ac57a436811 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -256,12 +256,13 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; const struct v4l2_mbus_framefmt *format; struct vsp1_entity *entity; unsigned int div_size; + unsigned int i; /* * Partitions are computed on the size before rotation, use the format @@ -272,17 +273,17 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) RWPF_PAD_SINK); div_size = format->width; - /* Gen2 hardware doesn't require image partitioning. */ - if (vsp1->info->gen == 2) { - pipe->div_size = div_size; - pipe->partitions = 1; - return; - } + /* + * Only Gen3 hardware requires image partitioning, Gen2 will operate + * with a single partition that covers the whole output. + */ + if (vsp1->info->gen == 3) { + list_for_each_entry(entity, &pipe->entities, list_pipe) { + unsigned int entity_max; - list_for_each_entry(entity, &pipe->entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + if (!entity->ops->max_width) + continue; - if (entity->ops->max_width) { entity_max = entity->ops->max_width(entity, pipe); if (entity_max) div_size = min(div_size, entity_max); @@ -291,6 +292,15 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); + pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), + GFP_KERNEL); + if (!pipe->part_table) + return -ENOMEM; + + for (i = 0; i < pipe->partitions; ++i) + pipe->part_table[i] = vsp1_video_partition(pipe, div_size, i); + + return 0; } /* ----------------------------------------------------------------------------- @@ -373,8 +383,7 @@ static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, { struct vsp1_entity *entity; - pipe->partition = vsp1_video_partition(pipe, pipe->div_size, - pipe->current_partition); + pipe->partition = pipe->part_table[pipe->current_partition]; list_for_each_entry(entity, &pipe->entities, list_pipe) { if (entity->ops->configure) @@ -783,9 +792,12 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb) static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) { struct vsp1_entity *entity; + int ret; /* Determine this pipelines sizes for image partitioning support. */ - vsp1_video_pipeline_setup_partitions(pipe); + ret = vsp1_video_pipeline_setup_partitions(pipe); + if (ret < 0) + return ret; /* Prepare the display list. */ pipe->dl = vsp1_dl_list_get(pipe->output->dlm); @@ -834,6 +846,12 @@ static void vsp1_video_cleanup_pipeline(struct vsp1_pipeline *pipe) vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR); INIT_LIST_HEAD(&video->irqqueue); spin_unlock_irqrestore(&video->irqlock, flags); + + /* Release our partition table allocation */ + mutex_lock(&pipe->lock); + kfree(pipe->part_table); + pipe->part_table = NULL; + mutex_unlock(&pipe->lock); } static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) -- cgit v1.2.3 From 62dad91c29f36799bf778178f52864a749603d4f Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:41 -0400 Subject: media: v4l: vsp1: Remove redundant context variables The vsp1_pipe object context variables for div_size and current_partition allowed state to be maintained through processing the partitions during processing. Now that the partition tables are calculated during stream on, there is no requirement to store these variables in the pipe object. Utilise local variables for the processing as required. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_pipe.h | 4 ---- drivers/media/platform/vsp1/vsp1_video.c | 21 +++++++-------------- 2 files changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 0cfd07a187a2..9653ef5cfb0c 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -80,10 +80,8 @@ enum vsp1_pipeline_state { * @uds_input: entity at the input of the UDS, if the UDS is present * @entities: list of entities in the pipeline * @dl: display list associated with the pipeline - * @div_size: The maximum allowed partition size for the pipeline * @partitions: The number of partitions used to process one frame * @partition: The current partition for configuration to process - * @current_partition: The partition number currently being configured * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { @@ -115,10 +113,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; - unsigned int div_size; unsigned int partitions; struct v4l2_rect partition; - unsigned int current_partition; struct v4l2_rect *part_table; }; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 2ac57a436811..176fd4b17df5 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -290,7 +290,6 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) } } - pipe->div_size = div_size; pipe->partitions = DIV_ROUND_UP(format->width, div_size); pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), GFP_KERNEL); @@ -379,11 +378,12 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe, } static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, - struct vsp1_dl_list *dl) + struct vsp1_dl_list *dl, + unsigned int partition) { struct vsp1_entity *entity; - pipe->partition = pipe->part_table[pipe->current_partition]; + pipe->partition = pipe->part_table[partition]; list_for_each_entry(entity, &pipe->entities, list_pipe) { if (entity->ops->configure) @@ -396,6 +396,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) { struct vsp1_device *vsp1 = pipe->output->entity.vsp1; struct vsp1_entity *entity; + unsigned int partition; if (!pipe->dl) pipe->dl = vsp1_dl_list_get(pipe->output->dlm); @@ -412,20 +413,12 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) } /* Run the first partition */ - pipe->current_partition = 0; - vsp1_video_pipeline_run_partition(pipe, pipe->dl); + vsp1_video_pipeline_run_partition(pipe, pipe->dl, 0); /* Process consecutive partitions as necessary */ - for (pipe->current_partition = 1; - pipe->current_partition < pipe->partitions; - pipe->current_partition++) { + for (partition = 1; partition < pipe->partitions; ++partition) { struct vsp1_dl_list *dl; - /* - * Partition configuration operations will utilise - * the pipe->current_partition variable to determine - * the work they should complete. - */ dl = vsp1_dl_list_get(pipe->output->dlm); /* @@ -438,7 +431,7 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) break; } - vsp1_video_pipeline_run_partition(pipe, dl); + vsp1_video_pipeline_run_partition(pipe, dl, partition); vsp1_dl_list_add_chain(pipe->dl, dl); } -- cgit v1.2.3 From 40650268787afed3600e91599b7d8570be42bf96 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:42 -0400 Subject: media: v4l: vsp1: Move partition rectangles to struct and operate directly As we develop the partition algorithm, we need to store more information per partition to describe the phase and other parameters. To keep this data together, further abstract the existing v4l2_rect into a partition specific structure. As partitions only have horizontal coordinates, store the left and width values only. When generating the partition windows, operate directly on the partition struct rather than copying and duplicating the processed data Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_pipe.h | 15 +++++++++-- drivers/media/platform/vsp1/vsp1_rpf.c | 4 +-- drivers/media/platform/vsp1/vsp1_uds.c | 18 +++++++------ drivers/media/platform/vsp1/vsp1_video.c | 43 ++++++++++++++------------------ drivers/media/platform/vsp1/vsp1_wpf.c | 14 +++++------ 5 files changed, 51 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 9653ef5cfb0c..4e9fd96108be 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -57,6 +57,17 @@ enum vsp1_pipeline_state { VSP1_PIPELINE_STOPPING, }; +/* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @left: horizontal coordinate of the partition start in pixels relative to the + * left edge of the image + * @width: partition width in pixels + */ +struct vsp1_partition { + unsigned int left; + unsigned int width; +}; + /* * struct vsp1_pipeline - A VSP1 hardware pipeline * @pipe: the media pipeline @@ -114,8 +125,8 @@ struct vsp1_pipeline { struct vsp1_dl_list *dl; unsigned int partitions; - struct v4l2_rect partition; - struct v4l2_rect *part_table; + struct vsp1_partition *partition; + struct vsp1_partition *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 8feddd59cf8d..126741f00ae3 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -108,9 +108,9 @@ static void rpf_configure(struct vsp1_entity *entity, output = vsp1_entity_get_pad_format(wpf, wpf->config, RWPF_PAD_SINK); - crop.width = pipe->partition.width * input_width + crop.width = pipe->partition->width * input_width / output->width; - crop.left += pipe->partition.left * input_width + crop.left += pipe->partition->left * input_width / output->width; } diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index 4226403ad235..4a43e7413b68 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -271,23 +271,25 @@ static void uds_configure(struct vsp1_entity *entity, unsigned int vscale; bool multitap; + input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + UDS_PAD_SINK); + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + UDS_PAD_SOURCE); + if (params == VSP1_ENTITY_PARAMS_PARTITION) { - const struct v4l2_rect *clip = &pipe->partition; + struct vsp1_partition *partition = pipe->partition; vsp1_uds_write(uds, dl, VI6_UDS_CLIP_SIZE, - (clip->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | - (clip->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); + (partition->width + << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | + (output->height + << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); return; } if (params != VSP1_ENTITY_PARAMS_INIT) return; - input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, - UDS_PAD_SINK); - output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, - UDS_PAD_SOURCE); - hscale = uds_compute_ratio(input->width, output->width); vscale = uds_compute_ratio(input->height, output->height); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 176fd4b17df5..abbdcafa7c94 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -183,19 +183,19 @@ static int __vsp1_video_try_format(struct vsp1_video *video, */ /** - * vsp1_video_partition - Calculate the active partition output window + * vsp1_video_calculate_partition - Calculate the active partition output window * + * @pipe: the pipeline + * @partition: partition that will hold the calculated values * @div_size: pre-determined maximum partition division size * @index: partition index - * - * Returns a v4l2_rect describing the partition window. */ -static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, - unsigned int div_size, - unsigned int index) +static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int div_size, + unsigned int index) { const struct v4l2_mbus_framefmt *format; - struct v4l2_rect partition; unsigned int modulus; /* @@ -208,18 +208,14 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, /* A single partition simply processes the output size in full. */ if (pipe->partitions <= 1) { - partition.left = 0; - partition.top = 0; - partition.width = format->width; - partition.height = format->height; - return partition; + partition->left = 0; + partition->width = format->width; + return; } /* Initialise the partition with sane starting conditions. */ - partition.left = index * div_size; - partition.top = 0; - partition.width = div_size; - partition.height = format->height; + partition->left = index * div_size; + partition->width = div_size; modulus = format->width % div_size; @@ -242,18 +238,16 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, if (modulus < div_size / 2) { if (index == partitions - 1) { /* Halve the penultimate partition. */ - partition.width = div_size / 2; + partition->width = div_size / 2; } else if (index == partitions) { /* Increase the final partition. */ - partition.width = (div_size / 2) + modulus; - partition.left -= div_size / 2; + partition->width = (div_size / 2) + modulus; + partition->left -= div_size / 2; } } else if (index == partitions) { - partition.width = modulus; + partition->width = modulus; } } - - return partition; } static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) @@ -297,7 +291,8 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) return -ENOMEM; for (i = 0; i < pipe->partitions; ++i) - pipe->part_table[i] = vsp1_video_partition(pipe, div_size, i); + vsp1_video_calculate_partition(pipe, &pipe->part_table[i], + div_size, i); return 0; } @@ -383,7 +378,7 @@ static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, { struct vsp1_entity *entity; - pipe->partition = pipe->part_table[partition]; + pipe->partition = &pipe->part_table[partition]; list_for_each_entry(entity, &pipe->entities, list_pipe) { if (entity->ops->configure) diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 32df109b119f..c8f7cf048841 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -291,7 +291,7 @@ static void wpf_configure(struct vsp1_entity *entity, * multiple slices. */ if (pipe->partitions > 1) - width = pipe->partition.width; + width = pipe->partition->width; vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | @@ -320,13 +320,13 @@ static void wpf_configure(struct vsp1_entity *entity, * is applied horizontally or vertically accordingly. */ if (flip & BIT(WPF_CTRL_HFLIP) && !wpf->flip.rotate) - offset = format->width - pipe->partition.left - - pipe->partition.width; + offset = format->width - pipe->partition->left + - pipe->partition->width; else if (flip & BIT(WPF_CTRL_VFLIP) && wpf->flip.rotate) - offset = format->height - pipe->partition.left - - pipe->partition.width; + offset = format->height - pipe->partition->left + - pipe->partition->width; else - offset = pipe->partition.left; + offset = pipe->partition->left; for (i = 0; i < format->num_planes; ++i) { unsigned int hsub = i > 0 ? fmtinfo->hsub : 1; @@ -348,7 +348,7 @@ static void wpf_configure(struct vsp1_entity *entity, * image height. */ if (wpf->flip.rotate) - height = pipe->partition.width; + height = pipe->partition->width; else height = format->height; -- cgit v1.2.3 From 3609e7ba91a25b70bf15e824727f6dc796f1ba25 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:43 -0400 Subject: media: v4l: vsp1: Provide UDS register updates Provide register definitions required for UDS phase and partition algorithm support. The registers and bits defined here are available on Gen3 hardware only. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_regs.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index cd3e32af6e3b..362f4f8b1148 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -388,6 +388,7 @@ #define VI6_UDS_CTRL_NE_RCR (1 << 18) #define VI6_UDS_CTRL_NE_GY (1 << 17) #define VI6_UDS_CTRL_NE_BCB (1 << 16) +#define VI6_UDS_CTRL_AMDSLH (1 << 2) #define VI6_UDS_CTRL_TDIPC (1 << 1) #define VI6_UDS_SCALE 0x2304 @@ -420,11 +421,24 @@ #define VI6_UDS_PASS_BWIDTH_V_MASK (0x7f << 0) #define VI6_UDS_PASS_BWIDTH_V_SHIFT 0 +#define VI6_UDS_HPHASE 0x2314 +#define VI6_UDS_HPHASE_HSTP_MASK (0xfff << 16) +#define VI6_UDS_HPHASE_HSTP_SHIFT 16 +#define VI6_UDS_HPHASE_HEDP_MASK (0xfff << 0) +#define VI6_UDS_HPHASE_HEDP_SHIFT 0 + #define VI6_UDS_IPC 0x2318 #define VI6_UDS_IPC_FIELD (1 << 27) #define VI6_UDS_IPC_VEDP_MASK (0xfff << 0) #define VI6_UDS_IPC_VEDP_SHIFT 0 +#define VI6_UDS_HSZCLIP 0x231c +#define VI6_UDS_HSZCLIP_HCEN (1 << 28) +#define VI6_UDS_HSZCLIP_HCL_OFST_MASK (0xff << 16) +#define VI6_UDS_HSZCLIP_HCL_OFST_SHIFT 16 +#define VI6_UDS_HSZCLIP_HCL_SIZE_MASK (0x1fff << 0) +#define VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT 0 + #define VI6_UDS_CLIP_SIZE 0x2324 #define VI6_UDS_CLIP_SIZE_HSIZE_MASK (0x1fff << 16) #define VI6_UDS_CLIP_SIZE_HSIZE_SHIFT 16 -- cgit v1.2.3 From ab45e85851829ebb4e233ba5e401affa4128a352 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Fri, 4 Aug 2017 12:32:44 -0400 Subject: media: v4l: vsp1: Allow entities to participate in the partition algorithm The configuration of the pipeline and entities directly affects the inputs required to each entity for the partition algorithm. Thus it makes sense to involve those entities in the decision making process. Extend the entity ops API to provide an optional .partition() operation. This allows entities that affect the partition window to adapt the window based on their configuration. Entities implementing this operation must update the window parameter in place, which will then be passed up the pipeline. This creates a process whereby each entity describes what is required to satisfy the required output to its predecessor in the pipeline. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_entity.h | 7 ++++++ drivers/media/platform/vsp1/vsp1_pipe.c | 22 +++++++++++++++++ drivers/media/platform/vsp1/vsp1_pipe.h | 30 ++++++++++++++++++++-- drivers/media/platform/vsp1/vsp1_rpf.c | 27 +++++++++----------- drivers/media/platform/vsp1/vsp1_sru.c | 26 ++++++++++++++++++++ drivers/media/platform/vsp1/vsp1_uds.c | 41 ++++++++++++++++++++++++++++++- drivers/media/platform/vsp1/vsp1_video.c | 22 +++++++++++------ drivers/media/platform/vsp1/vsp1_wpf.c | 24 ++++++++++++------ 8 files changed, 166 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index c169a060b6d2..05c616883f4a 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h @@ -21,6 +21,8 @@ struct vsp1_device; struct vsp1_dl_list; struct vsp1_pipeline; +struct vsp1_partition; +struct vsp1_partition_window; enum vsp1_entity_type { VSP1_ENTITY_BRU, @@ -81,12 +83,17 @@ struct vsp1_route { * selection rectangles, ...) * @max_width: Return the max supported width of data that the entity can * process in a single operation. + * @partition: Process the partition construction based on this entity's + * configuration. */ struct vsp1_entity_operations { void (*destroy)(struct vsp1_entity *); void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, struct vsp1_dl_list *, enum vsp1_entity_params); unsigned int (*max_width)(struct vsp1_entity *, struct vsp1_pipeline *); + void (*partition)(struct vsp1_entity *, struct vsp1_pipeline *, + struct vsp1_partition *, unsigned int, + struct vsp1_partition_window *); }; struct vsp1_entity { diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index e817623b84e0..eff346727c72 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c @@ -382,6 +382,28 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, vsp1_uds_set_alpha(pipe->uds, dl, alpha); } +/* + * Propagate the partition calculations through the pipeline + * + * Work backwards through the pipe, allowing each entity to update the partition + * parameters based on its configuration, and the entity connected to its + * source. Each entity must produce the partition required for the previous + * entity in the pipeline. + */ +void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int index, + struct vsp1_partition_window *window) +{ + struct vsp1_entity *entity; + + list_for_each_entry_reverse(entity, &pipe->entities, list_pipe) { + if (entity->ops->partition) + entity->ops->partition(entity, pipe, partition, index, + window); + } +} + void vsp1_pipelines_suspend(struct vsp1_device *vsp1) { unsigned long flags; diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 4e9fd96108be..424e43fafaa5 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -58,16 +58,32 @@ enum vsp1_pipeline_state { }; /* - * struct vsp1_partition - A description of a slice for the partition algorithm + * struct vsp1_partition_window - Partition window coordinates * @left: horizontal coordinate of the partition start in pixels relative to the * left edge of the image * @width: partition width in pixels */ -struct vsp1_partition { +struct vsp1_partition_window { unsigned int left; unsigned int width; }; +/* + * struct vsp1_partition - A description of a slice for the partition algorithm + * @rpf: The RPF partition window configuration + * @uds_sink: The UDS input partition window configuration + * @uds_source: The UDS output partition window configuration + * @sru: The SRU partition window configuration + * @wpf: The WPF partition window configuration + */ +struct vsp1_partition { + struct vsp1_partition_window rpf; + struct vsp1_partition_window uds_sink; + struct vsp1_partition_window uds_source; + struct vsp1_partition_window sru; + struct vsp1_partition_window wpf; +}; + /* * struct vsp1_pipeline - A VSP1 hardware pipeline * @pipe: the media pipeline @@ -120,6 +136,11 @@ struct vsp1_pipeline { struct vsp1_entity *uds; struct vsp1_entity *uds_input; + /* + * The order of this list must be identical to the order of the entities + * in the pipeline, as it is assumed by the partition algorithm that we + * can walk this list in sequence. + */ struct list_head entities; struct vsp1_dl_list *dl; @@ -142,6 +163,11 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe); void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, struct vsp1_dl_list *dl, unsigned int alpha); +void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int index, + struct vsp1_partition_window *window); + void vsp1_pipelines_suspend(struct vsp1_device *vsp1); void vsp1_pipelines_resume(struct vsp1_device *vsp1); diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 126741f00ae3..fe0633da5a5f 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -97,21 +97,8 @@ static void rpf_configure(struct vsp1_entity *entity, * 'width' need to be adjusted. */ if (pipe->partitions > 1) { - const struct v4l2_mbus_framefmt *output; - struct vsp1_entity *wpf = &pipe->output->entity; - unsigned int input_width = crop.width; - - /* - * Scale the partition window based on the configuration - * of the pipeline. - */ - output = vsp1_entity_get_pad_format(wpf, wpf->config, - RWPF_PAD_SINK); - - crop.width = pipe->partition->width * input_width - / output->width; - crop.left += pipe->partition->left * input_width - / output->width; + crop.width = pipe->partition->rpf.width; + crop.left += pipe->partition->rpf.left; } vsp1_rpf_write(rpf, dl, VI6_RPF_SRC_BSIZE, @@ -260,8 +247,18 @@ static void rpf_configure(struct vsp1_entity *entity, } +static void rpf_partition(struct vsp1_entity *entity, + struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int partition_idx, + struct vsp1_partition_window *window) +{ + partition->rpf = *window; +} + static const struct vsp1_entity_operations rpf_entity_ops = { .configure = rpf_configure, + .partition = rpf_partition, }; /* ----------------------------------------------------------------------------- diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c index 30142793dfcd..51e5691187c3 100644 --- a/drivers/media/platform/vsp1/vsp1_sru.c +++ b/drivers/media/platform/vsp1/vsp1_sru.c @@ -18,6 +18,7 @@ #include "vsp1.h" #include "vsp1_dl.h" +#include "vsp1_pipe.h" #include "vsp1_sru.h" #define SRU_MIN_SIZE 4U @@ -325,9 +326,34 @@ static unsigned int sru_max_width(struct vsp1_entity *entity, return 256; } +static void sru_partition(struct vsp1_entity *entity, + struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int partition_idx, + struct vsp1_partition_window *window) +{ + struct vsp1_sru *sru = to_sru(&entity->subdev); + struct v4l2_mbus_framefmt *input; + struct v4l2_mbus_framefmt *output; + + input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + SRU_PAD_SINK); + output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, + SRU_PAD_SOURCE); + + /* Adapt if SRUx2 is enabled */ + if (input->width != output->width) { + window->width /= 2; + window->left /= 2; + } + + partition->sru = *window; +} + static const struct vsp1_entity_operations sru_entity_ops = { .configure = sru_configure, .max_width = sru_max_width, + .partition = sru_partition, }; /* ----------------------------------------------------------------------------- diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index 4a43e7413b68..72f72a9d2152 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -279,8 +279,15 @@ static void uds_configure(struct vsp1_entity *entity, if (params == VSP1_ENTITY_PARAMS_PARTITION) { struct vsp1_partition *partition = pipe->partition; + /* Input size clipping */ + vsp1_uds_write(uds, dl, VI6_UDS_HSZCLIP, VI6_UDS_HSZCLIP_HCEN | + (0 << VI6_UDS_HSZCLIP_HCL_OFST_SHIFT) | + (partition->uds_sink.width + << VI6_UDS_HSZCLIP_HCL_SIZE_SHIFT)); + + /* Output size clipping */ vsp1_uds_write(uds, dl, VI6_UDS_CLIP_SIZE, - (partition->width + (partition->uds_source.width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | (output->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); @@ -345,9 +352,41 @@ static unsigned int uds_max_width(struct vsp1_entity *entity, return 2048; } +/* ----------------------------------------------------------------------------- + * Partition Algorithm Support + */ + +static void uds_partition(struct vsp1_entity *entity, + struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int partition_idx, + struct vsp1_partition_window *window) +{ + struct vsp1_uds *uds = to_uds(&entity->subdev); + const struct v4l2_mbus_framefmt *output; + const struct v4l2_mbus_framefmt *input; + + /* Initialise the partition state */ + partition->uds_sink = *window; + partition->uds_source = *window; + + input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + UDS_PAD_SINK); + output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, + UDS_PAD_SOURCE); + + partition->uds_sink.width = window->width * input->width + / output->width; + partition->uds_sink.left = window->left * input->width + / output->width; + + *window = partition->uds_sink; +} + static const struct vsp1_entity_operations uds_entity_ops = { .configure = uds_configure, .max_width = uds_max_width, + .partition = uds_partition, }; /* ----------------------------------------------------------------------------- diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index abbdcafa7c94..ab53132ad3fa 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -196,6 +196,7 @@ static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe, unsigned int index) { const struct v4l2_mbus_framefmt *format; + struct vsp1_partition_window window; unsigned int modulus; /* @@ -208,14 +209,17 @@ static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe, /* A single partition simply processes the output size in full. */ if (pipe->partitions <= 1) { - partition->left = 0; - partition->width = format->width; + window.left = 0; + window.width = format->width; + + vsp1_pipeline_propagate_partition(pipe, partition, index, + &window); return; } /* Initialise the partition with sane starting conditions. */ - partition->left = index * div_size; - partition->width = div_size; + window.left = index * div_size; + window.width = div_size; modulus = format->width % div_size; @@ -238,16 +242,18 @@ static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe, if (modulus < div_size / 2) { if (index == partitions - 1) { /* Halve the penultimate partition. */ - partition->width = div_size / 2; + window.width = div_size / 2; } else if (index == partitions) { /* Increase the final partition. */ - partition->width = (div_size / 2) + modulus; - partition->left -= div_size / 2; + window.width = (div_size / 2) + modulus; + window.left -= div_size / 2; } } else if (index == partitions) { - partition->width = modulus; + window.width = modulus; } } + + vsp1_pipeline_propagate_partition(pipe, partition, index, &window); } static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index c8f7cf048841..0b882074315e 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -291,7 +291,7 @@ static void wpf_configure(struct vsp1_entity *entity, * multiple slices. */ if (pipe->partitions > 1) - width = pipe->partition->width; + width = pipe->partition->wpf.width; vsp1_wpf_write(wpf, dl, VI6_WPF_HSZCLIP, VI6_WPF_SZCLIP_EN | (0 << VI6_WPF_SZCLIP_OFST_SHIFT) | @@ -320,13 +320,13 @@ static void wpf_configure(struct vsp1_entity *entity, * is applied horizontally or vertically accordingly. */ if (flip & BIT(WPF_CTRL_HFLIP) && !wpf->flip.rotate) - offset = format->width - pipe->partition->left - - pipe->partition->width; + offset = format->width - pipe->partition->wpf.left + - pipe->partition->wpf.width; else if (flip & BIT(WPF_CTRL_VFLIP) && wpf->flip.rotate) - offset = format->height - pipe->partition->left - - pipe->partition->width; + offset = format->height - pipe->partition->wpf.left + - pipe->partition->wpf.width; else - offset = pipe->partition->left; + offset = pipe->partition->wpf.left; for (i = 0; i < format->num_planes; ++i) { unsigned int hsub = i > 0 ? fmtinfo->hsub : 1; @@ -348,7 +348,7 @@ static void wpf_configure(struct vsp1_entity *entity, * image height. */ if (wpf->flip.rotate) - height = pipe->partition->width; + height = pipe->partition->wpf.width; else height = format->height; @@ -471,10 +471,20 @@ static unsigned int wpf_max_width(struct vsp1_entity *entity, return wpf->flip.rotate ? 256 : wpf->max_width; } +static void wpf_partition(struct vsp1_entity *entity, + struct vsp1_pipeline *pipe, + struct vsp1_partition *partition, + unsigned int partition_idx, + struct vsp1_partition_window *window) +{ + partition->wpf = *window; +} + static const struct vsp1_entity_operations wpf_entity_ops = { .destroy = vsp1_wpf_destroy, .configure = wpf_configure, .max_width = wpf_max_width, + .partition = wpf_partition, }; /* ----------------------------------------------------------------------------- -- cgit v1.2.3 From 265a2988d202b3aba0bbbb4d828c66d3741d59db Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Thu, 22 Jun 2017 15:23:54 -0400 Subject: media: rc-core: consistent use of rc_repeat() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NEC decoder and the Sanyo decoders check if dev->keypressed is true before calling rc_repeat (without holding dev->keylock). Meanwhile, the XMP and JVC decoders do no such checks. This patch makes sure all users of rc_repeat() do so consistently by removing extra checks in NEC/Sanyo and modifying the check a bit in rc_repeat() so that no input event is generated if the key isn't pressed. Signed-off-by: David Härdeman Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-nec-decoder.c | 10 +++------- drivers/media/rc/ir-sanyo-decoder.c | 10 +++------- drivers/media/rc/rc-main.c | 6 +++--- 3 files changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 3ce850314dca..75b9137f6faf 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -88,13 +88,9 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { - if (!dev->keypressed) { - IR_dprintk(1, "Discarding last key repeat: event after key up\n"); - } else { - rc_repeat(dev); - IR_dprintk(1, "Repeat last key\n"); - data->state = STATE_TRAILER_PULSE; - } + rc_repeat(dev); + IR_dprintk(1, "Repeat last key\n"); + data->state = STATE_TRAILER_PULSE; return 0; } diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index 520bb77dcb62..e6a906a34f90 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -110,13 +110,9 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) break; if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { - if (!dev->keypressed) { - IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n"); - } else { - rc_repeat(dev); - IR_dprintk(1, "SANYO repeat last key\n"); - data->state = STATE_INACTIVE; - } + rc_repeat(dev); + IR_dprintk(1, "SANYO repeat last key\n"); + data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index a9eba0013525..7387bd4d75b0 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -616,12 +616,12 @@ void rc_repeat(struct rc_dev *dev) spin_lock_irqsave(&dev->keylock, flags); - input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); - input_sync(dev->input_dev); - if (!dev->keypressed) goto out; + input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); + input_sync(dev->input_dev); + dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); -- cgit v1.2.3 From 50c3c1ba171f3f68f2aa820121517deb5211e7ee Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Fri, 30 Jun 2017 02:03:05 -0400 Subject: media: rc: mtk-cir: add platform data to adapt into various hardware This patch is the preparation patch in order to adapt into various hardware through adding platform data which holds specific characteristics and differences among MediaTek supported CIR devices instead of the old way defining those data in the static way as macro has. And the existing logic would be slightly changed to operate on those data which the actual device depends on. Signed-off-by: Sean Wang Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mtk-cir.c | 221 +++++++++++++++++++++++++++++++++------------ 1 file changed, 165 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index f1e164e441e8..32b1031f08c9 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -25,35 +25,28 @@ /* Register to enable PWM and IR */ #define MTK_CONFIG_HIGH_REG 0x0c -/* Enable IR pulse width detection */ + +/* Bit to enable IR pulse width detection */ #define MTK_PWM_EN BIT(13) -/* Enable IR hardware function */ -#define MTK_IR_EN BIT(0) -/* Register to setting sample period */ -#define MTK_CONFIG_LOW_REG 0x10 -/* Field to set sample period */ -#define CHK_PERIOD DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, \ - MTK_IR_CLK_PERIOD) -#define MTK_CHK_PERIOD (((CHK_PERIOD) << 8) & (GENMASK(20, 8))) -#define MTK_CHK_PERIOD_MASK (GENMASK(20, 8)) +/* + * Register to setting ok count whose unit based on hardware sampling period + * indicating IR receiving completion and then making IRQ fires + */ +#define MTK_OK_COUNT(x) (((x) & GENMASK(23, 16)) << 16) + +/* Bit to enable IR hardware function */ +#define MTK_IR_EN BIT(0) -/* Register to clear state of state machine */ -#define MTK_IRCLR_REG 0x20 /* Bit to restart IR receiving */ #define MTK_IRCLR BIT(0) -/* Register containing pulse width data */ -#define MTK_CHKDATA_REG(i) (0x88 + 4 * (i)) +/* Fields containing pulse width data */ #define MTK_WIDTH_MASK (GENMASK(7, 0)) -/* Register to enable IR interrupt */ -#define MTK_IRINT_EN_REG 0xcc /* Bit to enable interrupt */ #define MTK_IRINT_EN BIT(0) -/* Register to ack IR interrupt */ -#define MTK_IRINT_CLR_REG 0xd0 /* Bit to clear interrupt status */ #define MTK_IRINT_CLR BIT(0) @@ -63,24 +56,73 @@ #define MTK_IR_END(v, p) ((v) == MTK_MAX_SAMPLES && (p) == 0) /* Number of registers to record the pulse width */ #define MTK_CHKDATA_SZ 17 -/* Source clock frequency */ -#define MTK_IR_BASE_CLK 273000000 -/* Frequency after IR internal divider */ -#define MTK_IR_CLK_FREQ (MTK_IR_BASE_CLK / 4) -/* Period for MTK_IR_CLK in ns*/ -#define MTK_IR_CLK_PERIOD DIV_ROUND_CLOSEST(1000000000ul, \ - MTK_IR_CLK_FREQ) /* Sample period in ns */ -#define MTK_IR_SAMPLE (MTK_IR_CLK_PERIOD * 0xc00) +#define MTK_IR_SAMPLE 46000 + +enum mtk_fields { + /* Register to setting software sampling period */ + MTK_CHK_PERIOD, + /* Register to setting hardware sampling period */ + MTK_HW_PERIOD, +}; + +enum mtk_regs { + /* Register to clear state of state machine */ + MTK_IRCLR_REG, + /* Register containing pulse width data */ + MTK_CHKDATA_REG, + /* Register to enable IR interrupt */ + MTK_IRINT_EN_REG, + /* Register to ack IR interrupt */ + MTK_IRINT_CLR_REG +}; + +static const u32 mt7623_regs[] = { + [MTK_IRCLR_REG] = 0x20, + [MTK_CHKDATA_REG] = 0x88, + [MTK_IRINT_EN_REG] = 0xcc, + [MTK_IRINT_CLR_REG] = 0xd0, +}; + +struct mtk_field_type { + u32 reg; + u8 offset; + u32 mask; +}; + +/* + * struct mtk_ir_data - This is the structure holding all differences among + various hardwares + * @regs: The pointer to the array holding registers offset + * @fields: The pointer to the array holding fields location + * @div: The internal divisor for the based reference clock + * @ok_count: The count indicating the completion of IR data + * receiving when count is reached + * @hw_period: The value indicating the hardware sampling period + */ +struct mtk_ir_data { + const u32 *regs; + const struct mtk_field_type *fields; + u8 div; + u8 ok_count; + u32 hw_period; +}; + +static const struct mtk_field_type mt7623_fields[] = { + [MTK_CHK_PERIOD] = {0x10, 8, GENMASK(20, 8)}, + [MTK_HW_PERIOD] = {0x10, 0, GENMASK(7, 0)}, +}; /* * struct mtk_ir - This is the main datasructure for holding the state * of the driver * @dev: The device pointer * @rc: The rc instrance - * @irq: The IRQ that we are using * @base: The mapped register i/o base - * @clk: The clock that we are using + * @irq: The IRQ that we are using + * @clk: The clock that IR internal is using + * @bus: The clock that software decoder is using + * @data: Holding specific data for vaious platform */ struct mtk_ir { struct device *dev; @@ -88,8 +130,36 @@ struct mtk_ir { void __iomem *base; int irq; struct clk *clk; + struct clk *bus; + const struct mtk_ir_data *data; }; +static inline u32 mtk_chkdata_reg(struct mtk_ir *ir, u32 i) +{ + return ir->data->regs[MTK_CHKDATA_REG] + 4 * i; +} + +static inline u32 mtk_chk_period(struct mtk_ir *ir) +{ + u32 val; + + /* Period of raw software sampling in ns */ + val = DIV_ROUND_CLOSEST(1000000000ul, + clk_get_rate(ir->bus) / ir->data->div); + + /* + * Period for software decoder used in the + * unit of raw software sampling + */ + val = DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, val); + + dev_dbg(ir->dev, "@pwm clk = \t%lu\n", + clk_get_rate(ir->bus) / ir->data->div); + dev_dbg(ir->dev, "@chkperiod = %08x\n", val); + + return val; +} + static void mtk_w32_mask(struct mtk_ir *ir, u32 val, u32 mask, unsigned int reg) { u32 tmp; @@ -113,16 +183,16 @@ static inline void mtk_irq_disable(struct mtk_ir *ir, u32 mask) { u32 val; - val = mtk_r32(ir, MTK_IRINT_EN_REG); - mtk_w32(ir, val & ~mask, MTK_IRINT_EN_REG); + val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]); + mtk_w32(ir, val & ~mask, ir->data->regs[MTK_IRINT_EN_REG]); } static inline void mtk_irq_enable(struct mtk_ir *ir, u32 mask) { u32 val; - val = mtk_r32(ir, MTK_IRINT_EN_REG); - mtk_w32(ir, val | mask, MTK_IRINT_EN_REG); + val = mtk_r32(ir, ir->data->regs[MTK_IRINT_EN_REG]); + mtk_w32(ir, val | mask, ir->data->regs[MTK_IRINT_EN_REG]); } static irqreturn_t mtk_ir_irq(int irqno, void *dev_id) @@ -140,7 +210,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id) * every decoder to reset themselves through long enough * trailing spaces and 2) the IRQ handler guarantees that * start of IR message is always contained in and starting - * from register MTK_CHKDATA_REG(0). + * from register mtk_chkdata_reg(ir, i). */ ir_raw_event_reset(ir->rc); @@ -149,7 +219,7 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id) /* Handle all pulse and space IR controller captures */ for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) { - val = mtk_r32(ir, MTK_CHKDATA_REG(i)); + val = mtk_r32(ir, mtk_chkdata_reg(ir, i)); dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val); for (j = 0 ; j < 4 ; j++) { @@ -181,18 +251,35 @@ static irqreturn_t mtk_ir_irq(int irqno, void *dev_id) * Restart controller for the next receive that would * clear up all CHKDATA registers */ - mtk_w32_mask(ir, 0x1, MTK_IRCLR, MTK_IRCLR_REG); + mtk_w32_mask(ir, 0x1, MTK_IRCLR, ir->data->regs[MTK_IRCLR_REG]); /* Clear interrupt status */ - mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, MTK_IRINT_CLR_REG); + mtk_w32_mask(ir, 0x1, MTK_IRINT_CLR, + ir->data->regs[MTK_IRINT_CLR_REG]); return IRQ_HANDLED; } +static const struct mtk_ir_data mt7623_data = { + .regs = mt7623_regs, + .fields = mt7623_fields, + .ok_count = 0xf, + .hw_period = 0xff, + .div = 4, +}; + +static const struct of_device_id mtk_ir_match[] = { + { .compatible = "mediatek,mt7623-cir", .data = &mt7623_data}, + {}, +}; +MODULE_DEVICE_TABLE(of, mtk_ir_match); + static int mtk_ir_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *dn = dev->of_node; + const struct of_device_id *of_id = + of_match_device(mtk_ir_match, &pdev->dev); struct resource *res; struct mtk_ir *ir; u32 val; @@ -204,9 +291,7 @@ static int mtk_ir_probe(struct platform_device *pdev) return -ENOMEM; ir->dev = dev; - - if (!of_device_is_compatible(dn, "mediatek,mt7623-cir")) - return -ENODEV; + ir->data = of_id->data; ir->clk = devm_clk_get(dev, "clk"); if (IS_ERR(ir->clk)) { @@ -214,6 +299,15 @@ static int mtk_ir_probe(struct platform_device *pdev) return PTR_ERR(ir->clk); } + ir->bus = devm_clk_get(dev, "bus"); + if (IS_ERR(ir->bus)) { + /* + * For compatibility with older device trees try unnamed + * ir->bus uses the same clock as ir->clock. + */ + ir->bus = ir->clk; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ir->base = devm_ioremap_resource(dev, res); if (IS_ERR(ir->base)) { @@ -256,40 +350,60 @@ static int mtk_ir_probe(struct platform_device *pdev) return -ENODEV; } - /* - * Enable interrupt after proper hardware - * setup and IRQ handler registration - */ if (clk_prepare_enable(ir->clk)) { + dev_err(dev, "try to enable ir_clk failed\n"); + return -EINVAL; + } + + if (clk_prepare_enable(ir->bus)) { dev_err(dev, "try to enable ir_clk failed\n"); ret = -EINVAL; goto exit_clkdisable_clk; } + /* + * Enable interrupt after proper hardware + * setup and IRQ handler registration + */ mtk_irq_disable(ir, MTK_IRINT_EN); ret = devm_request_irq(dev, ir->irq, mtk_ir_irq, 0, MTK_IR_DEV, ir); if (ret) { dev_err(dev, "failed request irq\n"); - goto exit_clkdisable_clk; + goto exit_clkdisable_bus; } + /* + * Setup software sample period as the reference of software decoder + */ + val = (mtk_chk_period(ir) << ir->data->fields[MTK_CHK_PERIOD].offset) & + ir->data->fields[MTK_CHK_PERIOD].mask; + mtk_w32_mask(ir, val, ir->data->fields[MTK_CHK_PERIOD].mask, + ir->data->fields[MTK_CHK_PERIOD].reg); + + /* + * Setup hardware sampling period used to setup the proper timeout for + * indicating end of IR receiving completion + */ + val = (ir->data->hw_period << ir->data->fields[MTK_HW_PERIOD].offset) & + ir->data->fields[MTK_HW_PERIOD].mask; + mtk_w32_mask(ir, val, ir->data->fields[MTK_HW_PERIOD].mask, + ir->data->fields[MTK_HW_PERIOD].reg); + /* Enable IR and PWM */ val = mtk_r32(ir, MTK_CONFIG_HIGH_REG); - val |= MTK_PWM_EN | MTK_IR_EN; + val |= MTK_OK_COUNT(ir->data->ok_count) | MTK_PWM_EN | MTK_IR_EN; mtk_w32(ir, val, MTK_CONFIG_HIGH_REG); - /* Setting sample period */ - mtk_w32_mask(ir, MTK_CHK_PERIOD, MTK_CHK_PERIOD_MASK, - MTK_CONFIG_LOW_REG); - mtk_irq_enable(ir, MTK_IRINT_EN); - dev_info(dev, "Initialized MT7623 IR driver, sample period = %luus\n", + dev_info(dev, "Initialized MT7623 IR driver, sample period = %dus\n", DIV_ROUND_CLOSEST(MTK_IR_SAMPLE, 1000)); return 0; +exit_clkdisable_bus: + clk_disable_unprepare(ir->bus); exit_clkdisable_clk: clk_disable_unprepare(ir->clk); @@ -308,17 +422,12 @@ static int mtk_ir_remove(struct platform_device *pdev) mtk_irq_disable(ir, MTK_IRINT_EN); synchronize_irq(ir->irq); + clk_disable_unprepare(ir->bus); clk_disable_unprepare(ir->clk); return 0; } -static const struct of_device_id mtk_ir_match[] = { - { .compatible = "mediatek,mt7623-cir" }, - {}, -}; -MODULE_DEVICE_TABLE(of, mtk_ir_match); - static struct platform_driver mtk_ir_driver = { .probe = mtk_ir_probe, .remove = mtk_ir_remove, -- cgit v1.2.3 From 583899828c607e59f51ce818f8e5de6996ad2ef7 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Fri, 30 Jun 2017 02:03:06 -0400 Subject: media: rc: mtk-cir: add support for MediaTek MT7622 SoC This patch adds driver for CIR controller on MT7622 SoC. It has similar handling logic as the previously MT7623 does, but there are some differences in the register and field definition. So for ease portability and maintenance, those differences all are being kept inside the platform data as other drivers usually do. Currently testing successfully on NEC and SONY remote controller. Signed-off-by: Sean Wang Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mtk-cir.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index 32b1031f08c9..667277205fee 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -84,6 +84,13 @@ static const u32 mt7623_regs[] = { [MTK_IRINT_CLR_REG] = 0xd0, }; +static const u32 mt7622_regs[] = { + [MTK_IRCLR_REG] = 0x18, + [MTK_CHKDATA_REG] = 0x30, + [MTK_IRINT_EN_REG] = 0x1c, + [MTK_IRINT_CLR_REG] = 0x20, +}; + struct mtk_field_type { u32 reg; u8 offset; @@ -113,6 +120,11 @@ static const struct mtk_field_type mt7623_fields[] = { [MTK_HW_PERIOD] = {0x10, 0, GENMASK(7, 0)}, }; +static const struct mtk_field_type mt7622_fields[] = { + [MTK_CHK_PERIOD] = {0x24, 0, GENMASK(24, 0)}, + [MTK_HW_PERIOD] = {0x10, 0, GENMASK(24, 0)}, +}; + /* * struct mtk_ir - This is the main datasructure for holding the state * of the driver @@ -268,8 +280,17 @@ static const struct mtk_ir_data mt7623_data = { .div = 4, }; +static const struct mtk_ir_data mt7622_data = { + .regs = mt7622_regs, + .fields = mt7622_fields, + .ok_count = 0xf, + .hw_period = 0xffff, + .div = 32, +}; + static const struct of_device_id mtk_ir_match[] = { { .compatible = "mediatek,mt7623-cir", .data = &mt7623_data}, + { .compatible = "mediatek,mt7622-cir", .data = &mt7622_data}, {}, }; MODULE_DEVICE_TABLE(of, mtk_ir_match); -- cgit v1.2.3 From b9e1486e0e4b5e0fc0cde214ceecec8a5734f620 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 2 Jul 2017 15:37:58 -0400 Subject: media: rc-core: do not depend on MEDIA_SUPPORT There is no dependency between the two, so remove the dependency in Kconfig files. Signed-off-by: Sean Young Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/arm/configs/imx_v6_v7_defconfig | 2 +- arch/arm/configs/omap2plus_defconfig | 2 +- arch/arm/configs/sunxi_defconfig | 2 +- arch/mips/configs/pistachio_defconfig | 2 +- drivers/media/Kconfig | 17 ++--------------- drivers/media/rc/Kconfig | 19 ++++++++++++++++--- 6 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index e74de69caeab..1736813bdea7 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -226,7 +226,7 @@ CONFIG_REGULATOR_MC13892=y CONFIG_REGULATOR_PFUZE100=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y CONFIG_RC_DEVICES=y CONFIG_IR_GPIO_CIR=y CONFIG_MEDIA_USB_SUPPORT=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index a120ae816260..0414acf731ce 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -304,7 +304,7 @@ CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TWL4030=y CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=m CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_LIRC=m diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 0ec1d1ec130f..22cd559531a9 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -95,7 +95,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y CONFIG_RC_DEVICES=y CONFIG_IR_SUNXI=y CONFIG_DRM=y diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 7d32fbbca962..3598d58aac30 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -207,7 +207,7 @@ CONFIG_IMGPDC_WDT=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y # CONFIG_RC_DECODERS is not set CONFIG_RC_DEVICES=y CONFIG_IR_IMG=y diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 94d4e7759127..edfe99b22d56 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -11,6 +11,8 @@ config CEC_NOTIFIER config CEC_PIN bool +source "drivers/media/rc/Kconfig" + menuconfig MEDIA_SUPPORT tristate "Multimedia support" depends on HAS_IOMEM @@ -75,20 +77,6 @@ config MEDIA_SDR_SUPPORT Say Y when you have a software defined radio device. -config MEDIA_RC_SUPPORT - bool "Remote Controller support" - depends on INPUT - ---help--- - Enable support for Remote Controllers on Linux. This is - needed in order to support several video capture adapters, - standalone IR receivers/transmitters, and RF receivers. - - Enable this option if you have a video capture board even - if you don't need IR, as otherwise, you may not be able to - compile the driver for your adapter. - - Say Y when you have a TV or an IR device. - config MEDIA_CEC_SUPPORT bool "HDMI CEC support" ---help--- @@ -178,7 +166,6 @@ config TTPCI_EEPROM source "drivers/media/dvb-core/Kconfig" comment "Media drivers" -source "drivers/media/rc/Kconfig" # # V4L platform/mem2mem drivers diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 5e83b76495f7..b6433c57a024 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -1,9 +1,20 @@ -config RC_CORE - tristate - depends on MEDIA_RC_SUPPORT + +menuconfig RC_CORE + tristate "Remote Controller support" depends on INPUT default y + ---help--- + Enable support for Remote Controllers on Linux. This is + needed in order to support several video capture adapters, + standalone IR receivers/transmitters, and RF receivers. + + Enable this option if you have a video capture board even + if you don't need IR, as otherwise, you may not be able to + compile the driver for your adapter. + Say Y when you have a TV or an IR device. + +if RC_CORE source "drivers/media/rc/keymaps/Kconfig" menuconfig RC_DECODERS @@ -436,3 +447,5 @@ config IR_SIR be called sir-ir. endif #RC_DEVICES + +endif #RC_CORE -- cgit v1.2.3 From 6efa09436939ec10f966577f0f7fd706a8420693 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 5 Jul 2017 14:16:04 -0400 Subject: media: sir_ir: remove unnecessary static in sir_interrupt() Remove unnecessary static on local variable delt. Such variable is initialized before being used, on every execution path throughout the function. The static has no benefit and, removing it reduces the code size. This issue was detected using Coccinelle and the following semantic patch: @bad exists@ position p; identifier x; type T; @@ static T x@p; ... x = <+...x...+> @@ identifier x; expression e; type T; position p != bad.p; @@ -static T x@p; ... when != x when strict ?x = e; In the following log you can see the difference in the code size. Also, there is a significant difference in the bss segment. This log is the output of the size command, before and after the code change: before: text data bss dec hex filename 5009 3456 576 9041 2351 drivers/media/rc/sir_ir.o after: text data bss dec hex filename 4988 3400 512 8900 22c4 drivers/media/rc/sir_ir.o Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/sir_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index 20234ba0b318..be67f7c9a75b 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -155,7 +155,7 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id) { unsigned char data; ktime_t curr_time; - static unsigned long delt; + unsigned long delt; unsigned long deltintr; unsigned long flags; int counter = 0; -- cgit v1.2.3 From d9a77b98df6be6a84f461753c504740fe4669c96 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 7 Jul 2017 04:15:12 -0400 Subject: media: imon: constify attribute_group structures attribute_groups are not supposed to change at runtime. All functions working with attribute_groups provided by work with const attribute_group. So mark the non-const structs as const. File size before: text data bss dec hex filename 18551 2256 77 20884 5194 drivers/media/rc/imon.o File size After adding 'const': text data bss dec hex filename 18679 2160 77 20916 51b4 drivers/media/rc/imon.o Signed-off-by: Arvind Yadav Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index bd76534a2749..717ba782d7a7 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -911,7 +911,7 @@ static struct attribute *imon_display_sysfs_entries[] = { NULL }; -static struct attribute_group imon_display_attr_group = { +static const struct attribute_group imon_display_attr_group = { .attrs = imon_display_sysfs_entries }; @@ -920,7 +920,7 @@ static struct attribute *imon_rf_sysfs_entries[] = { NULL }; -static struct attribute_group imon_rf_attr_group = { +static const struct attribute_group imon_rf_attr_group = { .attrs = imon_rf_sysfs_entries }; -- cgit v1.2.3 From db68102c8d5eeea173ae4187b4e581fa146bc094 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 7 Jul 2017 04:23:54 -0400 Subject: media: rc: constify attribute_group structures attribute_groups are not supposed to change at runtime. All functions working with attribute_groups provided by work with const attribute_group. So mark the non-const structs as const. File size before: text data bss dec hex filename 11605 880 20 12505 30d9 drivers/media/rc/rc-main.o File size After adding 'const': text data bss dec hex filename 11797 720 20 12537 30f9 drivers/media/rc/rc-main.o Signed-off-by: Arvind Yadav Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7387bd4d75b0..33c04ccccdff 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1507,7 +1507,7 @@ static struct attribute *rc_dev_protocol_attrs[] = { NULL, }; -static struct attribute_group rc_dev_protocol_attr_grp = { +static const struct attribute_group rc_dev_protocol_attr_grp = { .attrs = rc_dev_protocol_attrs, }; @@ -1517,7 +1517,7 @@ static struct attribute *rc_dev_filter_attrs[] = { NULL, }; -static struct attribute_group rc_dev_filter_attr_grp = { +static const struct attribute_group rc_dev_filter_attr_grp = { .attrs = rc_dev_filter_attrs, }; @@ -1528,7 +1528,7 @@ static struct attribute *rc_dev_wakeup_filter_attrs[] = { NULL, }; -static struct attribute_group rc_dev_wakeup_filter_attr_grp = { +static const struct attribute_group rc_dev_wakeup_filter_attr_grp = { .attrs = rc_dev_wakeup_filter_attrs, }; -- cgit v1.2.3 From 518f4b26be1ebf6ce220c4e37b5c7e5410c4d064 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 1 Jul 2017 12:13:19 -0400 Subject: media: rc-core: rename input_name to device_name When an ir-spi is registered, you get this message. rc rc0: Unspecified device as /devices/platform/soc/3f215080.spi/spi_master/spi32766/spi32766.128/rc/rc0 "Unspecified device" refers to input_name, which makes no sense for IR TX only devices. So, rename to device_name. Also make driver_name const char* so that no casts are needed anywhere. Now ir-spi reports: rc rc0: IR SPI as /devices/platform/soc/3f215080.spi/spi_master/spi32766/spi32766.128/rc/rc0 Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-picolcd_cir.c | 2 +- drivers/media/cec/cec-core.c | 4 ++-- drivers/media/common/siano/smsir.c | 4 ++-- drivers/media/i2c/ir-kbd-i2c.c | 2 +- drivers/media/pci/bt8xx/bttv-input.c | 2 +- drivers/media/pci/cx23885/cx23885-input.c | 2 +- drivers/media/pci/cx88/cx88-input.c | 2 +- drivers/media/pci/dm1105/dm1105.c | 2 +- drivers/media/pci/mantis/mantis_common.h | 2 +- drivers/media/pci/mantis/mantis_input.c | 4 ++-- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/pci/smipcie/smipcie-ir.c | 4 ++-- drivers/media/pci/smipcie/smipcie.h | 2 +- drivers/media/pci/ttpci/budget-ci.c | 2 +- drivers/media/rc/ati_remote.c | 2 +- drivers/media/rc/ene_ir.c | 4 ++-- drivers/media/rc/fintek-cir.c | 2 +- drivers/media/rc/gpio-ir-recv.c | 2 +- drivers/media/rc/igorplugusb.c | 2 +- drivers/media/rc/iguanair.c | 2 +- drivers/media/rc/img-ir/img-ir-hw.c | 2 +- drivers/media/rc/img-ir/img-ir-raw.c | 2 +- drivers/media/rc/imon.c | 2 +- drivers/media/rc/ir-hix5hd2.c | 2 +- drivers/media/rc/ir-spi.c | 1 + drivers/media/rc/ite-cir.c | 2 +- drivers/media/rc/mceusb.c | 2 +- drivers/media/rc/meson-ir.c | 2 +- drivers/media/rc/mtk-cir.c | 2 +- drivers/media/rc/nuvoton-cir.c | 2 +- drivers/media/rc/rc-loopback.c | 2 +- drivers/media/rc/rc-main.c | 8 ++++---- drivers/media/rc/redrat3.c | 2 +- drivers/media/rc/serial_ir.c | 10 +++++----- drivers/media/rc/sir_ir.c | 2 +- drivers/media/rc/st_rc.c | 2 +- drivers/media/rc/streamzap.c | 2 +- drivers/media/rc/sunxi-cir.c | 2 +- drivers/media/rc/ttusbir.c | 2 +- drivers/media/rc/winbond-cir.c | 2 +- drivers/media/usb/au0828/au0828-input.c | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 5 ++--- drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 +- drivers/media/usb/em28xx/em28xx-input.c | 2 +- drivers/media/usb/tm6000/tm6000-input.c | 2 +- include/media/cec.h | 2 +- include/media/rc-core.h | 6 +++--- 47 files changed, 62 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 8ffbb6f65a65..b3b2233f3c65 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -116,7 +116,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; rdev->open = picolcd_cir_open; rdev->close = picolcd_cir_close; - rdev->input_name = data->hdev->name; + rdev->device_name = data->hdev->name; rdev->input_phys = data->hdev->phys; rdev->input_id.bustype = data->hdev->bus; rdev->input_id.vendor = data->hdev->vendor; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index 52f085ba104a..efb7bbbc941f 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -263,12 +263,12 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, return ERR_PTR(-ENOMEM); } - snprintf(adap->input_name, sizeof(adap->input_name), + snprintf(adap->device_name, sizeof(adap->device_name), "RC for %s", name); snprintf(adap->input_phys, sizeof(adap->input_phys), "%s/input0", name); - adap->rc->input_name = adap->input_name; + adap->rc->device_name = adap->device_name; adap->rc->input_phys = adap->input_phys; adap->rc->input_id.bustype = BUS_CEC; adap->rc->input_id.vendor = 0; diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 7c898b06d85c..941c342896cc 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -73,7 +73,7 @@ int sms_ir_init(struct smscore_device_t *coredev) strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys)); strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys)); - dev->input_name = coredev->ir.name; + dev->device_name = coredev->ir.name; dev->input_phys = coredev->ir.phys; dev->dev.parent = coredev->device; @@ -91,7 +91,7 @@ int sms_ir_init(struct smscore_device_t *coredev) dev->driver_name = MODULE_NAME; pr_debug("Input device (IR) %s is set for key events\n", - dev->input_name); + dev->device_name); err = rc_register_device(dev); if (err < 0) { diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index cee7fd9cf08b..af909bf5dd5b 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -452,7 +452,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) */ rc->input_id.bustype = BUS_I2C; rc->input_phys = ir->phys; - rc->input_name = ir->name; + rc->device_name = ir->name; /* * Initialize the other fields of rc_dev diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 2fd07a8afcd2..bb8eda51ee27 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -535,7 +535,7 @@ int bttv_input_init(struct bttv *btv) snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(btv->c.pci)); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_PCI; rc->input_id.version = 1; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 4367cb3162b6..c9b8e3f4d9fb 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -351,7 +351,7 @@ int cx23885_input_init(struct cx23885_dev *dev) } kernel_ir->rc = rc; - rc->input_name = kernel_ir->name; + rc->device_name = kernel_ir->name; rc->input_phys = kernel_ir->phys; rc->input_id.bustype = BUS_PCI; rc->input_id.version = 1; diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index 01f2e472a2a0..a5dbee776455 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -464,7 +464,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); - dev->input_name = ir->name; + dev->device_name = ir->name; dev->input_phys = ir->phys; dev->input_id.bustype = BUS_PCI; dev->input_id.version = 1; diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 190ca9c17237..0bc618f36385 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -748,7 +748,7 @@ static int dm1105_ir_init(struct dm1105_dev *dm1105) dev->driver_name = MODULE_NAME; dev->map_name = RC_MAP_DM1105_NEC; - dev->input_name = "DVB on-card IR receiver"; + dev->device_name = "DVB on-card IR receiver"; dev->input_phys = dm1105->ir.input_phys; dev->input_id.bustype = BUS_PCI; dev->input_id.version = 1; diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h index d48778a366a9..a664c319ef0a 100644 --- a/drivers/media/pci/mantis/mantis_common.h +++ b/drivers/media/pci/mantis/mantis_common.h @@ -176,7 +176,7 @@ struct mantis_pci { struct work_struct uart_work; struct rc_dev *rc; - char input_name[80]; + char device_name[80]; char input_phys[80]; char *rc_map_name; }; diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c index 50d10cb7d49d..001b7f827699 100644 --- a/drivers/media/pci/mantis/mantis_input.c +++ b/drivers/media/pci/mantis/mantis_input.c @@ -46,12 +46,12 @@ int mantis_input_init(struct mantis_pci *mantis) goto out; } - snprintf(mantis->input_name, sizeof(mantis->input_name), + snprintf(mantis->device_name, sizeof(mantis->device_name), "Mantis %s IR receiver", mantis->hwconfig->model_name); snprintf(mantis->input_phys, sizeof(mantis->input_phys), "pci-%s/ir0", pci_name(mantis->pdev)); - dev->input_name = mantis->input_name; + dev->device_name = mantis->device_name; dev->input_phys = mantis->input_phys; dev->input_id.bustype = BUS_PCI; dev->input_id.vendor = mantis->vendor_id; diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 78849c19f68a..ba1fc77a6f7b 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -870,7 +870,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) if (raw_decode) rc->driver_type = RC_DRIVER_IR_RAW; - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_PCI; rc->input_id.version = 1; diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c index d2730c3fdbae..fc3375720a35 100644 --- a/drivers/media/pci/smipcie/smipcie-ir.c +++ b/drivers/media/pci/smipcie/smipcie-ir.c @@ -188,14 +188,14 @@ int smi_ir_init(struct smi_dev *dev) return -ENOMEM; /* init input device */ - snprintf(ir->input_name, sizeof(ir->input_name), "IR (%s)", + snprintf(ir->device_name, sizeof(ir->device_name), "IR (%s)", dev->info->name); snprintf(ir->input_phys, sizeof(ir->input_phys), "pci-%s/ir0", pci_name(dev->pci_dev)); rc_dev->driver_name = "SMI_PCIe"; rc_dev->input_phys = ir->input_phys; - rc_dev->input_name = ir->input_name; + rc_dev->device_name = ir->device_name; rc_dev->input_id.bustype = BUS_PCI; rc_dev->input_id.version = 1; rc_dev->input_id.vendor = dev->pci_dev->subsystem_vendor; diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h index 611e4f02cadd..c8368c78ddd5 100644 --- a/drivers/media/pci/smipcie/smipcie.h +++ b/drivers/media/pci/smipcie/smipcie.h @@ -240,7 +240,7 @@ struct smi_rc { struct smi_dev *dev; struct rc_dev *rc_dev; char input_phys[64]; - char input_name[64]; + char device_name[64]; struct work_struct work; u8 irData[256]; diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 5b8aab4c7b81..cf185c83cc9e 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -186,7 +186,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) "pci-%s/ir0", pci_name(saa->pci)); dev->driver_name = MODULE_NAME; - dev->input_name = budget_ci->ir.name; + dev->device_name = budget_ci->ir.name; dev->input_phys = budget_ci->ir.phys; dev->input_id.bustype = BUS_PCI; dev->input_id.version = 1; diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index a4c6ad4f67c1..a7f76002b30a 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -766,7 +766,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote) rdev->open = ati_remote_rc_open; rdev->close = ati_remote_rc_close; - rdev->input_name = ati_remote->rc_name; + rdev->device_name = ati_remote->rc_name; rdev->input_phys = ati_remote->rc_phys; usb_to_input_id(ati_remote->udev, &rdev->input_id); diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 60da963f40dc..41f6b1c52407 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1060,7 +1060,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) rdev->s_idle = ene_set_idle; rdev->driver_name = ENE_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->input_name = "ENE eHome Infrared Remote Receiver"; + rdev->device_name = "ENE eHome Infrared Remote Receiver"; if (dev->hw_learning_and_tx_capable) { rdev->s_learning_mode = ene_set_learning_mode; @@ -1070,7 +1070,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) rdev->s_tx_carrier = ene_set_tx_carrier; rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle; rdev->s_carrier_report = ene_set_carrier_report; - rdev->input_name = "ENE eHome Infrared Remote Transceiver"; + rdev->device_name = "ENE eHome Infrared Remote Transceiver"; } dev->rdev = rdev; diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 0d3562712f27..57155e4c9f38 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -532,7 +532,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; rdev->open = fintek_open; rdev->close = fintek_close; - rdev->input_name = FINTEK_DESCRIPTION; + rdev->device_name = FINTEK_DESCRIPTION; rdev->input_phys = "fintek/cir0"; rdev->input_id.bustype = BUS_HOST; rdev->input_id.vendor = VENDOR_ID_FINTEK; diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index b4f773b9dc1d..561c27a4be64 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -150,7 +150,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) } rcdev->priv = gpio_dev; - rcdev->input_name = GPIO_IR_DEVICE_NAME; + rcdev->device_name = GPIO_IR_DEVICE_NAME; rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index cb6d4f1247da..5babc6371df4 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -194,7 +194,7 @@ static int igorplugusb_probe(struct usb_interface *intf, if (!rc) goto fail; - rc->input_name = DRIVER_DESC; + rc->device_name = DRIVER_DESC; rc->input_phys = ir->phys; usb_to_input_id(udev, &rc->input_id); rc->dev.parent = &intf->dev; diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 8711a7ff55cc..4357dd36d7b9 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -487,7 +487,7 @@ static int iguanair_probe(struct usb_interface *intf, usb_make_path(ir->udev, ir->phys, sizeof(ir->phys)); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 8d1439622533..dd46973e0cbf 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -1083,7 +1083,7 @@ int img_ir_probe_hw(struct img_ir_priv *priv) rdev->priv = priv; rdev->map_name = RC_MAP_EMPTY; rdev->allowed_protocols = img_ir_allowed_protos(priv); - rdev->input_name = "IMG Infrared Decoder"; + rdev->device_name = "IMG Infrared Decoder"; rdev->s_filter = img_ir_set_normal_filter; rdev->s_wakeup_filter = img_ir_set_wakeup_filter; diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 8d2f8e2006e7..7f23a863310c 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -117,7 +117,7 @@ int img_ir_probe_raw(struct img_ir_priv *priv) } rdev->priv = priv; rdev->map_name = RC_MAP_EMPTY; - rdev->input_name = "IMG Infrared Decoder Raw"; + rdev->device_name = "IMG Infrared Decoder Raw"; /* Register raw decoder */ error = rc_register_device(rdev); diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 717ba782d7a7..ab560fdaae7c 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -2063,7 +2063,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) sizeof(ictx->phys_rdev)); strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev)); - rdev->input_name = ictx->name_rdev; + rdev->device_name = ictx->name_rdev; rdev->input_phys = ictx->phys_rdev; usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id); rdev->dev.parent = ictx->dev; diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 50951f686852..0e639fb6f7b9 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -249,7 +249,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) rdev->driver_name = IR_HIX5HD2_NAME; map_name = of_get_property(node, "linux,rc-map-name", NULL); rdev->map_name = map_name ?: RC_MAP_EMPTY; - rdev->input_name = IR_HIX5HD2_NAME; + rdev->device_name = IR_HIX5HD2_NAME; rdev->input_phys = IR_HIX5HD2_NAME "/input0"; rdev->input_id.bustype = BUS_HOST; rdev->input_id.vendor = 0x0001; diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index 7e383b3fedd5..29ed0638cb74 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c @@ -155,6 +155,7 @@ static int ir_spi_probe(struct spi_device *spi) idata->rc->tx_ir = ir_spi_tx; idata->rc->s_tx_carrier = ir_spi_set_tx_carrier; idata->rc->s_tx_duty_cycle = ir_spi_set_duty_cycle; + idata->rc->device_name = "IR SPI"; idata->rc->driver_name = IR_SPI_DRIVER_NAME; idata->rc->priv = idata; idata->spi = spi; diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index e9e4befbbebb..c8eea30b4e50 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1576,7 +1576,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle; } - rdev->input_name = dev_desc->model; + rdev->device_name = dev_desc->model; rdev->input_id.bustype = BUS_HOST; rdev->input_id.vendor = PCI_VENDOR_ID_ITE; rdev->input_id.product = 0; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index eb130694bbb8..d9c7bbd25253 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1264,7 +1264,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; usb_to_input_id(ir->usbdev, &rc->input_id); rc->dev.parent = dev; diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 65566d569cb1..dfe3da487be0 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -138,7 +138,7 @@ static int meson_ir_probe(struct platform_device *pdev) } ir->rc->priv = ir; - ir->rc->input_name = DRIVER_NAME; + ir->rc->device_name = DRIVER_NAME; ir->rc->input_phys = DRIVER_NAME "/input0"; ir->rc->input_id.bustype = BUS_HOST; map_name = of_get_property(node, "linux,rc-map-name", NULL); diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index 667277205fee..da4461fabce6 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -343,7 +343,7 @@ static int mtk_ir_probe(struct platform_device *pdev) } ir->rc->priv = ir; - ir->rc->input_name = MTK_IR_DEV; + ir->rc->device_name = MTK_IR_DEV; ir->rc->input_phys = MTK_IR_DEV "/input0"; ir->rc->input_id.bustype = BUS_HOST; ir->rc->input_id.vendor = 0x0001; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index ec4b25bd2ec2..c44f723081cb 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1134,7 +1134,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->tx_ir = nvt_tx_ir; rdev->s_tx_carrier = nvt_set_tx_carrier; rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter; - rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; + rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; rdev->input_phys = "nuvoton/cir0"; rdev->input_id.bustype = BUS_HOST; rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2; diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 62195af24fbe..46cc9c29d68a 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -219,7 +219,7 @@ static int __init loop_init(void) return -ENOMEM; } - rc->input_name = "rc-core loopback device"; + rc->device_name = "rc-core loopback device"; rc->input_phys = "rc-core/virtual"; rc->input_id.bustype = BUS_VIRTUAL; rc->input_id.version = 1; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 33c04ccccdff..f306e67b8b66 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -530,7 +530,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) if (keycode != KEY_RESERVED) IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", - dev->input_name, scancode, keycode); + dev->device_name, scancode, keycode); return keycode; } @@ -663,7 +663,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol, dev->last_keycode = keycode; IR_dprintk(1, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", - dev->input_name, keycode, protocol, scancode); + dev->device_name, keycode, protocol, scancode); input_report_key(dev->input_dev, keycode, 1); led_trigger_event(led_feedback, LED_FULL); @@ -1663,7 +1663,7 @@ static int rc_prepare_rx_device(struct rc_dev *dev) dev->input_dev->dev.parent = &dev->dev; memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id)); dev->input_dev->phys = dev->input_phys; - dev->input_dev->name = dev->input_name; + dev->input_dev->name = dev->device_name; return 0; @@ -1759,7 +1759,7 @@ int rc_register_device(struct rc_dev *dev) path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); dev_info(&dev->dev, "%s as %s\n", - dev->input_name ?: "Unspecified device", path ?: "N/A"); + dev->device_name ?: "Unspecified device", path ?: "N/A"); kfree(path); if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 56d43be2756b..29fa37b99553 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -951,7 +951,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys)); - rc->input_name = rr3->name; + rc->device_name = rr3->name; rc->input_phys = rr3->phys; usb_to_input_id(rr3->udev, &rc->input_id); rc->dev.parent = dev; diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 77d5d4cbed0a..9a5e9fa01196 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -513,19 +513,19 @@ static int serial_ir_probe(struct platform_device *dev) switch (type) { case IR_HOMEBREW: - rcdev->input_name = "Serial IR type home-brew"; + rcdev->device_name = "Serial IR type home-brew"; break; case IR_IRDEO: - rcdev->input_name = "Serial IR type IRdeo"; + rcdev->device_name = "Serial IR type IRdeo"; break; case IR_IRDEO_REMOTE: - rcdev->input_name = "Serial IR type IRdeo remote"; + rcdev->device_name = "Serial IR type IRdeo remote"; break; case IR_ANIMAX: - rcdev->input_name = "Serial IR type AnimaX"; + rcdev->device_name = "Serial IR type AnimaX"; break; case IR_IGOR: - rcdev->input_name = "Serial IR type IgorPlug"; + rcdev->device_name = "Serial IR type IgorPlug"; break; } diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index be67f7c9a75b..83b4410664af 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -308,7 +308,7 @@ static int sir_ir_probe(struct platform_device *dev) if (!rcdev) return -ENOMEM; - rcdev->input_name = "SIR IrDA port"; + rcdev->device_name = "SIR IrDA port"; rcdev->input_phys = KBUILD_MODNAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index a08e1dd06124..272de9c8a9f6 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -299,7 +299,7 @@ static int st_rc_probe(struct platform_device *pdev) rdev->close = st_rc_close; rdev->driver_name = IR_ST_NAME; rdev->map_name = RC_MAP_EMPTY; - rdev->input_name = "ST Remote Control Receiver"; + rdev->device_name = "ST Remote Control Receiver"; ret = rc_register_device(rdev); if (ret < 0) diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index b09c45abb5f3..829f2b348a46 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -299,7 +299,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); strlcat(sz->phys, "/input0", sizeof(sz->phys)); - rdev->input_name = sz->name; + rdev->device_name = sz->name; rdev->input_phys = sz->phys; usb_to_input_id(sz->usbdev, &rdev->input_id); rdev->dev.parent = dev; diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index 4b785dd775c1..87933eb14205 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -215,7 +215,7 @@ static int sunxi_ir_probe(struct platform_device *pdev) } ir->rc->priv = ir; - ir->rc->input_name = SUNXI_IR_DEV; + ir->rc->device_name = SUNXI_IR_DEV; ir->rc->input_phys = "sunxi-ir/input0"; ir->rc->input_id.bustype = BUS_HOST; ir->rc->input_id.vendor = 0x0001; diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 23be7702e2df..5002a91e830e 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -309,7 +309,7 @@ static int ttusbir_probe(struct usb_interface *intf, usb_make_path(tt->udev, tt->phys, sizeof(tt->phys)); - rc->input_name = DRIVER_DESC; + rc->device_name = DRIVER_DESC; rc->input_phys = tt->phys; usb_to_input_id(tt->udev, &rc->input_id); rc->dev.parent = &intf->dev; diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 5a4d4a611197..ea7be6d35ff8 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1068,7 +1068,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) } data->dev->driver_name = DRVNAME; - data->dev->input_name = WBCIR_NAME; + data->dev->device_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; data->dev->input_id.bustype = BUS_HOST; data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND; diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 9d82ec0a4b64..9ae42ebefa8a 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -335,7 +335,7 @@ int au0828_rc_register(struct au0828_dev *dev) usb_make_path(dev->usbdev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_USB; rc->input_id.version = 1; diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 955fb0d07507..096bb75a24e5 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -154,13 +154,12 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d) } dev->dev.parent = &d->udev->dev; - dev->input_name = d->name; + dev->device_name = d->name; usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); dev->input_phys = d->rc_phys; usb_to_input_id(d->udev, &dev->input_id); - /* TODO: likely RC-core should took const char * */ - dev->driver_name = (char *) d->props->driver_name; + dev->driver_name = d->props->driver_name; dev->map_name = d->rc.map_name; dev->allowed_protocols = d->rc.allowed_protos; dev->change_protocol = d->rc.change_protocol; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c index f05f1fc80729..0b03f9bd9c26 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c @@ -279,7 +279,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) dev->change_protocol = d->props.rc.core.change_protocol; dev->allowed_protocols = d->props.rc.core.allowed_protos; usb_to_input_id(d->udev, &dev->input_id); - dev->input_name = "IR-receiver inside an USB DVB receiver"; + dev->device_name = "IR-receiver inside an USB DVB receiver"; dev->input_phys = d->rc_phys; dev->dev.parent = &d->udev->dev; dev->priv = d; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index ca9673917ad5..d8746b96a0f8 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -807,7 +807,7 @@ static int em28xx_ir_init(struct em28xx *dev) usb_make_path(udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_USB; rc->input_id.version = 1; diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c index 1a033f57fcc1..83e33aef0105 100644 --- a/drivers/media/usb/tm6000/tm6000-input.c +++ b/drivers/media/usb/tm6000/tm6000-input.c @@ -458,7 +458,7 @@ int tm6000_ir_init(struct tm6000_core *dev) rc_type = RC_BIT_UNKNOWN; tm6000_ir_change_protocol(rc, &rc_type); - rc->input_name = ir->name; + rc->device_name = ir->name; rc->input_phys = ir->phys; rc->input_id.bustype = BUS_USB; rc->input_id.version = 1; diff --git a/include/media/cec.h b/include/media/cec.h index 224359c9941a..d97aa6c32abd 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -203,7 +203,7 @@ struct cec_adapter { u16 phys_addrs[15]; u32 sequence; - char input_name[32]; + char device_name[32]; char input_phys[32]; char input_drv[32]; }; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 78dea39a9b39..16bd89caa22d 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -72,7 +72,7 @@ enum rc_filter_type { * @dev: driver model's view of this device * @managed_alloc: devm_rc_allocate_device was used to create rc_dev * @sysfs_groups: sysfs attribute groups - * @input_name: name of the input child device + * @device_name: name of the rc child device * @input_phys: physical path to the input child device * @input_id: id of the input child device (struct input_id) * @driver_name: name of the hardware driver which registered this device @@ -138,10 +138,10 @@ struct rc_dev { struct device dev; bool managed_alloc; const struct attribute_group *sysfs_groups[5]; - const char *input_name; + const char *device_name; const char *input_phys; struct input_id input_id; - char *driver_name; + const char *driver_name; const char *map_name; struct rc_map rc_map; struct mutex lock; -- cgit v1.2.3 From 219cb08ac015535c9c79a2f5730fca7c89915f17 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 1 Jul 2017 15:11:56 -0400 Subject: media: rc: mce kbd decoder not needed for IR TX drivers Without this patch, an input device is created which is not necessary. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-mce_kbd-decoder.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 6a4d58b88d91..5de14ae77421 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -358,6 +358,9 @@ static int ir_mce_kbd_register(struct rc_dev *dev) struct input_dev *idev; int i, ret; + if (dev->driver_type == RC_DRIVER_IR_RAW_TX) + return 0; + idev = input_allocate_device(); if (!idev) return -ENOMEM; @@ -413,6 +416,9 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev) struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd; struct input_dev *idev = mce_kbd->idev; + if (dev->driver_type == RC_DRIVER_IR_RAW_TX) + return 0; + del_timer_sync(&mce_kbd->rx_timeout); input_unregister_device(idev); -- cgit v1.2.3 From 24d79ebc6ccec5575b1f8ad35989c87796c47658 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 7 Jul 2017 05:51:59 -0400 Subject: media: rc: gpio-ir-tx: add new driver This is a simple bit-banging GPIO IR TX driver. Signed-off-by: Sean Young Signed-off-by: Matthias Reichl Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 6 ++ drivers/media/rc/Kconfig | 11 +++ drivers/media/rc/Makefile | 1 + drivers/media/rc/gpio-ir-tx.c | 174 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 drivers/media/rc/gpio-ir-tx.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 55d756712baf..a4736049d1f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5769,6 +5769,12 @@ S: Maintained F: Documentation/acpi/gpio-properties.txt F: drivers/gpio/gpiolib-acpi.c +GPIO IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/gpio-ir-tx.c + GPIO MOCKUP DRIVER M: Bamvor Jian Zhang L: linux-gpio@vger.kernel.org diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index b6433c57a024..06179d37a7c7 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -399,6 +399,17 @@ config IR_GPIO_CIR To compile this driver as a module, choose M here: the module will be called gpio-ir-recv. +config IR_GPIO_TX + tristate "GPIO IR Bit Banging Transmitter" + depends on RC_CORE + depends on LIRC + ---help--- + Say Y if you want to a GPIO based IR transmitter. This is a + bit banging driver. + + To compile this driver as a module, choose M here: the module will + be called gpio-ir-tx. + config RC_ST tristate "ST remote control receiver" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 245e2c2d0b22..3e64a4e4b312 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_IR_STREAMZAP) += streamzap.o obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o +obj-$(CONFIG_IR_GPIO_TX) += gpio-ir-tx.o obj-$(CONFIG_IR_IGORPLUGUSB) += igorplugusb.o obj-$(CONFIG_IR_IGUANA) += iguanair.o obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c new file mode 100644 index 000000000000..0b83408a2e18 --- /dev/null +++ b/drivers/media/rc/gpio-ir-tx.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2017 Sean Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "gpio-ir-tx" +#define DEVICE_NAME "GPIO IR Bit Banging Transmitter" + +struct gpio_ir { + struct gpio_desc *gpio; + unsigned int carrier; + unsigned int duty_cycle; + /* we need a spinlock to hold the cpu while transmitting */ + spinlock_t lock; +}; + +static const struct of_device_id gpio_ir_tx_of_match[] = { + { .compatible = "gpio-ir-tx", }, + { }, +}; +MODULE_DEVICE_TABLE(of, gpio_ir_tx_of_match); + +static int gpio_ir_tx_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle) +{ + struct gpio_ir *gpio_ir = dev->priv; + + gpio_ir->duty_cycle = duty_cycle; + + return 0; +} + +static int gpio_ir_tx_set_carrier(struct rc_dev *dev, u32 carrier) +{ + struct gpio_ir *gpio_ir = dev->priv; + + if (!carrier) + return -EINVAL; + + gpio_ir->carrier = carrier; + + return 0; +} + +static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) +{ + struct gpio_ir *gpio_ir = dev->priv; + unsigned long flags; + ktime_t edge; + /* + * delta should never exceed 0.5 seconds (IR_MAX_DURATION) and on + * m68k ndelay(s64) does not compile; so use s32 rather than s64. + */ + s32 delta; + int i; + unsigned int pulse, space; + + /* Ensure the dividend fits into 32 bit */ + pulse = DIV_ROUND_CLOSEST(gpio_ir->duty_cycle * (NSEC_PER_SEC / 100), + gpio_ir->carrier); + space = DIV_ROUND_CLOSEST((100 - gpio_ir->duty_cycle) * + (NSEC_PER_SEC / 100), gpio_ir->carrier); + + spin_lock_irqsave(&gpio_ir->lock, flags); + + edge = ktime_get(); + + for (i = 0; i < count; i++) { + if (i % 2) { + // space + edge = ktime_add_us(edge, txbuf[i]); + delta = ktime_us_delta(edge, ktime_get()); + if (delta > 10) { + spin_unlock_irqrestore(&gpio_ir->lock, flags); + usleep_range(delta, delta + 10); + spin_lock_irqsave(&gpio_ir->lock, flags); + } else if (delta > 0) { + udelay(delta); + } + } else { + // pulse + ktime_t last = ktime_add_us(edge, txbuf[i]); + + while (ktime_get() < last) { + gpiod_set_value(gpio_ir->gpio, 1); + edge += pulse; + delta = edge - ktime_get(); + if (delta > 0) + ndelay(delta); + gpiod_set_value(gpio_ir->gpio, 0); + edge += space; + delta = edge - ktime_get(); + if (delta > 0) + ndelay(delta); + } + + edge = last; + } + } + + spin_unlock_irqrestore(&gpio_ir->lock, flags); + + return count; +} + +static int gpio_ir_tx_probe(struct platform_device *pdev) +{ + struct gpio_ir *gpio_ir; + struct rc_dev *rcdev; + int rc; + + gpio_ir = devm_kmalloc(&pdev->dev, sizeof(*gpio_ir), GFP_KERNEL); + if (!gpio_ir) + return -ENOMEM; + + rcdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW_TX); + if (!rcdev) + return -ENOMEM; + + gpio_ir->gpio = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW); + if (IS_ERR(gpio_ir->gpio)) { + if (PTR_ERR(gpio_ir->gpio) != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get gpio (%ld)\n", + PTR_ERR(gpio_ir->gpio)); + return PTR_ERR(gpio_ir->gpio); + } + + rcdev->priv = gpio_ir; + rcdev->driver_name = DRIVER_NAME; + rcdev->device_name = DEVICE_NAME; + rcdev->tx_ir = gpio_ir_tx; + rcdev->s_tx_duty_cycle = gpio_ir_tx_set_duty_cycle; + rcdev->s_tx_carrier = gpio_ir_tx_set_carrier; + + gpio_ir->carrier = 38000; + gpio_ir->duty_cycle = 50; + spin_lock_init(&gpio_ir->lock); + + rc = devm_rc_register_device(&pdev->dev, rcdev); + if (rc < 0) + dev_err(&pdev->dev, "failed to register rc device\n"); + + return rc; +} + +static struct platform_driver gpio_ir_tx_driver = { + .probe = gpio_ir_tx_probe, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(gpio_ir_tx_of_match), + }, +}; +module_platform_driver(gpio_ir_tx_driver); + +MODULE_DESCRIPTION("GPIO IR Bit Banging Transmitter"); +MODULE_AUTHOR("Sean Young "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From db3df8765e38db994d602435e578f6e1b41e7a87 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 7 Jul 2017 05:52:02 -0400 Subject: media: rc: pwm-ir-tx: add new driver This is new driver which uses pwm, so it is more power-efficient than the bit banging gpio-ir-tx driver. Signed-off-by: Sean Young Reviewed-by: Pavel Machek Tested-by: Matthias Reichl Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 6 ++ drivers/media/rc/Kconfig | 12 ++++ drivers/media/rc/Makefile | 1 + drivers/media/rc/pwm-ir-tx.c | 138 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 drivers/media/rc/pwm-ir-tx.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index a4736049d1f1..38471657e222 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10794,6 +10794,12 @@ F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt F: Documentation/hwmon/pwm-fan F: drivers/hwmon/pwm-fan.c +PWM IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/pwm-ir-tx.c + PWM SUBSYSTEM M: Thierry Reding L: linux-pwm@vger.kernel.org diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 06179d37a7c7..d27be2516974 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -410,6 +410,18 @@ config IR_GPIO_TX To compile this driver as a module, choose M here: the module will be called gpio-ir-tx. +config IR_PWM_TX + tristate "PWM IR transmitter" + depends on RC_CORE + depends on LIRC + depends on PWM + ---help--- + Say Y if you want to use a PWM based IR transmitter. This is + more power efficient than the bit banging gpio driver. + + To compile this driver as a module, choose M here: the module will + be called pwm-ir-tx. + config RC_ST tristate "ST remote control receiver" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 3e64a4e4b312..466c40216347 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o obj-$(CONFIG_IR_GPIO_TX) += gpio-ir-tx.o +obj-$(CONFIG_IR_PWM_TX) += pwm-ir-tx.o obj-$(CONFIG_IR_IGORPLUGUSB) += igorplugusb.o obj-$(CONFIG_IR_IGUANA) += iguanair.o obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c new file mode 100644 index 000000000000..27d0f5837a76 --- /dev/null +++ b/drivers/media/rc/pwm-ir-tx.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2017 Sean Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "pwm-ir-tx" +#define DEVICE_NAME "PWM IR Transmitter" + +struct pwm_ir { + struct pwm_device *pwm; + unsigned int carrier; + unsigned int duty_cycle; +}; + +static const struct of_device_id pwm_ir_of_match[] = { + { .compatible = "pwm-ir-tx", }, + { }, +}; +MODULE_DEVICE_TABLE(of, pwm_ir_of_match); + +static int pwm_ir_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle) +{ + struct pwm_ir *pwm_ir = dev->priv; + + pwm_ir->duty_cycle = duty_cycle; + + return 0; +} + +static int pwm_ir_set_carrier(struct rc_dev *dev, u32 carrier) +{ + struct pwm_ir *pwm_ir = dev->priv; + + if (!carrier) + return -EINVAL; + + pwm_ir->carrier = carrier; + + return 0; +} + +static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf, + unsigned int count) +{ + struct pwm_ir *pwm_ir = dev->priv; + struct pwm_device *pwm = pwm_ir->pwm; + int i, duty, period; + ktime_t edge; + long delta; + + period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier); + duty = DIV_ROUND_CLOSEST(pwm_ir->duty_cycle * period, 100); + + pwm_config(pwm, duty, period); + + edge = ktime_get(); + + for (i = 0; i < count; i++) { + if (i % 2) // space + pwm_disable(pwm); + else + pwm_enable(pwm); + + edge = ktime_add_us(edge, txbuf[i]); + delta = ktime_us_delta(edge, ktime_get()); + if (delta > 0) + usleep_range(delta, delta + 10); + } + + pwm_disable(pwm); + + return count; +} + +static int pwm_ir_probe(struct platform_device *pdev) +{ + struct pwm_ir *pwm_ir; + struct rc_dev *rcdev; + int rc; + + pwm_ir = devm_kmalloc(&pdev->dev, sizeof(*pwm_ir), GFP_KERNEL); + if (!pwm_ir) + return -ENOMEM; + + pwm_ir->pwm = devm_pwm_get(&pdev->dev, NULL); + if (IS_ERR(pwm_ir->pwm)) + return PTR_ERR(pwm_ir->pwm); + + pwm_ir->carrier = 38000; + pwm_ir->duty_cycle = 50; + + rcdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW_TX); + if (!rcdev) + return -ENOMEM; + + rcdev->priv = pwm_ir; + rcdev->driver_name = DRIVER_NAME; + rcdev->device_name = DEVICE_NAME; + rcdev->tx_ir = pwm_ir_tx; + rcdev->s_tx_duty_cycle = pwm_ir_set_duty_cycle; + rcdev->s_tx_carrier = pwm_ir_set_carrier; + + rc = devm_rc_register_device(&pdev->dev, rcdev); + if (rc < 0) + dev_err(&pdev->dev, "failed to register rc device\n"); + + return rc; +} + +static struct platform_driver pwm_ir_driver = { + .probe = pwm_ir_probe, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(pwm_ir_of_match), + }, +}; +module_platform_driver(pwm_ir_driver); + +MODULE_DESCRIPTION("PWM IR Transmitter"); +MODULE_AUTHOR("Sean Young "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From a8c2d62b1bddf5fa4d23a380be8904e5593c2b40 Mon Sep 17 00:00:00 2001 From: Yves Lemée Date: Wed, 12 Jul 2017 15:17:37 -0400 Subject: media: lirc_zilog: Clean up lirc zilog error codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According the coding style guidelines, the ENOSYS error code must be returned in case of a non existent system call. This code has been replaced with the ENOTTY error code indicating a missing functionality. Signed-off-by: Yves Lemée Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_zilog.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 015e41bd036e..26dd32d5b5b2 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -1249,7 +1249,7 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) break; case LIRC_GET_REC_MODE: if (!(features & LIRC_CAN_REC_MASK)) - return -ENOSYS; + return -ENOTTY; result = put_user(LIRC_REC2MODE (features & LIRC_CAN_REC_MASK), @@ -1257,21 +1257,21 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) break; case LIRC_SET_REC_MODE: if (!(features & LIRC_CAN_REC_MASK)) - return -ENOSYS; + return -ENOTTY; result = get_user(mode, uptr); if (!result && !(LIRC_MODE2REC(mode) & features)) - result = -EINVAL; + result = -ENOTTY; break; case LIRC_GET_SEND_MODE: if (!(features & LIRC_CAN_SEND_MASK)) - return -ENOSYS; + return -ENOTTY; result = put_user(LIRC_MODE_PULSE, uptr); break; case LIRC_SET_SEND_MODE: if (!(features & LIRC_CAN_SEND_MASK)) - return -ENOSYS; + return -ENOTTY; result = get_user(mode, uptr); if (!result && mode != LIRC_MODE_PULSE) -- cgit v1.2.3 From 87284271b73b80ae773747bf95dae83773746113 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 15 Jul 2017 17:13:14 -0400 Subject: media: rc: nuvoton: remove rudimentary transmit functionality Transmit support in this driver was never tested and based on the code it can't work. Just one example: The buffer provided to nvt_tx_ir holds unsigned int values in micro seconds: First value is for a pulse, second for a pause, etc. Bytes in this buffer are copied as-is to the chip FIFO what can't work as the chip-internal format is totally different. See also conversion done in nvt_process_rx_ir_data. Even if we would try to fix this we have the issue that we can't test it. There seems to be no device on the market using IR transmit with one of the chips supported by this driver. To facilitate maintenance of the driver I'd propose to remove the rudimentary transmit support. Signed-off-by: Heiner Kallweit Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 114 ++--------------------------------------- drivers/media/rc/nuvoton-cir.h | 24 --------- 2 files changed, 3 insertions(+), 135 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index c44f723081cb..5249cb58ea73 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -727,70 +727,6 @@ out_raw: return ret; } -/* - * nvt_tx_ir - * - * 1) clean TX fifo first (handled by AP) - * 2) copy data from user space - * 3) disable RX interrupts, enable TX interrupts: TTR & TFU - * 4) send 9 packets to TX FIFO to open TTR - * in interrupt_handler: - * 5) send all data out - * go back to write(): - * 6) disable TX interrupts, re-enable RX interupts - * - * The key problem of this function is user space data may larger than - * driver's data buf length. So nvt_tx_ir() will only copy TX_BUF_LEN data to - * buf, and keep current copied data buf num in cur_buf_num. But driver's buf - * number may larger than TXFCONT (0xff). So in interrupt_handler, it has to - * set TXFCONT as 0xff, until buf_count less than 0xff. - */ -static int nvt_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned n) -{ - struct nvt_dev *nvt = dev->priv; - unsigned long flags; - unsigned int i; - u8 iren; - int ret; - - spin_lock_irqsave(&nvt->lock, flags); - - ret = min((unsigned)(TX_BUF_LEN / sizeof(unsigned)), n); - nvt->tx.buf_count = (ret * sizeof(unsigned)); - - memcpy(nvt->tx.buf, txbuf, nvt->tx.buf_count); - - nvt->tx.cur_buf_num = 0; - - /* save currently enabled interrupts */ - iren = nvt_cir_reg_read(nvt, CIR_IREN); - - /* now disable all interrupts, save TFU & TTR */ - nvt_cir_reg_write(nvt, CIR_IREN_TFU | CIR_IREN_TTR, CIR_IREN); - - nvt->tx.tx_state = ST_TX_REPLY; - - nvt_cir_reg_write(nvt, CIR_FIFOCON_TX_TRIGGER_LEV_8 | - CIR_FIFOCON_RXFIFOCLR, CIR_FIFOCON); - - /* trigger TTR interrupt by writing out ones, (yes, it's ugly) */ - for (i = 0; i < 9; i++) - nvt_cir_reg_write(nvt, 0x01, CIR_STXFIFO); - - spin_unlock_irqrestore(&nvt->lock, flags); - - wait_event(nvt->tx.queue, nvt->tx.tx_state == ST_TX_REQUEST); - - spin_lock_irqsave(&nvt->lock, flags); - nvt->tx.tx_state = ST_TX_NONE; - spin_unlock_irqrestore(&nvt->lock, flags); - - /* restore enabled interrupts to prior state */ - nvt_cir_reg_write(nvt, iren, CIR_IREN); - - return ret; -} - /* dump contents of the last rx buffer we got from the hw rx fifo */ static void nvt_dump_rx_buf(struct nvt_dev *nvt) { @@ -895,11 +831,6 @@ static void nvt_cir_log_irqs(u8 status, u8 iren) CIR_IRSTS_TFU | CIR_IRSTS_GH) ? " ?" : ""); } -static bool nvt_cir_tx_inactive(struct nvt_dev *nvt) -{ - return nvt->tx.tx_state == ST_TX_NONE; -} - /* interrupt service routine for incoming and outgoing CIR data */ static irqreturn_t nvt_cir_isr(int irq, void *data) { @@ -952,40 +883,8 @@ static irqreturn_t nvt_cir_isr(int irq, void *data) if (status & CIR_IRSTS_RFO) nvt_handle_rx_fifo_overrun(nvt); - - else if (status & (CIR_IRSTS_RTR | CIR_IRSTS_PE)) { - /* We only do rx if not tx'ing */ - if (nvt_cir_tx_inactive(nvt)) - nvt_get_rx_ir_data(nvt); - } - - if (status & CIR_IRSTS_TE) - nvt_clear_tx_fifo(nvt); - - if (status & CIR_IRSTS_TTR) { - unsigned int pos, count; - u8 tmp; - - pos = nvt->tx.cur_buf_num; - count = nvt->tx.buf_count; - - /* Write data into the hardware tx fifo while pos < count */ - if (pos < count) { - nvt_cir_reg_write(nvt, nvt->tx.buf[pos], CIR_STXFIFO); - nvt->tx.cur_buf_num++; - /* Disable TX FIFO Trigger Level Reach (TTR) interrupt */ - } else { - tmp = nvt_cir_reg_read(nvt, CIR_IREN); - nvt_cir_reg_write(nvt, tmp & ~CIR_IREN_TTR, CIR_IREN); - } - } - - if (status & CIR_IRSTS_TFU) { - if (nvt->tx.tx_state == ST_TX_REPLY) { - nvt->tx.tx_state = ST_TX_REQUEST; - wake_up(&nvt->tx.queue); - } - } + else if (status & (CIR_IRSTS_RTR | CIR_IRSTS_PE)) + nvt_get_rx_ir_data(nvt); spin_unlock(&nvt->lock); @@ -1062,7 +961,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) if (!nvt) return -ENOMEM; - /* input device for IR remote (and tx) */ + /* input device for IR remote */ nvt->rdev = devm_rc_allocate_device(&pdev->dev, RC_DRIVER_IR_RAW); if (!nvt->rdev) return -ENOMEM; @@ -1105,8 +1004,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) pnp_set_drvdata(pdev, nvt); - init_waitqueue_head(&nvt->tx.queue); - ret = nvt_hw_detect(nvt); if (ret) return ret; @@ -1131,7 +1028,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->encode_wakeup = true; rdev->open = nvt_open; rdev->close = nvt_close; - rdev->tx_ir = nvt_tx_ir; rdev->s_tx_carrier = nvt_set_tx_carrier; rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter; rdev->device_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; @@ -1148,8 +1044,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) #if 0 rdev->min_timeout = XYZ; rdev->max_timeout = XYZ; - /* tx bits */ - rdev->tx_resolution = XYZ; #endif ret = devm_rc_register_device(&pdev->dev, rdev); if (ret) @@ -1205,8 +1099,6 @@ static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state) spin_lock_irqsave(&nvt->lock, flags); - nvt->tx.tx_state = ST_TX_NONE; - /* disable all CIR interrupts */ nvt_cir_reg_write(nvt, 0, CIR_IREN); diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 88a29df38a57..0737c27f7ddc 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -46,14 +46,6 @@ static int debug; KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__) -/* - * Original lirc driver said min value of 76, and recommended value of 256 - * for the buffer length, but then used 2048. Never mind that the size of the - * RX FIFO is 32 bytes... So I'm using 32 for RX and 256 for TX atm, but I'm - * not sure if maybe that TX value is off by a factor of 8 (bits vs. bytes), - * and I don't have TX-capable hardware to test/debug on... - */ -#define TX_BUF_LEN 256 #define RX_BUF_LEN 32 #define SIO_ID_MASK 0xfff0 @@ -81,14 +73,6 @@ struct nvt_dev { u8 buf[RX_BUF_LEN]; unsigned int pkts; - struct { - u8 buf[TX_BUF_LEN]; - unsigned int buf_count; - unsigned int cur_buf_num; - wait_queue_head_t queue; - u8 tx_state; - } tx; - /* EFER Config register index/data pair */ u32 cr_efir; u32 cr_efdr; @@ -103,18 +87,10 @@ struct nvt_dev { u8 chip_major; u8 chip_minor; - /* hardware features */ - bool hw_tx_capable; - /* carrier period = 1 / frequency */ u32 carrier; }; -/* send states */ -#define ST_TX_NONE 0x0 -#define ST_TX_REQUEST 0x2 -#define ST_TX_REPLY 0x4 - /* buffer packet constants */ #define BUF_PULSE_BIT 0x80 #define BUF_LEN_MASK 0x7f -- cgit v1.2.3 From a4b80242d0467f58c7c273f62b2db73bf90956d1 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 11:25:39 -0400 Subject: media: st-rc: explicitly request exclusive reset control Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Cc: Patrice Chotard Signed-off-by: Philipp Zabel Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/st_rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 272de9c8a9f6..dc15dc8a7d21 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -280,7 +280,7 @@ static int st_rc_probe(struct platform_device *pdev) else rc_dev->rx_base = rc_dev->base; - rc_dev->rstc = reset_control_get_optional(dev, NULL); + rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(rc_dev->rstc)) { ret = PTR_ERR(rc_dev->rstc); goto err; -- cgit v1.2.3 From a2df9d064336ba62b810639114c06b2b0bfe3e0b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Jul 2017 11:25:41 -0400 Subject: media: rc: sunxi-cir: explicitly request exclusive reset control Commit a53e35db70d1 ("reset: Ensure drivers are explicit when requesting reset lines") started to transition the reset control request API calls to explicitly state whether the driver needs exclusive or shared reset control behavior. Convert all drivers requesting exclusive resets to the explicit API call so the temporary transition helpers can be removed. No functional changes. Cc: Maxime Ripard Cc: Chen-Yu Tsai Signed-off-by: Philipp Zabel Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/sunxi-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index 87933eb14205..f619b76273be 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -173,7 +173,7 @@ static int sunxi_ir_probe(struct platform_device *pdev) } /* Reset (optional) */ - ir->rst = devm_reset_control_get_optional(dev, NULL); + ir->rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(ir->rst)) return PTR_ERR(ir->rst); ret = reset_control_deassert(ir->rst); -- cgit v1.2.3 From e8ffda78623677f7935b30901a173405b4861bda Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 30 Jul 2017 09:23:11 -0400 Subject: media: rc: ir-nec-decoder: move scancode composing code into a shared function The NEC scancode composing and protocol type detection in ir_nec_decode() is generic enough to be a shared function. Let's create an inline function in rc-core.h, so that other remote control drivers can reuse this function to save some code. Signed-off-by: Shawn Guo Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-nec-decoder.c | 32 +++----------------------------- include/media/rc-core.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 75b9137f6faf..23d2bc8c190d 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -51,7 +51,6 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) u32 scancode; enum rc_type rc_type; u8 address, not_address, command, not_command; - bool send_32bits = false; if (!is_timing_event(ev)) { if (ev.reset) @@ -157,34 +156,9 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) command = bitrev8((data->bits >> 8) & 0xff); not_command = bitrev8((data->bits >> 0) & 0xff); - if ((command ^ not_command) != 0xff) { - IR_dprintk(1, "NEC checksum error: received 0x%08x\n", - data->bits); - send_32bits = true; - } - - if (send_32bits) { - /* NEC transport, but modified protocol, used by at - * least Apple and TiVo remotes */ - scancode = not_address << 24 | - address << 16 | - not_command << 8 | - command; - IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode); - rc_type = RC_TYPE_NEC32; - } else if ((address ^ not_address) != 0xff) { - /* Extended NEC */ - scancode = address << 16 | - not_address << 8 | - command; - IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); - rc_type = RC_TYPE_NECX; - } else { - /* Normal NEC */ - scancode = address << 8 | command; - IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); - rc_type = RC_TYPE_NEC; - } + scancode = ir_nec_bytes_to_scancode(address, not_address, + command, not_command, + &rc_type); if (data->is_nec_x) data->necx_repeat = true; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 16bd89caa22d..b6c18840d125 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -340,4 +340,35 @@ static inline u32 ir_extract_bits(u32 data, u32 mask) return value; } +/* Get NEC scancode and protocol type from address and command bytes */ +static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address, + u8 command, u8 not_command, + enum rc_type *protocol) +{ + u32 scancode; + + if ((command ^ not_command) != 0xff) { + /* NEC transport, but modified protocol, used by at + * least Apple and TiVo remotes + */ + scancode = not_address << 24 | + address << 16 | + not_command << 8 | + command; + *protocol = RC_TYPE_NEC32; + } else if ((address ^ not_address) != 0xff) { + /* Extended NEC */ + scancode = address << 16 | + not_address << 8 | + command; + *protocol = RC_TYPE_NECX; + } else { + /* Normal NEC */ + scancode = address << 8 | command; + *protocol = RC_TYPE_NEC; + } + + return scancode; +} + #endif /* _RC_CORE */ -- cgit v1.2.3 From b429996ced6f599b20ffc79789a54c65a21b0d96 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 30 Jul 2017 09:23:13 -0400 Subject: media: rc: add zx-irdec remote control driver It adds the remote control driver and corresponding keymap file for IRDEC block found on ZTE ZX family SoCs. Signed-off-by: Shawn Guo Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 11 ++ drivers/media/rc/Makefile | 1 + drivers/media/rc/keymaps/Makefile | 3 +- drivers/media/rc/keymaps/rc-zx-irdec.c | 79 ++++++++++++++ drivers/media/rc/zx-irdec.c | 183 +++++++++++++++++++++++++++++++++ include/media/rc-map.h | 1 + 6 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 drivers/media/rc/keymaps/rc-zx-irdec.c create mode 100644 drivers/media/rc/zx-irdec.c (limited to 'drivers') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d27be2516974..d9ce8ff55d0c 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -469,6 +469,17 @@ config IR_SIR To compile this driver as a module, choose M here: the module will be called sir-ir. +config IR_ZX + tristate "ZTE ZX IR remote control" + depends on RC_CORE + depends on ARCH_ZX || COMPILE_TEST + ---help--- + Say Y if you want to use the IR remote control available + on ZTE ZX family SoCs. + + To compile this driver as a module, choose M here: the + module will be called zx-irdec. + endif #RC_DEVICES endif #RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 466c40216347..9bc6a3980ed0 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -43,3 +43,4 @@ obj-$(CONFIG_IR_IMG) += img-ir/ obj-$(CONFIG_IR_SERIAL) += serial_ir.o obj-$(CONFIG_IR_SIR) += sir_ir.o obj-$(CONFIG_IR_MTK) += mtk-cir.o +obj-$(CONFIG_IR_ZX) += zx-irdec.o diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 2945f99907b5..af6496d709fb 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -109,4 +109,5 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-videomate-tv-pvr.o \ rc-winfast.o \ rc-winfast-usbii-deluxe.o \ - rc-su3000.o + rc-su3000.o \ + rc-zx-irdec.o diff --git a/drivers/media/rc/keymaps/rc-zx-irdec.c b/drivers/media/rc/keymaps/rc-zx-irdec.c new file mode 100644 index 000000000000..cc889df47eb8 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-zx-irdec.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2017 Sanechips Technology Co., Ltd. + * Copyright 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +static struct rc_map_table zx_irdec_table[] = { + { 0x01, KEY_1 }, + { 0x02, KEY_2 }, + { 0x03, KEY_3 }, + { 0x04, KEY_4 }, + { 0x05, KEY_5 }, + { 0x06, KEY_6 }, + { 0x07, KEY_7 }, + { 0x08, KEY_8 }, + { 0x09, KEY_9 }, + { 0x31, KEY_0 }, + { 0x16, KEY_DELETE }, + { 0x0a, KEY_MODE }, /* Input method */ + { 0x0c, KEY_VOLUMEUP }, + { 0x18, KEY_VOLUMEDOWN }, + { 0x0b, KEY_CHANNELUP }, + { 0x15, KEY_CHANNELDOWN }, + { 0x0d, KEY_PAGEUP }, + { 0x13, KEY_PAGEDOWN }, + { 0x46, KEY_FASTFORWARD }, + { 0x43, KEY_REWIND }, + { 0x44, KEY_PLAYPAUSE }, + { 0x45, KEY_STOP }, + { 0x49, KEY_OK }, + { 0x47, KEY_UP }, + { 0x4b, KEY_DOWN }, + { 0x48, KEY_LEFT }, + { 0x4a, KEY_RIGHT }, + { 0x4d, KEY_MENU }, + { 0x56, KEY_APPSELECT }, /* Application */ + { 0x4c, KEY_BACK }, + { 0x1e, KEY_INFO }, + { 0x4e, KEY_F1 }, + { 0x4f, KEY_F2 }, + { 0x50, KEY_F3 }, + { 0x51, KEY_F4 }, + { 0x1c, KEY_AUDIO }, + { 0x12, KEY_MUTE }, + { 0x11, KEY_DOT }, /* Location */ + { 0x1d, KEY_SETUP }, + { 0x40, KEY_POWER }, +}; + +static struct rc_map_list zx_irdec_map = { + .map = { + .scan = zx_irdec_table, + .size = ARRAY_SIZE(zx_irdec_table), + .rc_type = RC_TYPE_NEC, + .name = RC_MAP_ZX_IRDEC, + } +}; + +static int __init init_rc_map_zx_irdec(void) +{ + return rc_map_register(&zx_irdec_map); +} + +static void __exit exit_rc_map_zx_irdec(void) +{ + rc_map_unregister(&zx_irdec_map); +} + +module_init(init_rc_map_zx_irdec) +module_exit(exit_rc_map_zx_irdec) + +MODULE_AUTHOR("Shawn Guo "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/zx-irdec.c b/drivers/media/rc/zx-irdec.c new file mode 100644 index 000000000000..9452bac9262c --- /dev/null +++ b/drivers/media/rc/zx-irdec.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2017 Sanechips Technology Co., Ltd. + * Copyright 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "zx-irdec" + +#define ZX_IR_ENABLE 0x04 +#define ZX_IREN BIT(0) +#define ZX_IR_CTRL 0x08 +#define ZX_DEGL_MASK GENMASK(21, 20) +#define ZX_DEGL_VALUE(x) (((x) << 20) & ZX_DEGL_MASK) +#define ZX_WDBEGIN_MASK GENMASK(18, 8) +#define ZX_WDBEGIN_VALUE(x) (((x) << 8) & ZX_WDBEGIN_MASK) +#define ZX_IR_INTEN 0x10 +#define ZX_IR_INTSTCLR 0x14 +#define ZX_IR_CODE 0x30 +#define ZX_IR_CNUM 0x34 +#define ZX_NECRPT BIT(16) + +struct zx_irdec { + void __iomem *base; + struct rc_dev *rcd; +}; + +static void zx_irdec_set_mask(struct zx_irdec *irdec, unsigned int reg, + u32 mask, u32 value) +{ + u32 data; + + data = readl(irdec->base + reg); + data &= ~mask; + data |= value & mask; + writel(data, irdec->base + reg); +} + +static irqreturn_t zx_irdec_irq(int irq, void *dev_id) +{ + struct zx_irdec *irdec = dev_id; + u8 address, not_address; + u8 command, not_command; + u32 rawcode, scancode; + enum rc_type rc_type; + + /* Clear interrupt */ + writel(1, irdec->base + ZX_IR_INTSTCLR); + + /* Check repeat frame */ + if (readl(irdec->base + ZX_IR_CNUM) & ZX_NECRPT) { + rc_repeat(irdec->rcd); + goto done; + } + + rawcode = readl(irdec->base + ZX_IR_CODE); + not_command = (rawcode >> 24) & 0xff; + command = (rawcode >> 16) & 0xff; + not_address = (rawcode >> 8) & 0xff; + address = rawcode & 0xff; + + scancode = ir_nec_bytes_to_scancode(address, not_address, + command, not_command, + &rc_type); + rc_keydown(irdec->rcd, rc_type, scancode, 0); + +done: + return IRQ_HANDLED; +} + +static int zx_irdec_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct zx_irdec *irdec; + struct resource *res; + struct rc_dev *rcd; + int irq; + int ret; + + irdec = devm_kzalloc(dev, sizeof(*irdec), GFP_KERNEL); + if (!irdec) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irdec->base = devm_ioremap_resource(dev, res); + if (IS_ERR(irdec->base)) + return PTR_ERR(irdec->base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + rcd = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE); + if (!rcd) { + dev_err(dev, "failed to allocate rc device\n"); + return -ENOMEM; + } + + irdec->rcd = rcd; + + rcd->priv = irdec; + rcd->input_phys = DRIVER_NAME "/input0"; + rcd->input_id.bustype = BUS_HOST; + rcd->map_name = RC_MAP_ZX_IRDEC; + rcd->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + rcd->driver_name = DRIVER_NAME; + rcd->device_name = DRIVER_NAME; + + platform_set_drvdata(pdev, irdec); + + ret = devm_rc_register_device(dev, rcd); + if (ret) { + dev_err(dev, "failed to register rc device\n"); + return ret; + } + + ret = devm_request_irq(dev, irq, zx_irdec_irq, 0, NULL, irdec); + if (ret) { + dev_err(dev, "failed to request irq\n"); + return ret; + } + + /* + * Initialize deglitch level and watchdog counter beginner as + * recommended by vendor BSP code. + */ + zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_DEGL_MASK, ZX_DEGL_VALUE(0)); + zx_irdec_set_mask(irdec, ZX_IR_CTRL, ZX_WDBEGIN_MASK, + ZX_WDBEGIN_VALUE(0x21c)); + + /* Enable interrupt */ + writel(1, irdec->base + ZX_IR_INTEN); + + /* Enable the decoder */ + zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, ZX_IREN); + + return 0; +} + +static int zx_irdec_remove(struct platform_device *pdev) +{ + struct zx_irdec *irdec = platform_get_drvdata(pdev); + + /* Disable the decoder */ + zx_irdec_set_mask(irdec, ZX_IR_ENABLE, ZX_IREN, 0); + + /* Disable interrupt */ + writel(0, irdec->base + ZX_IR_INTEN); + + return 0; +} + +static const struct of_device_id zx_irdec_match[] = { + { .compatible = "zte,zx296718-irdec" }, + { }, +}; +MODULE_DEVICE_TABLE(of, zx_irdec_match); + +static struct platform_driver zx_irdec_driver = { + .probe = zx_irdec_probe, + .remove = zx_irdec_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = zx_irdec_match, + }, +}; +module_platform_driver(zx_irdec_driver); + +MODULE_DESCRIPTION("ZTE ZX IR remote control driver"); +MODULE_AUTHOR("Shawn Guo "); +MODULE_LICENSE("GPL v2"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 1a815a572fa1..c69482852f29 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -313,6 +313,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_WINFAST "rc-winfast" #define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" #define RC_MAP_SU3000 "rc-su3000" +#define RC_MAP_ZX_IRDEC "rc-zx-irdec" /* * Please, do not just append newer Remote Controller names at the end. -- cgit v1.2.3 From 89d8a2cc51d1f29ea24a0b44dde13253141190a0 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 3 Aug 2017 17:42:28 -0400 Subject: media: lirc_zilog: driver only sends LIRCCODE This driver cannot send pulse, it only accepts driver-dependent codes. Cc: # v3.2 Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/lirc/lirc_zilog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 26dd32d5b5b2..71af13bd0ebd 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -288,7 +288,7 @@ static void release_ir_tx(struct kref *ref) struct IR_tx *tx = container_of(ref, struct IR_tx, ref); struct IR *ir = tx->ir; - ir->l.features &= ~LIRC_CAN_SEND_PULSE; + ir->l.features &= ~LIRC_CAN_SEND_LIRCCODE; /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */ ir->tx = NULL; kfree(tx); @@ -1267,14 +1267,14 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (!(features & LIRC_CAN_SEND_MASK)) return -ENOTTY; - result = put_user(LIRC_MODE_PULSE, uptr); + result = put_user(LIRC_MODE_LIRCCODE, uptr); break; case LIRC_SET_SEND_MODE: if (!(features & LIRC_CAN_SEND_MASK)) return -ENOTTY; result = get_user(mode, uptr); - if (!result && mode != LIRC_MODE_PULSE) + if (!result && mode != LIRC_MODE_LIRCCODE) return -EINVAL; break; default: @@ -1512,7 +1512,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) kref_init(&tx->ref); ir->tx = tx; - ir->l.features |= LIRC_CAN_SEND_PULSE; + ir->l.features |= LIRC_CAN_SEND_LIRCCODE; mutex_init(&tx->client_lock); tx->c = client; tx->need_boot = 1; -- cgit v1.2.3 From ff05cf0937ad9c88bcfffd5d871918dc1827d989 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 4 Aug 2017 05:30:20 -0400 Subject: media: mceusb: do not read data parameters unless required This causes out-of-bounds read on device probe. BUG: KASAN: slab-out-of-bounds in mceusb_dev_printdata+0xdc/0x830 [mceusb] Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index d9c7bbd25253..60258889b162 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -538,12 +538,12 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd) return datasize; } -static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, - int buf_len, int offset, int len, bool out) +static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, + int offset, int len, bool out) { #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) char *inout; - u8 cmd, subcmd, data1, data2, data3, data4; + u8 cmd, subcmd, *data; struct device *dev = ir->dev; int start, skip = 0; u32 carrier, period; @@ -564,17 +564,14 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, start = offset + skip; cmd = buf[start] & 0xff; subcmd = buf[start + 1] & 0xff; - data1 = buf[start + 2] & 0xff; - data2 = buf[start + 3] & 0xff; - data3 = buf[start + 4] & 0xff; - data4 = buf[start + 5] & 0xff; + data = buf + start + 2; switch (cmd) { case MCE_CMD_NULL: if (subcmd == MCE_CMD_NULL) break; if ((subcmd == MCE_CMD_PORT_SYS) && - (data1 == MCE_CMD_RESUME)) + (data[0] == MCE_CMD_RESUME)) dev_dbg(dev, "Device resume requested"); else dev_dbg(dev, "Unknown command 0x%02x 0x%02x", @@ -585,7 +582,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, case MCE_RSP_EQEMVER: if (!out) dev_dbg(dev, "Emulator interface version %x", - data1); + data[0]); break; case MCE_CMD_G_REVISION: if (len == 2) @@ -603,13 +600,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, case MCE_RSP_EQWAKEVERSION: if (!out) dev_dbg(dev, "Wake version, proto: 0x%02x, payload: 0x%02x, address: 0x%02x, version: 0x%02x", - data1, data2, data3, data4); + data[0], data[1], data[2], data[3]); break; case MCE_RSP_GETPORTSTATUS: if (!out) /* We use data1 + 1 here, to match hw labels */ dev_dbg(dev, "TX port %d: blaster is%s connected", - data1 + 1, data4 ? " not" : ""); + data[0] + 1, data[3] ? " not" : ""); break; case MCE_CMD_FLASHLED: dev_dbg(dev, "Attempting to flash LED"); @@ -630,11 +627,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_CMD_UNKNOWN: dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x", - data1, data2); + data[0], data[1]); break; case MCE_RSP_EQIRCFS: - period = DIV_ROUND_CLOSEST( - (1U << data1 * 2) * (data2 + 1), 10); + period = DIV_ROUND_CLOSEST((1U << data[0] * 2) * + (data[1] + 1), 10); if (!period) break; carrier = (1000 * 1000) / period; @@ -646,11 +643,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_RSP_EQIRTXPORTS: dev_dbg(dev, "%s transmit blaster mask of 0x%02x", - inout, data1); + inout, data[0]); break; case MCE_RSP_EQIRTIMEOUT: /* value is in units of 50us, so x*50/1000 ms */ - period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000; + period = ((data[0] << 8) | data[1]) * + MCE_TIME_UNIT / 1000; dev_dbg(dev, "%s receive timeout of %d ms", inout, period); break; @@ -662,7 +660,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, break; case MCE_RSP_EQIRRXPORTEN: dev_dbg(dev, "%s %s-range receive sensor in use", - inout, data1 == 0x02 ? "short" : "long"); + inout, data[0] == 0x02 ? "short" : "long"); break; case MCE_CMD_GETIRRXPORTEN: /* aka MCE_RSP_EQIRRXCFCNT */ @@ -670,13 +668,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, dev_dbg(dev, "Get receive sensor"); else if (ir->learning_enabled) dev_dbg(dev, "RX pulse count: %d", - ((data1 << 8) | data2)); + ((data[0] << 8) | data[1])); break; case MCE_RSP_EQIRNUMPORTS: if (out) break; dev_dbg(dev, "Num TX ports: %x, num RX ports: %x", - data1, data2); + data[0], data[1]); break; case MCE_RSP_CMD_ILLEGAL: dev_dbg(dev, "Illegal PORT_IR command"); -- cgit v1.2.3 From 4fe055ecfc0a597e19dc159cf5289fd8f18ef9e3 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 4 Aug 2017 06:33:41 -0400 Subject: media: winbond-cir: buffer overrun during transmit We're reading beyond the buffer before checking its length. BUG: KASAN: slab-out-of-bounds in wbcir_irq_tx Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/winbond-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index ea7be6d35ff8..a18eb232ed81 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -429,7 +429,7 @@ wbcir_irq_tx(struct wbcir_data *data) bytes[used] = byte; } - while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen) + while (data->txoff != data->txlen && data->txbuf[data->txoff] == 0) data->txoff++; if (used == 0) { -- cgit v1.2.3 From e5e26439d1c46c8a201b0d05c719e33f0f091802 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 6 Aug 2017 15:25:52 -0400 Subject: media: rc-core: improve ir_raw_store_edge() handling The gpio-ir-recv driver does many wakeups (once per edge); the saa7134 driver has special handling to only wakeup 15ms after the first edge. Make this part of rc-core so gpio-ir-recv also benefits from this (so a rc-5 keypress now causes 3 wakeups rather than 24). Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-input.c | 26 +------------------------- drivers/media/rc/rc-core-priv.h | 2 ++ drivers/media/rc/rc-ir-raw.c | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index ba1fc77a6f7b..81e27ddcf6df 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -452,13 +452,6 @@ static void saa7134_input_timer(unsigned long data) mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); } -static void ir_raw_decode_timer_end(unsigned long data) -{ - struct saa7134_dev *dev = (struct saa7134_dev *)data; - - ir_raw_event_handle(dev->remote->dev); -} - static int __saa7134_ir_start(void *priv) { struct saa7134_dev *dev = priv; @@ -514,10 +507,6 @@ static int __saa7134_ir_start(void *priv) (unsigned long)dev); ir->timer.expires = jiffies + HZ; add_timer(&ir->timer); - } else if (ir->raw_decode) { - /* set timer_end for code completion */ - setup_timer(&ir->timer, ir_raw_decode_timer_end, - (unsigned long)dev); } return 0; @@ -535,7 +524,7 @@ static void __saa7134_ir_stop(void *priv) if (!ir->running) return; - if (ir->polling || ir->raw_decode) + if (ir->polling) del_timer_sync(&ir->timer); ir->running = false; @@ -1057,7 +1046,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) static int saa7134_raw_decode_irq(struct saa7134_dev *dev) { struct saa7134_card_ir *ir = dev->remote; - unsigned long timeout; int space; /* Generate initial event */ @@ -1066,17 +1054,5 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE); - /* - * Wait 15 ms from the start of the first IR event before processing - * the event. This time is enough for NEC protocol. May need adjustments - * to work with other protocols. - */ - smp_mb(); - - if (!timer_pending(&ir->timer)) { - timeout = jiffies + msecs_to_jiffies(15); - mod_timer(&ir->timer, timeout); - } - return 1; } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index b3e7cac2c3ee..cae13efc1a88 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -43,6 +43,8 @@ struct ir_raw_event_ctrl { ktime_t last_event; /* when last event occurred */ enum raw_event_type last_type; /* last event type */ struct rc_dev *dev; /* pointer to the parent rc_dev */ + /* edge driver */ + struct timer_list edge_handle; /* raw decoder state follows */ struct ir_raw_event prev_ev; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index b6d256f03847..07a694298119 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -133,6 +133,11 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) dev->raw->last_event = now; dev->raw->last_type = type; + + if (!timer_pending(&dev->raw->edge_handle)) + mod_timer(&dev->raw->edge_handle, + jiffies + msecs_to_jiffies(15)); + return rc; } EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); @@ -483,6 +488,13 @@ int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode, } EXPORT_SYMBOL(ir_raw_encode_scancode); +static void edge_handle(unsigned long arg) +{ + struct rc_dev *dev = (struct rc_dev *)arg; + + ir_raw_event_handle(dev); +} + /* * Used to (un)register raw event clients */ @@ -504,6 +516,8 @@ int ir_raw_event_prepare(struct rc_dev *dev) dev->raw->dev = dev; dev->change_protocol = change_protocol; + setup_timer(&dev->raw->edge_handle, edge_handle, + (unsigned long)dev); INIT_KFIFO(dev->raw->kfifo); return 0; @@ -555,6 +569,7 @@ void ir_raw_event_unregister(struct rc_dev *dev) return; kthread_stop(dev->raw->thread); + del_timer_sync(&dev->raw->edge_handle); mutex_lock(&ir_raw_handler_lock); list_del(&dev->raw->list); -- cgit v1.2.3 From 48b2de1971c766a8dc0aec668742e17cb0c75127 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 7 Aug 2017 08:30:18 -0400 Subject: media: rc: saa7134: add trailing space for timely decoding The gpio-ir-recv driver adds timeouts which the saa7134 lacks; this causes keypress not to arrive, and to only arrive once more IR is received. This is what the commit below calls "ghost keypresses", and that commit does not solve the issue completely. This makes the IR on the HVR-1150 much more reliable and responsive. Fixes: 3f5c4c73322e ("[media] rc: fix ghost keypresses with certain hw") Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-input.c | 3 +++ drivers/media/rc/gpio-ir-recv.c | 21 --------------------- drivers/media/rc/rc-ir-raw.c | 19 ++++++++++++++++++- 3 files changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 81e27ddcf6df..4b58c129be92 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -873,6 +873,9 @@ int saa7134_input_init1(struct saa7134_dev *dev) rc->dev.parent = &dev->pci->dev; rc->map_name = ir_codes; rc->driver_name = MODULE_NAME; + rc->min_timeout = 1; + rc->timeout = IR_DEFAULT_TIMEOUT; + rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; err = rc_register_device(rc); if (err) diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 561c27a4be64..512e31593a77 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -30,7 +30,6 @@ struct gpio_rc_dev { struct rc_dev *rcdev; int gpio_nr; bool active_low; - struct timer_list flush_timer; }; #ifdef CONFIG_OF @@ -94,26 +93,10 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) if (rc < 0) goto err_get_value; - mod_timer(&gpio_dev->flush_timer, - jiffies + nsecs_to_jiffies(gpio_dev->rcdev->timeout)); - - ir_raw_event_handle(gpio_dev->rcdev); - err_get_value: return IRQ_HANDLED; } -static void flush_timer(unsigned long arg) -{ - struct gpio_rc_dev *gpio_dev = (struct gpio_rc_dev *)arg; - DEFINE_IR_RAW_EVENT(ev); - - ev.timeout = true; - ev.duration = gpio_dev->rcdev->timeout; - ir_raw_event_store(gpio_dev->rcdev, &ev); - ir_raw_event_handle(gpio_dev->rcdev); -} - static int gpio_ir_recv_probe(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev; @@ -171,9 +154,6 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) gpio_dev->gpio_nr = pdata->gpio_nr; gpio_dev->active_low = pdata->active_low; - setup_timer(&gpio_dev->flush_timer, flush_timer, - (unsigned long)gpio_dev); - rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); if (rc < 0) goto err_gpio_request; @@ -216,7 +196,6 @@ static int gpio_ir_recv_remove(struct platform_device *pdev) struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); - del_timer_sync(&gpio_dev->flush_timer); rc_unregister_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); kfree(gpio_dev); diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 07a694298119..ef5efd994eef 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -134,9 +134,13 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) dev->raw->last_event = now; dev->raw->last_type = type; - if (!timer_pending(&dev->raw->edge_handle)) + /* timer could be set to timeout (125ms by default) */ + if (!timer_pending(&dev->raw->edge_handle) || + time_after(dev->raw->edge_handle.expires, + jiffies + msecs_to_jiffies(15))) { mod_timer(&dev->raw->edge_handle, jiffies + msecs_to_jiffies(15)); + } return rc; } @@ -491,6 +495,19 @@ EXPORT_SYMBOL(ir_raw_encode_scancode); static void edge_handle(unsigned long arg) { struct rc_dev *dev = (struct rc_dev *)arg; + ktime_t interval = ktime_get() - dev->raw->last_event; + + if (interval >= dev->timeout) { + DEFINE_IR_RAW_EVENT(ev); + + ev.timeout = true; + ev.duration = interval; + + ir_raw_event_store(dev, &ev); + } else { + mod_timer(&dev->raw->edge_handle, + jiffies + nsecs_to_jiffies(dev->timeout - interval)); + } ir_raw_event_handle(dev); } -- cgit v1.2.3 From 86fe1ac0d563477b1d10d49a92237e3f3d74e7be Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 7 Aug 2017 08:38:10 -0400 Subject: media: rc: simplify ir_raw_event_store_edge() Since commit 12749b198fa4 ("[media] rc: saa7134: add trailing space for timely decoding"), the workaround of inserting reset events is no longer needed. Note that the initial reset is not needed either; other rc-core drivers that don't use ir_raw_event_store_edge() never call this at all. Verified on a HVR-1150 and Raspberry Pi. Fixes: 3f5c4c73322e ("[media] rc: fix ghost keypresses with certain hw") Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-input.c | 2 +- drivers/media/rc/gpio-ir-recv.c | 6 +----- drivers/media/rc/img-ir/img-ir-raw.c | 4 ++-- drivers/media/rc/rc-core-priv.h | 1 - drivers/media/rc/rc-ir-raw.c | 31 +++++-------------------------- include/media/rc-core.h | 10 +--------- 6 files changed, 10 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 4b58c129be92..e7b386ee3ff9 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -1055,7 +1055,7 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; - ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE); + ir_raw_event_store_edge(dev->remote->dev, !space); return 1; } diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 512e31593a77..24c7ac8f1b82 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -76,7 +76,6 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) struct gpio_rc_dev *gpio_dev = dev_id; int gval; int rc = 0; - enum raw_event_type type = IR_SPACE; gval = gpio_get_value(gpio_dev->gpio_nr); @@ -86,10 +85,7 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) if (gpio_dev->active_low) gval = !gval; - if (gval == 1) - type = IR_PULSE; - - rc = ir_raw_event_store_edge(gpio_dev->rcdev, type); + rc = ir_raw_event_store_edge(gpio_dev->rcdev, gval == 1); if (rc < 0) goto err_get_value; diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 7f23a863310c..64714efc1145 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -40,9 +40,9 @@ static void img_ir_refresh_raw(struct img_ir_priv *priv, u32 irq_status) /* report the edge to the IR raw decoders */ if (ir_status) /* low */ - ir_raw_event_store_edge(rc_dev, IR_SPACE); + ir_raw_event_store_edge(rc_dev, false); else /* high */ - ir_raw_event_store_edge(rc_dev, IR_PULSE); + ir_raw_event_store_edge(rc_dev, true); ir_raw_event_handle(rc_dev); } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index cae13efc1a88..5e5b10fbc47e 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -41,7 +41,6 @@ struct ir_raw_event_ctrl { /* fifo for the pulse/space durations */ DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE); ktime_t last_event; /* when last event occurred */ - enum raw_event_type last_type; /* last event type */ struct rc_dev *dev; /* pointer to the parent rc_dev */ /* edge driver */ struct timer_list edge_handle; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index ef5efd994eef..1761be8c7028 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -88,7 +88,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); /** * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space * @dev: the struct rc_dev device descriptor - * @type: the type of the event that has occurred + * @pulse: true for pulse, false for space * * This routine (which may be called from an interrupt context) is used to * store the beginning of an ir pulse or space (or the start/end of ir @@ -96,43 +96,22 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); * hardware which does not provide durations directly but only interrupts * (or similar events) on state change. */ -int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) +int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) { ktime_t now; - s64 delta; /* ns */ DEFINE_IR_RAW_EVENT(ev); int rc = 0; - int delay; if (!dev->raw) return -EINVAL; now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); - delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); + ev.duration = ktime_sub(now, dev->raw->last_event); + ev.pulse = !pulse; - /* Check for a long duration since last event or if we're - * being called for the first time, note that delta can't - * possibly be negative. - */ - if (delta > delay || !dev->raw->last_type) - type |= IR_START_EVENT; - else - ev.duration = delta; - - if (type & IR_START_EVENT) - ir_raw_event_reset(dev); - else if (dev->raw->last_type & IR_SPACE) { - ev.pulse = false; - rc = ir_raw_event_store(dev, &ev); - } else if (dev->raw->last_type & IR_PULSE) { - ev.pulse = true; - rc = ir_raw_event_store(dev, &ev); - } else - return 0; + rc = ir_raw_event_store(dev, &ev); dev->raw->last_event = now; - dev->raw->last_type = type; /* timer could be set to timeout (125ms by default) */ if (!timer_pending(&dev->raw->edge_handle) || diff --git a/include/media/rc-core.h b/include/media/rc-core.h index b6c18840d125..5be527ff851d 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -272,14 +272,6 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode); * The Raw interface is specific to InfraRed. It may be a good idea to * split it later into a separate header. */ - -enum raw_event_type { - IR_SPACE = (1 << 0), - IR_PULSE = (1 << 1), - IR_START_EVENT = (1 << 2), - IR_STOP_EVENT = (1 << 3), -}; - struct ir_raw_event { union { u32 duration; @@ -308,7 +300,7 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev) void ir_raw_event_handle(struct rc_dev *dev); int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); -int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); +int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev); void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); -- cgit v1.2.3 From 2168b416c8326cc2edff9d986feebc569cf9ec10 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 7 Aug 2017 09:21:29 -0400 Subject: media: rc: ensure we do not read out of bounds If rc_validate_filter() is called for CEC or XMP, then we would read beyond the end of the array. Suggested-by: Hans Verkuil Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f306e67b8b66..7aaf28bcb01e 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -733,7 +733,7 @@ EXPORT_SYMBOL_GPL(rc_keydown_notimeout); static int rc_validate_filter(struct rc_dev *dev, struct rc_scancode_filter *filter) { - static u32 masks[] = { + static const u32 masks[] = { [RC_TYPE_RC5] = 0x1f7f, [RC_TYPE_RC5X_20] = 0x1f7f3f, [RC_TYPE_RC5_SZ] = 0x2fff, @@ -757,6 +757,9 @@ static int rc_validate_filter(struct rc_dev *dev, u32 s = filter->data; enum rc_type protocol = dev->wakeup_protocol; + if (protocol >= ARRAY_SIZE(masks)) + return -EINVAL; + switch (protocol) { case RC_TYPE_NECX: if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0) -- cgit v1.2.3 From 12c3b9b921d00cc2e4c460b11ae68b733a457a22 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 7 Aug 2017 15:54:51 -0400 Subject: media: rc: saa7134: raw decoder can support any protocol Any protocol for which we have a software decoder, can be enabled. Without this only the loaded protocol decoders can be selected. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index e7b386ee3ff9..a14b86d88afb 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -856,8 +856,10 @@ int saa7134_input_init1(struct saa7134_dev *dev) rc->priv = dev; rc->open = saa7134_ir_open; rc->close = saa7134_ir_close; - if (raw_decode) + if (raw_decode) { rc->driver_type = RC_DRIVER_IR_RAW; + rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + } rc->device_name = ir->name; rc->input_phys = ir->phys; -- cgit v1.2.3 From d57ea877af38057b0ef31758cf3b99765dc33695 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 9 Aug 2017 13:19:16 -0400 Subject: media: rc: per-protocol repeat period CEC needs a keypress timeout of 550ms, which is too high for the IR protocols. Also fill in known repeat times, with 50ms error margin. Also, combine all protocol data into one structure. Signed-off-by: Sean Young Suggested-by: Hans Verkuil Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 138 +++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 7aaf28bcb01e..f2d3cc450d08 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -30,8 +30,54 @@ #define IR_TAB_MAX_SIZE 8192 #define RC_DEV_MAX 256 -/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */ -#define IR_KEYPRESS_TIMEOUT 250 +static const struct { + const char *name; + unsigned int repeat_period; + unsigned int scancode_bits; +} protocols[] = { + [RC_TYPE_UNKNOWN] = { .name = "unknown", .repeat_period = 250 }, + [RC_TYPE_OTHER] = { .name = "other", .repeat_period = 250 }, + [RC_TYPE_RC5] = { .name = "rc-5", + .scancode_bits = 0x1f7f, .repeat_period = 164 }, + [RC_TYPE_RC5X_20] = { .name = "rc-5x-20", + .scancode_bits = 0x1f7f3f, .repeat_period = 164 }, + [RC_TYPE_RC5_SZ] = { .name = "rc-5-sz", + .scancode_bits = 0x2fff, .repeat_period = 164 }, + [RC_TYPE_JVC] = { .name = "jvc", + .scancode_bits = 0xffff, .repeat_period = 250 }, + [RC_TYPE_SONY12] = { .name = "sony-12", + .scancode_bits = 0x1f007f, .repeat_period = 100 }, + [RC_TYPE_SONY15] = { .name = "sony-15", + .scancode_bits = 0xff007f, .repeat_period = 100 }, + [RC_TYPE_SONY20] = { .name = "sony-20", + .scancode_bits = 0x1fff7f, .repeat_period = 100 }, + [RC_TYPE_NEC] = { .name = "nec", + .scancode_bits = 0xffff, .repeat_period = 160 }, + [RC_TYPE_NECX] = { .name = "nec-x", + .scancode_bits = 0xffffff, .repeat_period = 160 }, + [RC_TYPE_NEC32] = { .name = "nec-32", + .scancode_bits = 0xffffffff, .repeat_period = 160 }, + [RC_TYPE_SANYO] = { .name = "sanyo", + .scancode_bits = 0x1fffff, .repeat_period = 250 }, + [RC_TYPE_MCIR2_KBD] = { .name = "mcir2-kbd", + .scancode_bits = 0xffff, .repeat_period = 150 }, + [RC_TYPE_MCIR2_MSE] = { .name = "mcir2-mse", + .scancode_bits = 0x1fffff, .repeat_period = 150 }, + [RC_TYPE_RC6_0] = { .name = "rc-6-0", + .scancode_bits = 0xffff, .repeat_period = 164 }, + [RC_TYPE_RC6_6A_20] = { .name = "rc-6-6a-20", + .scancode_bits = 0xfffff, .repeat_period = 164 }, + [RC_TYPE_RC6_6A_24] = { .name = "rc-6-6a-24", + .scancode_bits = 0xffffff, .repeat_period = 164 }, + [RC_TYPE_RC6_6A_32] = { .name = "rc-6-6a-32", + .scancode_bits = 0xffffffff, .repeat_period = 164 }, + [RC_TYPE_RC6_MCE] = { .name = "rc-6-mce", + .scancode_bits = 0xffff7fff, .repeat_period = 164 }, + [RC_TYPE_SHARP] = { .name = "sharp", + .scancode_bits = 0x1fff, .repeat_period = 250 }, + [RC_TYPE_XMP] = { .name = "xmp", .repeat_period = 250 }, + [RC_TYPE_CEC] = { .name = "cec", .repeat_period = 550 }, +}; /* Used to keep track of known keymaps */ static LIST_HEAD(rc_map_list); @@ -613,6 +659,7 @@ static void ir_timer_keyup(unsigned long cookie) void rc_repeat(struct rc_dev *dev) { unsigned long flags; + unsigned int timeout = protocols[dev->last_protocol].repeat_period; spin_lock_irqsave(&dev->keylock, flags); @@ -622,7 +669,7 @@ void rc_repeat(struct rc_dev *dev) input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); input_sync(dev->input_dev); - dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); out: @@ -692,7 +739,8 @@ void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 togg ir_do_keydown(dev, protocol, scancode, keycode, toggle); if (dev->keypressed) { - dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT); + dev->keyup_jiffies = jiffies + + msecs_to_jiffies(protocols[protocol].repeat_period); mod_timer(&dev->timer_keyup, dev->keyup_jiffies); } spin_unlock_irqrestore(&dev->keylock, flags); @@ -733,33 +781,14 @@ EXPORT_SYMBOL_GPL(rc_keydown_notimeout); static int rc_validate_filter(struct rc_dev *dev, struct rc_scancode_filter *filter) { - static const u32 masks[] = { - [RC_TYPE_RC5] = 0x1f7f, - [RC_TYPE_RC5X_20] = 0x1f7f3f, - [RC_TYPE_RC5_SZ] = 0x2fff, - [RC_TYPE_SONY12] = 0x1f007f, - [RC_TYPE_SONY15] = 0xff007f, - [RC_TYPE_SONY20] = 0x1fff7f, - [RC_TYPE_JVC] = 0xffff, - [RC_TYPE_NEC] = 0xffff, - [RC_TYPE_NECX] = 0xffffff, - [RC_TYPE_NEC32] = 0xffffffff, - [RC_TYPE_SANYO] = 0x1fffff, - [RC_TYPE_MCIR2_KBD] = 0xffff, - [RC_TYPE_MCIR2_MSE] = 0x1fffff, - [RC_TYPE_RC6_0] = 0xffff, - [RC_TYPE_RC6_6A_20] = 0xfffff, - [RC_TYPE_RC6_6A_24] = 0xffffff, - [RC_TYPE_RC6_6A_32] = 0xffffffff, - [RC_TYPE_RC6_MCE] = 0xffff7fff, - [RC_TYPE_SHARP] = 0x1fff, - }; - u32 s = filter->data; + u32 mask, s = filter->data; enum rc_type protocol = dev->wakeup_protocol; - if (protocol >= ARRAY_SIZE(masks)) + if (protocol >= ARRAY_SIZE(protocols)) return -EINVAL; + mask = protocols[protocol].scancode_bits; + switch (protocol) { case RC_TYPE_NECX: if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0) @@ -781,14 +810,13 @@ static int rc_validate_filter(struct rc_dev *dev, break; } - filter->data &= masks[protocol]; - filter->mask &= masks[protocol]; + filter->data &= mask; + filter->mask &= mask; /* * If we have to raw encode the IR for wakeup, we cannot have a mask */ - if (dev->encode_wakeup && - filter->mask != 0 && filter->mask != masks[protocol]) + if (dev->encode_wakeup && filter->mask != 0 && filter->mask != mask) return -EINVAL; return 0; @@ -1301,40 +1329,6 @@ unlock: return (ret < 0) ? ret : len; } -/* - * This is the list of all variants of all protocols, which is used by - * the wakeup_protocols sysfs entry. In the protocols sysfs entry some - * some protocols are grouped together (e.g. nec = nec + necx + nec32). - * - * For wakeup we need to know the exact protocol variant so the hardware - * can be programmed exactly what to expect. - */ -static const char * const proto_variant_names[] = { - [RC_TYPE_UNKNOWN] = "unknown", - [RC_TYPE_OTHER] = "other", - [RC_TYPE_RC5] = "rc-5", - [RC_TYPE_RC5X_20] = "rc-5x-20", - [RC_TYPE_RC5_SZ] = "rc-5-sz", - [RC_TYPE_JVC] = "jvc", - [RC_TYPE_SONY12] = "sony-12", - [RC_TYPE_SONY15] = "sony-15", - [RC_TYPE_SONY20] = "sony-20", - [RC_TYPE_NEC] = "nec", - [RC_TYPE_NECX] = "nec-x", - [RC_TYPE_NEC32] = "nec-32", - [RC_TYPE_SANYO] = "sanyo", - [RC_TYPE_MCIR2_KBD] = "mcir2-kbd", - [RC_TYPE_MCIR2_MSE] = "mcir2-mse", - [RC_TYPE_RC6_0] = "rc-6-0", - [RC_TYPE_RC6_6A_20] = "rc-6-6a-20", - [RC_TYPE_RC6_6A_24] = "rc-6-6a-24", - [RC_TYPE_RC6_6A_32] = "rc-6-6a-32", - [RC_TYPE_RC6_MCE] = "rc-6-mce", - [RC_TYPE_SHARP] = "sharp", - [RC_TYPE_XMP] = "xmp", - [RC_TYPE_CEC] = "cec", -}; - /** * show_wakeup_protocols() - shows the wakeup IR protocol * @device: the device descriptor @@ -1369,14 +1363,12 @@ static ssize_t show_wakeup_protocols(struct device *device, IR_dprintk(1, "%s: allowed - 0x%llx, enabled - %d\n", __func__, (long long)allowed, enabled); - for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) { + for (i = 0; i < ARRAY_SIZE(protocols); i++) { if (allowed & (1ULL << i)) { if (i == enabled) - tmp += sprintf(tmp, "[%s] ", - proto_variant_names[i]); + tmp += sprintf(tmp, "[%s] ", protocols[i].name); else - tmp += sprintf(tmp, "%s ", - proto_variant_names[i]); + tmp += sprintf(tmp, "%s ", protocols[i].name); } } @@ -1418,15 +1410,15 @@ static ssize_t store_wakeup_protocols(struct device *device, if (sysfs_streq(buf, "none")) { protocol = RC_TYPE_UNKNOWN; } else { - for (i = 0; i < ARRAY_SIZE(proto_variant_names); i++) { + for (i = 0; i < ARRAY_SIZE(protocols); i++) { if ((allowed & (1ULL << i)) && - sysfs_streq(buf, proto_variant_names[i])) { + sysfs_streq(buf, protocols[i].name)) { protocol = i; break; } } - if (i == ARRAY_SIZE(proto_variant_names)) { + if (i == ARRAY_SIZE(protocols)) { rc = -EINVAL; goto out; } -- cgit v1.2.3 From a9a249a2c997506a64eaee22f1458fda893f62a8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Aug 2017 09:31:24 -0400 Subject: media: cec: fix remote control passthrough The 'Press and Hold' operation was not correctly implemented, in particular the requirement that the repeat doesn't start until the second identical keypress arrives. The REP_DELAY value also had to be adjusted (see the comment in the code) to achieve the desired behavior. The 'enabled_protocols' field was also never set, fix that too. Since CEC is a fixed protocol the driver has to set this field. Signed-off-by: Hans Verkuil Acked-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 56 ++++++++++++++++++++++++++++++++++++++++---- drivers/media/cec/cec-core.c | 13 ++++++++++ include/media/cec.h | 5 ++++ 3 files changed, 69 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index d9adeb505c09..31d25e00d011 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1767,6 +1767,9 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, int la_idx = cec_log_addr2idx(adap, dest_laddr); bool from_unregistered = init_laddr == 0xf; struct cec_msg tx_cec_msg = { }; +#ifdef CONFIG_MEDIA_CEC_RC + int scancode; +#endif dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); @@ -1855,11 +1858,9 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, */ case 0x60: if (msg->len == 2) - rc_keydown(adap->rc, RC_TYPE_CEC, - msg->msg[2], 0); + scancode = msg->msg[2]; else - rc_keydown(adap->rc, RC_TYPE_CEC, - msg->msg[2] << 8 | msg->msg[3], 0); + scancode = msg->msg[2] << 8 | msg->msg[3]; break; /* * Other function messages that are not handled. @@ -1872,11 +1873,54 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, */ case 0x56: case 0x57: case 0x67: case 0x68: case 0x69: case 0x6a: + scancode = -1; break; default: - rc_keydown(adap->rc, RC_TYPE_CEC, msg->msg[2], 0); + scancode = msg->msg[2]; + break; + } + + /* Was repeating, but keypress timed out */ + if (adap->rc_repeating && !adap->rc->keypressed) { + adap->rc_repeating = false; + adap->rc_last_scancode = -1; + } + /* Different keypress from last time, ends repeat mode */ + if (adap->rc_last_scancode != scancode) { + rc_keyup(adap->rc); + adap->rc_repeating = false; + } + /* We can't handle this scancode */ + if (scancode < 0) { + adap->rc_last_scancode = scancode; + break; + } + + /* Send key press */ + rc_keydown(adap->rc, RC_TYPE_CEC, scancode, 0); + + /* When in repeating mode, we're done */ + if (adap->rc_repeating) + break; + + /* + * We are not repeating, but the new scancode is + * the same as the last one, and this second key press is + * within 550 ms (the 'Follower Safety Timeout') from the + * previous key press, so we now enable the repeating mode. + */ + if (adap->rc_last_scancode == scancode && + msg->rx_ts - adap->rc_last_keypress < 550 * NSEC_PER_MSEC) { + adap->rc_repeating = true; break; } + /* + * Not in repeating mode, so avoid triggering repeat mode + * by calling keyup. + */ + rc_keyup(adap->rc); + adap->rc_last_scancode = scancode; + adap->rc_last_keypress = msg->rx_ts; #endif break; @@ -1886,6 +1930,8 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, break; #ifdef CONFIG_MEDIA_CEC_RC rc_keyup(adap->rc); + adap->rc_repeating = false; + adap->rc_last_scancode = -1; #endif break; diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index efb7bbbc941f..fcd01577cd1c 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -276,9 +276,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.version = 1; adap->rc->driver_name = CEC_NAME; adap->rc->allowed_protocols = RC_BIT_CEC; + adap->rc->enabled_protocols = RC_BIT_CEC; adap->rc->priv = adap; adap->rc->map_name = RC_MAP_CEC; adap->rc->timeout = MS_TO_NS(100); + adap->rc_last_scancode = -1; #endif return adap; } @@ -310,6 +312,17 @@ int cec_register_adapter(struct cec_adapter *adap, adap->rc = NULL; return res; } + /* + * The REP_DELAY for CEC is really the time between the initial + * 'User Control Pressed' message and the second. The first + * keypress is always seen as non-repeating, the second + * (provided it has the same UI Command) will start the 'Press + * and Hold' (aka repeat) behavior. By setting REP_DELAY to the + * same value as REP_PERIOD the expected CEC behavior is + * reproduced. + */ + adap->rc->input_dev->rep[REP_DELAY] = + adap->rc->input_dev->rep[REP_PERIOD]; } #endif diff --git a/include/media/cec.h b/include/media/cec.h index d97aa6c32abd..60b26fc18464 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -190,6 +190,11 @@ struct cec_adapter { u32 tx_timeouts; +#ifdef CONFIG_MEDIA_CEC_RC + bool rc_repeating; + int rc_last_scancode; + u64 rc_last_keypress; +#endif #ifdef CONFIG_CEC_NOTIFIER struct cec_notifier *notifier; #endif -- cgit v1.2.3 From 6d741bfed5ed06ed42a16d30f1ed7afdcaf7f092 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Mon, 7 Aug 2017 16:20:58 -0400 Subject: media: rc: rename RC_TYPE_* to RC_PROTO_* and RC_BIT_* to RC_PROTO_BIT_* RC_TYPE is confusing and it's just the protocol. So rename it. Suggested-by: Hans Verkuil Signed-off-by: Sean Young Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-picolcd_cir.c | 2 +- drivers/media/cec/cec-adap.c | 2 +- drivers/media/cec/cec-core.c | 4 +- drivers/media/common/siano/smsir.c | 2 +- drivers/media/i2c/ir-kbd-i2c.c | 57 +++--- drivers/media/pci/bt8xx/bttv-input.c | 16 +- drivers/media/pci/cx18/cx18-i2c.c | 4 +- drivers/media/pci/cx23885/cx23885-input.c | 14 +- drivers/media/pci/cx88/cx88-input.c | 28 +-- drivers/media/pci/dm1105/dm1105.c | 2 +- drivers/media/pci/ivtv/ivtv-i2c.c | 14 +- drivers/media/pci/mantis/mantis_input.c | 2 +- drivers/media/pci/saa7134/saa7134-input.c | 46 +++-- drivers/media/pci/smipcie/smipcie-ir.c | 2 +- drivers/media/pci/ttpci/budget-ci.c | 5 +- drivers/media/rc/ati_remote.c | 5 +- drivers/media/rc/ene_ir.c | 2 +- drivers/media/rc/fintek-cir.c | 2 +- drivers/media/rc/gpio-ir-recv.c | 2 +- drivers/media/rc/igorplugusb.c | 9 +- drivers/media/rc/iguanair.c | 2 +- drivers/media/rc/img-ir/img-ir-hw.c | 4 +- drivers/media/rc/img-ir/img-ir-hw.h | 4 +- drivers/media/rc/img-ir/img-ir-jvc.c | 4 +- drivers/media/rc/img-ir/img-ir-nec.c | 20 +- drivers/media/rc/img-ir/img-ir-rc5.c | 4 +- drivers/media/rc/img-ir/img-ir-rc6.c | 4 +- drivers/media/rc/img-ir/img-ir-sanyo.c | 4 +- drivers/media/rc/img-ir/img-ir-sharp.c | 4 +- drivers/media/rc/img-ir/img-ir-sony.c | 27 +-- drivers/media/rc/imon.c | 49 ++--- drivers/media/rc/ir-hix5hd2.c | 2 +- drivers/media/rc/ir-jvc-decoder.c | 6 +- drivers/media/rc/ir-mce_kbd-decoder.c | 6 +- drivers/media/rc/ir-nec-decoder.c | 17 +- drivers/media/rc/ir-rc5-decoder.c | 25 +-- drivers/media/rc/ir-rc6-decoder.c | 30 +-- drivers/media/rc/ir-sanyo-decoder.c | 6 +- drivers/media/rc/ir-sharp-decoder.c | 6 +- drivers/media/rc/ir-sony-decoder.c | 23 +-- drivers/media/rc/ir-xmp-decoder.c | 4 +- drivers/media/rc/ite-cir.c | 2 +- drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c | 8 +- drivers/media/rc/keymaps/rc-alink-dtu-m.c | 8 +- drivers/media/rc/keymaps/rc-anysee.c | 8 +- drivers/media/rc/keymaps/rc-apac-viewcomp.c | 8 +- drivers/media/rc/keymaps/rc-asus-pc39.c | 8 +- drivers/media/rc/keymaps/rc-asus-ps3-100.c | 8 +- drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c | 8 +- drivers/media/rc/keymaps/rc-ati-x10.c | 8 +- drivers/media/rc/keymaps/rc-avermedia-a16d.c | 8 +- drivers/media/rc/keymaps/rc-avermedia-cardbus.c | 8 +- drivers/media/rc/keymaps/rc-avermedia-dvbt.c | 8 +- drivers/media/rc/keymaps/rc-avermedia-m135a.c | 8 +- .../media/rc/keymaps/rc-avermedia-m733a-rm-k6.c | 8 +- drivers/media/rc/keymaps/rc-avermedia-rm-ks.c | 8 +- drivers/media/rc/keymaps/rc-avermedia.c | 8 +- drivers/media/rc/keymaps/rc-avertv-303.c | 8 +- drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c | 8 +- drivers/media/rc/keymaps/rc-behold-columbus.c | 8 +- drivers/media/rc/keymaps/rc-behold.c | 8 +- drivers/media/rc/keymaps/rc-budget-ci-old.c | 8 +- drivers/media/rc/keymaps/rc-cec.c | 2 +- drivers/media/rc/keymaps/rc-cinergy-1400.c | 8 +- drivers/media/rc/keymaps/rc-cinergy.c | 8 +- drivers/media/rc/keymaps/rc-d680-dmb.c | 8 +- drivers/media/rc/keymaps/rc-delock-61959.c | 8 +- drivers/media/rc/keymaps/rc-dib0700-nec.c | 8 +- drivers/media/rc/keymaps/rc-dib0700-rc5.c | 8 +- drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c | 8 +- drivers/media/rc/keymaps/rc-digittrade.c | 8 +- drivers/media/rc/keymaps/rc-dm1105-nec.c | 8 +- drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c | 8 +- drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c | 8 +- drivers/media/rc/keymaps/rc-dtt200u.c | 8 +- drivers/media/rc/keymaps/rc-dvbsky.c | 8 +- drivers/media/rc/keymaps/rc-dvico-mce.c | 8 +- drivers/media/rc/keymaps/rc-dvico-portable.c | 8 +- drivers/media/rc/keymaps/rc-em-terratec.c | 8 +- drivers/media/rc/keymaps/rc-encore-enltv-fm53.c | 8 +- drivers/media/rc/keymaps/rc-encore-enltv.c | 8 +- drivers/media/rc/keymaps/rc-encore-enltv2.c | 8 +- drivers/media/rc/keymaps/rc-evga-indtube.c | 8 +- drivers/media/rc/keymaps/rc-eztv.c | 8 +- drivers/media/rc/keymaps/rc-flydvb.c | 8 +- drivers/media/rc/keymaps/rc-flyvideo.c | 8 +- drivers/media/rc/keymaps/rc-fusionhdtv-mce.c | 8 +- drivers/media/rc/keymaps/rc-gadmei-rm008z.c | 8 +- drivers/media/rc/keymaps/rc-geekbox.c | 8 +- drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c | 8 +- drivers/media/rc/keymaps/rc-gotview7135.c | 8 +- drivers/media/rc/keymaps/rc-hauppauge.c | 8 +- drivers/media/rc/keymaps/rc-imon-mce.c | 8 +- drivers/media/rc/keymaps/rc-imon-pad.c | 8 +- drivers/media/rc/keymaps/rc-iodata-bctv7e.c | 8 +- drivers/media/rc/keymaps/rc-it913x-v1.c | 8 +- drivers/media/rc/keymaps/rc-it913x-v2.c | 8 +- drivers/media/rc/keymaps/rc-kaiomy.c | 8 +- drivers/media/rc/keymaps/rc-kworld-315u.c | 8 +- drivers/media/rc/keymaps/rc-kworld-pc150u.c | 8 +- .../media/rc/keymaps/rc-kworld-plus-tv-analog.c | 8 +- drivers/media/rc/keymaps/rc-leadtek-y04g0051.c | 8 +- drivers/media/rc/keymaps/rc-lme2510.c | 8 +- drivers/media/rc/keymaps/rc-manli.c | 8 +- .../media/rc/keymaps/rc-medion-x10-digitainer.c | 8 +- drivers/media/rc/keymaps/rc-medion-x10-or2x.c | 8 +- drivers/media/rc/keymaps/rc-medion-x10.c | 8 +- drivers/media/rc/keymaps/rc-msi-digivox-ii.c | 8 +- drivers/media/rc/keymaps/rc-msi-digivox-iii.c | 8 +- drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c | 8 +- drivers/media/rc/keymaps/rc-msi-tvanywhere.c | 8 +- drivers/media/rc/keymaps/rc-nebula.c | 8 +- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 8 +- drivers/media/rc/keymaps/rc-norwood.c | 8 +- drivers/media/rc/keymaps/rc-npgtech.c | 8 +- drivers/media/rc/keymaps/rc-pctv-sedna.c | 8 +- drivers/media/rc/keymaps/rc-pinnacle-color.c | 8 +- drivers/media/rc/keymaps/rc-pinnacle-grey.c | 8 +- drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | 8 +- drivers/media/rc/keymaps/rc-pixelview-002t.c | 8 +- drivers/media/rc/keymaps/rc-pixelview-mk12.c | 8 +- drivers/media/rc/keymaps/rc-pixelview-new.c | 8 +- drivers/media/rc/keymaps/rc-pixelview.c | 8 +- .../media/rc/keymaps/rc-powercolor-real-angel.c | 8 +- drivers/media/rc/keymaps/rc-proteus-2309.c | 8 +- drivers/media/rc/keymaps/rc-purpletv.c | 8 +- drivers/media/rc/keymaps/rc-pv951.c | 8 +- drivers/media/rc/keymaps/rc-rc6-mce.c | 8 +- .../media/rc/keymaps/rc-real-audio-220-32-keys.c | 8 +- drivers/media/rc/keymaps/rc-reddo.c | 8 +- drivers/media/rc/keymaps/rc-snapstream-firefly.c | 8 +- drivers/media/rc/keymaps/rc-streamzap.c | 8 +- drivers/media/rc/keymaps/rc-su3000.c | 8 +- drivers/media/rc/keymaps/rc-tbs-nec.c | 8 +- drivers/media/rc/keymaps/rc-technisat-ts35.c | 8 +- drivers/media/rc/keymaps/rc-technisat-usb2.c | 8 +- .../media/rc/keymaps/rc-terratec-cinergy-c-pci.c | 8 +- .../media/rc/keymaps/rc-terratec-cinergy-s2-hd.c | 8 +- drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c | 8 +- drivers/media/rc/keymaps/rc-terratec-slim-2.c | 8 +- drivers/media/rc/keymaps/rc-terratec-slim.c | 8 +- drivers/media/rc/keymaps/rc-tevii-nec.c | 8 +- drivers/media/rc/keymaps/rc-tivo.c | 8 +- .../media/rc/keymaps/rc-total-media-in-hand-02.c | 8 +- drivers/media/rc/keymaps/rc-total-media-in-hand.c | 8 +- drivers/media/rc/keymaps/rc-trekstor.c | 8 +- drivers/media/rc/keymaps/rc-tt-1500.c | 8 +- drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c | 8 +- drivers/media/rc/keymaps/rc-twinhan1027.c | 8 +- drivers/media/rc/keymaps/rc-videomate-m1f.c | 8 +- drivers/media/rc/keymaps/rc-videomate-s350.c | 8 +- drivers/media/rc/keymaps/rc-videomate-tv-pvr.c | 8 +- drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 8 +- drivers/media/rc/keymaps/rc-winfast.c | 8 +- drivers/media/rc/keymaps/rc-zx-irdec.c | 2 +- drivers/media/rc/mceusb.c | 2 +- drivers/media/rc/meson-ir.c | 2 +- drivers/media/rc/mtk-cir.c | 2 +- drivers/media/rc/nuvoton-cir.c | 4 +- drivers/media/rc/rc-core-priv.h | 2 +- drivers/media/rc/rc-ir-raw.c | 4 +- drivers/media/rc/rc-loopback.c | 4 +- drivers/media/rc/rc-main.c | 152 ++++++++------- drivers/media/rc/redrat3.c | 2 +- drivers/media/rc/serial_ir.c | 2 +- drivers/media/rc/sir_ir.c | 2 +- drivers/media/rc/st_rc.c | 2 +- drivers/media/rc/streamzap.c | 2 +- drivers/media/rc/sunxi-cir.c | 2 +- drivers/media/rc/ttusbir.c | 2 +- drivers/media/rc/winbond-cir.c | 33 ++-- drivers/media/rc/zx-irdec.c | 9 +- drivers/media/usb/au0828/au0828-input.c | 4 +- drivers/media/usb/cx231xx/cx231xx-input.c | 6 +- drivers/media/usb/dvb-usb-v2/af9015.c | 11 +- drivers/media/usb/dvb-usb-v2/af9035.c | 14 +- drivers/media/usb/dvb-usb-v2/anysee.c | 4 +- drivers/media/usb/dvb-usb-v2/az6007.c | 11 +- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 2 +- drivers/media/usb/dvb-usb-v2/dvbsky.c | 4 +- drivers/media/usb/dvb-usb-v2/lmedm04.c | 6 +- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 13 +- drivers/media/usb/dvb-usb/cxusb.c | 30 +-- drivers/media/usb/dvb-usb/dib0700.h | 2 +- drivers/media/usb/dvb-usb/dib0700_core.c | 28 +-- drivers/media/usb/dvb-usb/dib0700_devices.c | 152 +++++++-------- drivers/media/usb/dvb-usb/dtt200u.c | 12 +- drivers/media/usb/dvb-usb/dvb-usb.h | 2 +- drivers/media/usb/dvb-usb/dw2102.c | 21 +- drivers/media/usb/dvb-usb/m920x.c | 4 +- drivers/media/usb/dvb-usb/pctv452e.c | 6 +- drivers/media/usb/dvb-usb/technisat-usb2.c | 2 +- drivers/media/usb/dvb-usb/ttusb2.c | 4 +- drivers/media/usb/em28xx/em28xx-input.c | 124 ++++++------ drivers/media/usb/hdpvr/hdpvr-i2c.c | 3 +- drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 10 +- drivers/media/usb/tm6000/tm6000-input.c | 38 ++-- include/media/i2c/ir-kbd-i2c.h | 8 +- include/media/rc-core.h | 33 ++-- include/media/rc-map.h | 215 +++++++++++---------- 200 files changed, 1204 insertions(+), 1158 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index b3b2233f3c65..32747b7f917e 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -113,7 +113,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) return -ENOMEM; rdev->priv = data; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->open = picolcd_cir_open; rdev->close = picolcd_cir_close; rdev->device_name = data->hdev->name; diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 31d25e00d011..9f8b64f2b253 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1897,7 +1897,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, } /* Send key press */ - rc_keydown(adap->rc, RC_TYPE_CEC, scancode, 0); + rc_keydown(adap->rc, RC_PROTO_CEC, scancode, 0); /* When in repeating mode, we're done */ if (adap->rc_repeating) diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index fcd01577cd1c..e9db90997b0a 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -275,8 +275,8 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->input_id.product = 0; adap->rc->input_id.version = 1; adap->rc->driver_name = CEC_NAME; - adap->rc->allowed_protocols = RC_BIT_CEC; - adap->rc->enabled_protocols = RC_BIT_CEC; + adap->rc->allowed_protocols = RC_PROTO_BIT_CEC; + adap->rc->enabled_protocols = RC_PROTO_BIT_CEC; adap->rc->priv = adap; adap->rc->map_name = RC_MAP_CEC; adap->rc->timeout = MS_TO_NS(100); diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 941c342896cc..e77bb0c95e69 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -86,7 +86,7 @@ int sms_ir_init(struct smscore_device_t *coredev) #endif dev->priv = coredev; - dev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; dev->map_name = sms_get_board(board_id)->rc_codes; dev->driver_name = MODULE_NAME; diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index af909bf5dd5b..a374e2a0ac3d 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -59,8 +59,8 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */ /* ----------------------------------------------------------------------- */ -static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol, - u32 *scancode, u8 *ptoggle, int size) +static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol, + u32 *scancode, u8 *ptoggle, int size) { unsigned char buf[6]; int start, range, toggle, dev, code, ircode, vendor; @@ -99,7 +99,7 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol, dprintk(1, "ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n", start, range, toggle, dev, code); - *protocol = RC_TYPE_RC5; + *protocol = RC_PROTO_RC5; *scancode = RC_SCANCODE_RC5(dev, code); *ptoggle = toggle; @@ -111,13 +111,13 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol, if (vendor == 0x800f) { *ptoggle = (dev & 0x80) != 0; - *protocol = RC_TYPE_RC6_MCE; + *protocol = RC_PROTO_RC6_MCE; dev &= 0x7f; dprintk(1, "ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n", *ptoggle, vendor, dev, code); } else { *ptoggle = 0; - *protocol = RC_TYPE_RC6_6A_32; + *protocol = RC_PROTO_RC6_6A_32; dprintk(1, "ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n", vendor, dev, code); } @@ -130,13 +130,13 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol, return 0; } -static int get_key_haup(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_haup(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { return get_key_haup_common(ir, protocol, scancode, toggle, 3); } -static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { int ret; @@ -155,7 +155,7 @@ static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_type *protocol, return get_key_haup_common(ir, protocol, scancode, toggle, 6); } -static int get_key_pixelview(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -166,13 +166,13 @@ static int get_key_pixelview(struct IR_i2c *ir, enum rc_type *protocol, return -EIO; } - *protocol = RC_TYPE_OTHER; + *protocol = RC_PROTO_OTHER; *scancode = b; *toggle = 0; return 1; } -static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char buf[4]; @@ -191,13 +191,13 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_type *protocol, if(buf[0] != 0x1 || buf[1] != 0xfe) return 0; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = buf[2]; *toggle = 0; return 1; } -static int get_key_knc1(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -221,13 +221,13 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_type *protocol, /* keep old data */ return 1; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; } -static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char subaddr, key, keygroup; @@ -262,7 +262,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_type *protocol, } key |= (keygroup & 1) << 6; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = key; if (ir->c->addr == 0x41) /* AVerMedia EM78P153 */ *scancode |= keygroup << 8; @@ -274,7 +274,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_type *protocol, static int ir_key_poll(struct IR_i2c *ir) { - enum rc_type protocol; + enum rc_proto protocol; u32 scancode; u8 toggle; int rc; @@ -315,7 +315,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) { char *ir_codes = NULL; const char *name = NULL; - u64 rc_type = RC_BIT_UNKNOWN; + u64 rc_proto = RC_PROTO_BIT_UNKNOWN; struct IR_i2c *ir; struct rc_dev *rc = NULL; struct i2c_adapter *adap = client->adapter; @@ -334,7 +334,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) case 0x64: name = "Pixelview"; ir->get_key = get_key_pixelview; - rc_type = RC_BIT_OTHER; + rc_proto = RC_PROTO_BIT_OTHER; ir_codes = RC_MAP_EMPTY; break; case 0x18: @@ -342,38 +342,39 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) case 0x1a: name = "Hauppauge"; ir->get_key = get_key_haup; - rc_type = RC_BIT_RC5; + rc_proto = RC_PROTO_BIT_RC5; ir_codes = RC_MAP_HAUPPAUGE; break; case 0x30: name = "KNC One"; ir->get_key = get_key_knc1; - rc_type = RC_BIT_OTHER; + rc_proto = RC_PROTO_BIT_OTHER; ir_codes = RC_MAP_EMPTY; break; case 0x6b: name = "FusionHDTV"; ir->get_key = get_key_fusionhdtv; - rc_type = RC_BIT_UNKNOWN; + rc_proto = RC_PROTO_BIT_UNKNOWN; ir_codes = RC_MAP_FUSIONHDTV_MCE; break; case 0x40: name = "AVerMedia Cardbus remote"; ir->get_key = get_key_avermedia_cardbus; - rc_type = RC_BIT_OTHER; + rc_proto = RC_PROTO_BIT_OTHER; ir_codes = RC_MAP_AVERMEDIA_CARDBUS; break; case 0x41: name = "AVerMedia EM78P153"; ir->get_key = get_key_avermedia_cardbus; - rc_type = RC_BIT_OTHER; + rc_proto = RC_PROTO_BIT_OTHER; /* RM-KV remote, seems to be same as RM-K6 */ ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6; break; case 0x71: name = "Hauppauge/Zilog Z8"; ir->get_key = get_key_haup_xvr; - rc_type = RC_BIT_RC5 | RC_BIT_RC6_MCE | RC_BIT_RC6_6A_32; + rc_proto = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_RC6_6A_32; ir_codes = RC_MAP_HAUPPAUGE; break; } @@ -388,7 +389,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) name = init_data->name; if (init_data->type) - rc_type = init_data->type; + rc_proto = init_data->type; if (init_data->polling_interval) ir->polling_interval = init_data->polling_interval; @@ -431,7 +432,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ir->rc = rc; /* Make sure we are all setup before going on */ - if (!name || !ir->get_key || !rc_type || !ir_codes) { + if (!name || !ir->get_key || !rc_proto || !ir_codes) { dprintk(1, ": Unsupported device at address 0x%02x\n", addr); err = -ENODEV; @@ -458,8 +459,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) * Initialize the other fields of rc_dev */ rc->map_name = ir->ir_codes; - rc->allowed_protocols = rc_type; - rc->enabled_protocols = rc_type; + rc->allowed_protocols = rc_proto; + rc->enabled_protocols = rc_proto; if (!rc->driver_name) rc->driver_name = MODULE_NAME; diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index bb8eda51ee27..73d655d073d6 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -69,12 +69,13 @@ static void ir_handle_key(struct bttv *btv) if ((ir->mask_keydown && (gpio & ir->mask_keydown)) || (ir->mask_keyup && !(gpio & ir->mask_keyup))) { - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); } else { /* HACK: Probably, ir->mask_keydown is missing for this board */ if (btv->c.type == BTTV_BOARD_WINFAST2000) - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); rc_keyup(ir->dev); } @@ -99,7 +100,7 @@ static void ir_enltv_handle_key(struct bttv *btv) gpio, data, (gpio & ir->mask_keyup) ? " up" : "up/down"); - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); if (keyup) rc_keyup(ir->dev); } else { @@ -113,7 +114,8 @@ static void ir_enltv_handle_key(struct bttv *btv) if (keyup) rc_keyup(ir->dev); else - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); } ir->last_gpio = data | keyup; @@ -235,7 +237,7 @@ static void bttv_rc5_timer_end(unsigned long data) } scancode = RC_SCANCODE_RC5(system, command); - rc_keydown(ir->dev, RC_TYPE_RC5, scancode, toggle); + rc_keydown(ir->dev, RC_PROTO_RC5, scancode, toggle); dprintk("scancode %x, toggle %x\n", scancode, toggle); } @@ -327,7 +329,7 @@ static void bttv_ir_stop(struct bttv *btv) * Get_key functions used by I2C remotes */ -static int get_key_pv951(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -355,7 +357,7 @@ static int get_key_pv951(struct IR_i2c *ir, enum rc_type *protocol, * the device is bound to the vendor-provided RC. */ - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c index eabdd4c5520a..b89fbcbfb491 100644 --- a/drivers/media/pci/cx18/cx18-i2c.c +++ b/drivers/media/pci/cx18/cx18-i2c.c @@ -93,8 +93,8 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw, case CX18_HW_Z8F0811_IR_RX_HAUP: init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_BIT_RC5 | RC_BIT_RC6_MCE | - RC_BIT_RC6_6A_32; + init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_RC6_6A_32; init_data->name = cx->card_name; info.platform_data = init_data; break; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index c9b8e3f4d9fb..944b70831f12 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -284,32 +284,32 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1290: case CX23885_BOARD_HAUPPAUGE_HVR1250: /* Integrated CX2388[58] IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; /* The grey Hauppauge RC-5 remote */ rc_map = RC_MAP_HAUPPAUGE; break; case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; /* The grey Terratec remote with orange buttons */ rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS; break; case CX23885_BOARD_TEVII_S470: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; /* A guess at the remote */ rc_map = RC_MAP_TEVII_NEC; break; case CX23885_BOARD_MYGICA_X8507: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; /* A guess at the remote */ rc_map = RC_MAP_TOTAL_MEDIA_IN_HAND_02; break; case CX23885_BOARD_TBS_6980: case CX23885_BOARD_TBS_6981: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; /* A guess at the remote */ rc_map = RC_MAP_TBS_NEC; break; @@ -320,12 +320,12 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_DVBSKY_S952: case CX23885_BOARD_DVBSKY_T982: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; rc_map = RC_MAP_DVBSKY; break; case CX23885_BOARD_TT_CT2_4500_CI: /* Integrated CX23885 IR controller */ - allowed_protos = RC_BIT_ALL_IR_DECODER; + allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; rc_map = RC_MAP_TT_1500; break; default: diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index a5dbee776455..e02449bf2041 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -132,7 +132,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) data = (data << 4) | ((gpio_key & 0xf0) >> 4); - rc_keydown(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown(ir->dev, RC_PROTO_UNKNOWN, data, 0); } else if (ir->core->boardnr == CX88_BOARD_PROLINK_PLAYTVPVR || ir->core->boardnr == CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO) { @@ -146,7 +146,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) scancode = RC_SCANCODE_NECX(addr, cmd); if (0 == (gpio & ir->mask_keyup)) - rc_keydown_notimeout(ir->dev, RC_TYPE_NECX, scancode, + rc_keydown_notimeout(ir->dev, RC_PROTO_NECX, scancode, 0); else rc_keyup(ir->dev); @@ -154,20 +154,22 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) } else if (ir->mask_keydown) { /* bit set on keydown */ if (gpio & ir->mask_keydown) - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); else rc_keyup(ir->dev); } else if (ir->mask_keyup) { /* bit cleared on keydown */ if (0 == (gpio & ir->mask_keyup)) - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); else rc_keyup(ir->dev); } else { /* can't distinguish keydown/up :-/ */ - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, 0); rc_keyup(ir->dev); } } @@ -267,7 +269,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) struct cx88_IR *ir; struct rc_dev *dev; char *ir_codes = NULL; - u64 rc_type = RC_BIT_OTHER; + u64 rc_proto = RC_PROTO_BIT_OTHER; int err = -ENOMEM; u32 hardware_mask = 0; /* For devices with a hardware mask, when * used with a full-code IR table @@ -348,7 +350,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) * 002-T mini RC, provided with newer PV hardware */ ir_codes = RC_MAP_PIXELVIEW_MK12; - rc_type = RC_BIT_NECX; + rc_proto = RC_PROTO_BIT_NECX; ir->gpio_addr = MO_GP1_IO; ir->mask_keyup = 0x80; ir->polling = 10; /* ms */ @@ -487,7 +489,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) dev->timeout = 10 * 1000 * 1000; /* 10 ms */ } else { dev->driver_type = RC_DRIVER_SCANCODE; - dev->allowed_protocols = rc_type; + dev->allowed_protocols = rc_proto; } ir->core = core; @@ -557,7 +559,7 @@ void cx88_ir_irq(struct cx88_core *core) ir_raw_event_handle(ir->dev); } -static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pvr2000(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { int flags, code; @@ -582,7 +584,7 @@ static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol, dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", code & 0xff, flags & 0xff); - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = code & 0xff; *toggle = 0; return 1; @@ -612,7 +614,7 @@ void cx88_i2c_init_ir(struct cx88_core *core) case CX88_BOARD_LEADTEK_PVR2000: addr_list = pvr2000_addr_list; core->init_data.name = "cx88 Leadtek PVR 2000 remote"; - core->init_data.type = RC_BIT_UNKNOWN; + core->init_data.type = RC_PROTO_BIT_UNKNOWN; core->init_data.get_key = get_key_pvr2000; core->init_data.ir_codes = RC_MAP_EMPTY; break; @@ -633,8 +635,8 @@ void cx88_i2c_init_ir(struct cx88_core *core) /* Hauppauge XVR */ core->init_data.name = "cx88 Hauppauge XVR remote"; core->init_data.ir_codes = RC_MAP_HAUPPAUGE; - core->init_data.type = RC_BIT_RC5 | RC_BIT_RC6_MCE | - RC_BIT_RC6_6A_32; + core->init_data.type = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_RC6_6A_32; core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; info.platform_data = &core->init_data; diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 0bc618f36385..7c3900dec368 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -675,7 +675,7 @@ static void dm1105_emit_key(struct work_struct *work) data = (ircom >> 8) & 0x7f; /* FIXME: UNKNOWN because we don't generate a full NEC scancode (yet?) */ - rc_keydown(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown(ir->dev, RC_PROTO_UNKNOWN, data, 0); } /* work handler */ diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c index dea80efd5836..69b4fa6f0362 100644 --- a/drivers/media/pci/ivtv/ivtv-i2c.c +++ b/drivers/media/pci/ivtv/ivtv-i2c.c @@ -148,7 +148,7 @@ static const char * const hw_devicenames[] = { "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */ }; -static int get_key_adaptec(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_adaptec(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char keybuf[4]; @@ -168,7 +168,7 @@ static int get_key_adaptec(struct IR_i2c *ir, enum rc_type *protocol, keybuf[2] &= 0x7f; keybuf[3] |= 0x80; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24; *toggle = 0; return 1; @@ -201,22 +201,22 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS; init_data->internal_get_key_func = IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; - init_data->type = RC_BIT_OTHER; + init_data->type = RC_PROTO_BIT_OTHER; init_data->name = "AVerMedia AVerTV card"; break; case IVTV_HW_I2C_IR_RX_HAUP_EXT: case IVTV_HW_I2C_IR_RX_HAUP_INT: init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; - init_data->type = RC_BIT_RC5; + init_data->type = RC_PROTO_BIT_RC5; init_data->name = itv->card_name; break; case IVTV_HW_Z8F0811_IR_RX_HAUP: /* Default to grey remote */ init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_BIT_RC5 | RC_BIT_RC6_MCE | - RC_BIT_RC6_6A_32; + init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_RC6_6A_32; init_data->name = itv->card_name; break; case IVTV_HW_I2C_IR_RX_ADAPTEC: @@ -224,7 +224,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) init_data->name = itv->card_name; /* FIXME: The protocol and RC_MAP needs to be corrected */ init_data->ir_codes = RC_MAP_EMPTY; - init_data->type = RC_BIT_UNKNOWN; + init_data->type = RC_PROTO_BIT_UNKNOWN; break; } diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c index 001b7f827699..7519dcc934dd 100644 --- a/drivers/media/pci/mantis/mantis_input.c +++ b/drivers/media/pci/mantis/mantis_input.c @@ -31,7 +31,7 @@ void mantis_input_process(struct mantis_pci *mantis, int scancode) { if (mantis->rc) - rc_keydown(mantis->rc, RC_TYPE_UNKNOWN, scancode, 0); + rc_keydown(mantis->rc, RC_PROTO_UNKNOWN, scancode, 0); } int mantis_input_init(struct mantis_pci *mantis) diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index a14b86d88afb..9337e4615519 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -83,14 +83,16 @@ static int build_key(struct saa7134_dev *dev) if (data == ir->mask_keycode) rc_keyup(ir->dev); else - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); return 0; } if (ir->polling) { if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); } else { rc_keyup(ir->dev); } @@ -98,7 +100,8 @@ static int build_key(struct saa7134_dev *dev) else { /* IRQ driven mode - handle key press and release in one go */ if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0); + rc_keydown_notimeout(ir->dev, RC_PROTO_UNKNOWN, data, + 0); rc_keyup(ir->dev); } } @@ -108,7 +111,7 @@ static int build_key(struct saa7134_dev *dev) /* --------------------- Chip specific I2C key builders ----------------- */ -static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { int gpio; @@ -154,13 +157,14 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol, return -EIO; } - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; } -static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, + enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -201,14 +205,14 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol /* Button pressed */ input_dbg("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; } /* copied and modified from get_key_msi_tvanywhere_plus() */ -static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -249,13 +253,13 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol, /* Button pressed */ input_dbg("get_key_kworld_pc150u: Key = 0x%02X\n", b); - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; } -static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_purpletv(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char b; @@ -274,13 +278,13 @@ static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol, if (b & 0x80) return 1; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; *toggle = 0; return 1; } -static int get_key_hvr1110(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_hvr1110(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char buf[5]; @@ -304,14 +308,14 @@ static int get_key_hvr1110(struct IR_i2c *ir, enum rc_type *protocol, * * FIXME: start bits could maybe be used...? */ - *protocol = RC_TYPE_RC5; + *protocol = RC_PROTO_RC5; *scancode = RC_SCANCODE_RC5(buf[3] & 0x1f, buf[4] >> 2); *toggle = !!(buf[3] & 0x40); return 1; } -static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { unsigned char data[12]; @@ -338,7 +342,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, if (data[9] != (unsigned char)(~data[8])) return 0; - *protocol = RC_TYPE_NECX; + *protocol = RC_PROTO_NECX; *scancode = RC_SCANCODE_NECX(data[11] << 8 | data[10], data[9]); *toggle = 0; return 1; @@ -347,7 +351,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, /* Common (grey or coloured) pinnacle PCTV remote handling * */ -static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pinnacle(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle, int parity_offset, int marker, int code_modulo) { @@ -384,7 +388,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, code %= code_modulo; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = code; *toggle = 0; @@ -401,7 +405,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol, * * Sylvain Pasche */ -static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { @@ -413,7 +417,7 @@ static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_type *protocol, * * Ricardo Cerqueira */ -static int get_key_pinnacle_color(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_pinnacle_color(struct IR_i2c *ir, enum rc_proto *protocol, u32 *scancode, u8 *toggle) { /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE @@ -858,7 +862,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) rc->close = saa7134_ir_close; if (raw_decode) { rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; } rc->device_name = ir->name; @@ -1022,7 +1026,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "BeholdTV"; dev->init_data.get_key = get_key_beholdm6xx; dev->init_data.ir_codes = RC_MAP_BEHOLD; - dev->init_data.type = RC_BIT_NECX; + dev->init_data.type = RC_PROTO_BIT_NECX; info.addr = 0x2d; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c index fc3375720a35..c5595af6b976 100644 --- a/drivers/media/pci/smipcie/smipcie-ir.c +++ b/drivers/media/pci/smipcie/smipcie-ir.c @@ -144,7 +144,7 @@ static void smi_ir_decode(struct work_struct *work) rc5_system = (dwIRCode & 0x7C0) >> 6; toggle = (dwIRCode & 0x800) ? 1 : 0; scancode = rc5_system << 8 | rc5_command; - rc_keydown(rc_dev, RC_TYPE_RC5, scancode, toggle); + rc_keydown(rc_dev, RC_PROTO_RC5, scancode, toggle); } } end_ir_decode: diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index cf185c83cc9e..57af11804fd6 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -158,14 +158,15 @@ static void msp430_ir_interrupt(unsigned long data) return; if (budget_ci->ir.full_rc5) { - rc_keydown(dev, RC_TYPE_RC5, + rc_keydown(dev, RC_PROTO_RC5, RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key), !!(command & 0x20)); return; } /* FIXME: We should generate complete scancodes for all devices */ - rc_keydown(dev, RC_TYPE_UNKNOWN, budget_ci->ir.ir_key, !!(command & 0x20)); + rc_keydown(dev, RC_PROTO_UNKNOWN, budget_ci->ir.ir_key, + !!(command & 0x20)); } static int msp430_ir_init(struct budget_ci *budget_ci) diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index a7f76002b30a..d0871d60a723 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -622,7 +622,8 @@ static void ati_remote_input_report(struct urb *urb) * it would cause ghost repeats which would be a * regression for this driver. */ - rc_keydown_notimeout(ati_remote->rdev, RC_TYPE_OTHER, + rc_keydown_notimeout(ati_remote->rdev, + RC_PROTO_OTHER, scancode, data[2]); rc_keyup(ati_remote->rdev); } @@ -760,7 +761,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote) struct rc_dev *rdev = ati_remote->rdev; rdev->priv = ati_remote; - rdev->allowed_protocols = RC_BIT_OTHER; + rdev->allowed_protocols = RC_PROTO_BIT_OTHER; rdev->driver_name = "ati_remote"; rdev->open = ati_remote_rc_open; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 41f6b1c52407..af7ba23e16e1 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -1053,7 +1053,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!dev->hw_learning_and_tx_capable) learning_mode_force = false; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->priv = dev; rdev->open = ene_open; rdev->close = ene_close; diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 57155e4c9f38..f2639d0c2fca 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -529,7 +529,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id /* Set up the rc device */ rdev->priv = fintek; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->open = fintek_open; rdev->close = fintek_close; rdev->device_name = FINTEK_DESCRIPTION; diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 24c7ac8f1b82..7248b3662285 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -143,7 +143,7 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) if (pdata->allowed_protos) rcdev->allowed_protocols = pdata->allowed_protos; else - rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index 5babc6371df4..a5ea86be8f44 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -202,10 +202,11 @@ static int igorplugusb_probe(struct usb_interface *intf, * This device can only store 36 pulses + spaces, which is not enough * for the NEC protocol and many others. */ - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER & ~(RC_BIT_NEC | - RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_6A_20 | - RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | - RC_BIT_SONY20 | RC_BIT_SANYO); + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER & + ~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | + RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 | + RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO); rc->priv = ir; rc->driver_name = DRIVER_NAME; diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 4357dd36d7b9..30e24da67226 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -491,7 +491,7 @@ static int iguanair_probe(struct usb_interface *intf, rc->input_phys = ir->phys; usb_to_input_id(ir->udev, &rc->input_id); rc->dev.parent = &intf->dev; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->priv = ir; rc->open = iguanair_open; rc->close = iguanair_close; diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index dd46973e0cbf..82fdf4cc0824 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -589,7 +589,7 @@ static void img_ir_set_decoder(struct img_ir_priv *priv, /* clear the wakeup scancode filter */ rdev->scancode_wakeup_filter.data = 0; rdev->scancode_wakeup_filter.mask = 0; - rdev->wakeup_protocol = RC_TYPE_UNKNOWN; + rdev->wakeup_protocol = RC_PROTO_UNKNOWN; /* clear raw filters */ _img_ir_set_filter(priv, NULL); @@ -823,7 +823,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) int ret = IMG_IR_SCANCODE; struct img_ir_scancode_req request; - request.protocol = RC_TYPE_UNKNOWN; + request.protocol = RC_PROTO_UNKNOWN; request.toggle = 0; if (dec->scancode) diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h index 91a297731661..58b68dd6c67d 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.h +++ b/drivers/media/rc/img-ir/img-ir-hw.h @@ -135,13 +135,13 @@ struct img_ir_timing_regvals { /** * struct img_ir_scancode_req - Scancode request data. * @protocol: Protocol code of received message (defaults to - * RC_TYPE_UNKNOWN). + * RC_PROTO_UNKNOWN). * @scancode: Scan code of received message (must be written by * handler if IMG_IR_SCANCODE is returned). * @toggle: Toggle bit (defaults to 0). */ struct img_ir_scancode_req { - enum rc_type protocol; + enum rc_proto protocol; u32 scancode; u8 toggle; }; diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c b/drivers/media/rc/img-ir/img-ir-jvc.c index d3e2fc0bcfe1..4b07c76fbe1b 100644 --- a/drivers/media/rc/img-ir/img-ir-jvc.c +++ b/drivers/media/rc/img-ir/img-ir-jvc.c @@ -23,7 +23,7 @@ static int img_ir_jvc_scancode(int len, u64 raw, u64 enabled_protocols, cust = (raw >> 0) & 0xff; data = (raw >> 8) & 0xff; - request->protocol = RC_TYPE_JVC; + request->protocol = RC_PROTO_JVC; request->scancode = cust << 8 | data; return IMG_IR_SCANCODE; } @@ -52,7 +52,7 @@ static int img_ir_jvc_filter(const struct rc_scancode_filter *in, * http://support.jvc.com/consumer/support/documents/RemoteCodes.pdf */ struct img_ir_decoder img_ir_jvc = { - .type = RC_BIT_JVC, + .type = RC_PROTO_BIT_JVC, .control = { .decoden = 1, .code_type = IMG_IR_CODETYPE_PULSEDIST, diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c index 044fd42b22a0..2fc0678ad2d7 100644 --- a/drivers/media/rc/img-ir/img-ir-nec.c +++ b/drivers/media/rc/img-ir/img-ir-nec.c @@ -35,20 +35,20 @@ static int img_ir_nec_scancode(int len, u64 raw, u64 enabled_protocols, bitrev8(addr_inv) << 16 | bitrev8(data) << 8 | bitrev8(data_inv); - request->protocol = RC_TYPE_NEC32; + request->protocol = RC_PROTO_NEC32; } else if ((addr_inv ^ addr) != 0xff) { /* Extended NEC */ /* scan encoding: AAaaDD */ request->scancode = addr << 16 | addr_inv << 8 | data; - request->protocol = RC_TYPE_NECX; + request->protocol = RC_PROTO_NECX; } else { /* Normal NEC */ /* scan encoding: AADD */ request->scancode = addr << 8 | data; - request->protocol = RC_TYPE_NEC; + request->protocol = RC_PROTO_NEC; } return IMG_IR_SCANCODE; } @@ -63,7 +63,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in, data = in->data & 0xff; data_m = in->mask & 0xff; - protocols &= RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + protocols &= RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32; /* * If only one bit is set, we were requested to do an exact @@ -72,14 +72,14 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in, */ if (!is_power_of_2(protocols)) { if ((in->data | in->mask) & 0xff000000) - protocols = RC_BIT_NEC32; + protocols = RC_PROTO_BIT_NEC32; else if ((in->data | in->mask) & 0x00ff0000) - protocols = RC_BIT_NECX; + protocols = RC_PROTO_BIT_NECX; else - protocols = RC_BIT_NEC; + protocols = RC_PROTO_BIT_NEC; } - if (protocols == RC_BIT_NEC32) { + if (protocols == RC_PROTO_BIT_NEC32) { /* 32-bit NEC (used by Apple and TiVo remotes) */ /* scan encoding: as transmitted, MSBit = first received bit */ addr = bitrev8(in->data >> 24); @@ -90,7 +90,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in, data_m = bitrev8(in->mask >> 8); data_inv = bitrev8(in->data >> 0); data_inv_m = bitrev8(in->mask >> 0); - } else if (protocols == RC_BIT_NECX) { + } else if (protocols == RC_PROTO_BIT_NECX) { /* Extended NEC */ /* scan encoding AAaaDD */ addr = (in->data >> 16) & 0xff; @@ -128,7 +128,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in, * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol */ struct img_ir_decoder img_ir_nec = { - .type = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32, + .type = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32, .control = { .decoden = 1, .code_type = IMG_IR_CODETYPE_PULSEDIST, diff --git a/drivers/media/rc/img-ir/img-ir-rc5.c b/drivers/media/rc/img-ir/img-ir-rc5.c index a8a28a377eee..a1bc8705472b 100644 --- a/drivers/media/rc/img-ir/img-ir-rc5.c +++ b/drivers/media/rc/img-ir/img-ir-rc5.c @@ -33,7 +33,7 @@ static int img_ir_rc5_scancode(int len, u64 raw, u64 enabled_protocols, if (!start) return -EINVAL; - request->protocol = RC_TYPE_RC5; + request->protocol = RC_PROTO_RC5; request->scancode = addr << 8 | cmd; request->toggle = tgl; return IMG_IR_SCANCODE; @@ -52,7 +52,7 @@ static int img_ir_rc5_filter(const struct rc_scancode_filter *in, * see http://www.sbprojects.com/knowledge/ir/rc5.php */ struct img_ir_decoder img_ir_rc5 = { - .type = RC_BIT_RC5, + .type = RC_PROTO_BIT_RC5, .control = { .bitoriend2 = 1, .code_type = IMG_IR_CODETYPE_BIPHASE, diff --git a/drivers/media/rc/img-ir/img-ir-rc6.c b/drivers/media/rc/img-ir/img-ir-rc6.c index de1e27534968..5f34f59ca257 100644 --- a/drivers/media/rc/img-ir/img-ir-rc6.c +++ b/drivers/media/rc/img-ir/img-ir-rc6.c @@ -54,7 +54,7 @@ static int img_ir_rc6_scancode(int len, u64 raw, u64 enabled_protocols, if (mode) return -EINVAL; - request->protocol = RC_TYPE_RC6_0; + request->protocol = RC_PROTO_RC6_0; request->scancode = addr << 8 | cmd; request->toggle = trl2; return IMG_IR_SCANCODE; @@ -73,7 +73,7 @@ static int img_ir_rc6_filter(const struct rc_scancode_filter *in, * see http://www.sbprojects.com/knowledge/ir/rc6.php */ struct img_ir_decoder img_ir_rc6 = { - .type = RC_BIT_RC6_0, + .type = RC_PROTO_BIT_RC6_0, .control = { .bitorien = 1, .code_type = IMG_IR_CODETYPE_BIPHASE, diff --git a/drivers/media/rc/img-ir/img-ir-sanyo.c b/drivers/media/rc/img-ir/img-ir-sanyo.c index f394994ffc22..55a755bb437c 100644 --- a/drivers/media/rc/img-ir/img-ir-sanyo.c +++ b/drivers/media/rc/img-ir/img-ir-sanyo.c @@ -44,7 +44,7 @@ static int img_ir_sanyo_scancode(int len, u64 raw, u64 enabled_protocols, return -EINVAL; /* Normal Sanyo */ - request->protocol = RC_TYPE_SANYO; + request->protocol = RC_PROTO_SANYO; request->scancode = addr << 8 | data; return IMG_IR_SCANCODE; } @@ -80,7 +80,7 @@ static int img_ir_sanyo_filter(const struct rc_scancode_filter *in, /* Sanyo decoder */ struct img_ir_decoder img_ir_sanyo = { - .type = RC_BIT_SANYO, + .type = RC_PROTO_BIT_SANYO, .control = { .decoden = 1, .code_type = IMG_IR_CODETYPE_PULSEDIST, diff --git a/drivers/media/rc/img-ir/img-ir-sharp.c b/drivers/media/rc/img-ir/img-ir-sharp.c index fe5acc4f030e..2d2530902cfa 100644 --- a/drivers/media/rc/img-ir/img-ir-sharp.c +++ b/drivers/media/rc/img-ir/img-ir-sharp.c @@ -32,7 +32,7 @@ static int img_ir_sharp_scancode(int len, u64 raw, u64 enabled_protocols, /* probably the second half of the message */ return -EINVAL; - request->protocol = RC_TYPE_SHARP; + request->protocol = RC_PROTO_SHARP; request->scancode = addr << 8 | cmd; return IMG_IR_SCANCODE; } @@ -73,7 +73,7 @@ static int img_ir_sharp_filter(const struct rc_scancode_filter *in, * See also http://www.sbprojects.com/knowledge/ir/sharp.php */ struct img_ir_decoder img_ir_sharp = { - .type = RC_BIT_SHARP, + .type = RC_PROTO_BIT_SHARP, .control = { .decoden = 0, .decodend2 = 1, diff --git a/drivers/media/rc/img-ir/img-ir-sony.c b/drivers/media/rc/img-ir/img-ir-sony.c index 3fcba271a419..a942d0be908c 100644 --- a/drivers/media/rc/img-ir/img-ir-sony.c +++ b/drivers/media/rc/img-ir/img-ir-sony.c @@ -19,32 +19,32 @@ static int img_ir_sony_scancode(int len, u64 raw, u64 enabled_protocols, switch (len) { case 12: - if (!(enabled_protocols & RC_BIT_SONY12)) + if (!(enabled_protocols & RC_PROTO_BIT_SONY12)) return -EINVAL; func = raw & 0x7f; /* first 7 bits */ raw >>= 7; dev = raw & 0x1f; /* next 5 bits */ subdev = 0; - request->protocol = RC_TYPE_SONY12; + request->protocol = RC_PROTO_SONY12; break; case 15: - if (!(enabled_protocols & RC_BIT_SONY15)) + if (!(enabled_protocols & RC_PROTO_BIT_SONY15)) return -EINVAL; func = raw & 0x7f; /* first 7 bits */ raw >>= 7; dev = raw & 0xff; /* next 8 bits */ subdev = 0; - request->protocol = RC_TYPE_SONY15; + request->protocol = RC_PROTO_SONY15; break; case 20: - if (!(enabled_protocols & RC_BIT_SONY20)) + if (!(enabled_protocols & RC_PROTO_BIT_SONY20)) return -EINVAL; func = raw & 0x7f; /* first 7 bits */ raw >>= 7; dev = raw & 0x1f; /* next 5 bits */ raw >>= 5; subdev = raw & 0xff; /* next 8 bits */ - request->protocol = RC_TYPE_SONY20; + request->protocol = RC_PROTO_SONY20; break; default: return -EINVAL; @@ -68,7 +68,8 @@ static int img_ir_sony_filter(const struct rc_scancode_filter *in, func = (in->data >> 0) & 0x7f; func_m = (in->mask >> 0) & 0x7f; - protocols &= RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20; + protocols &= RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | + RC_PROTO_BIT_SONY20; /* * If only one bit is set, we were requested to do an exact @@ -77,20 +78,20 @@ static int img_ir_sony_filter(const struct rc_scancode_filter *in, */ if (!is_power_of_2(protocols)) { if (subdev & subdev_m) - protocols = RC_BIT_SONY20; + protocols = RC_PROTO_BIT_SONY20; else if (dev & dev_m & 0xe0) - protocols = RC_BIT_SONY15; + protocols = RC_PROTO_BIT_SONY15; else - protocols = RC_BIT_SONY12; + protocols = RC_PROTO_BIT_SONY12; } - if (protocols == RC_BIT_SONY20) { + if (protocols == RC_PROTO_BIT_SONY20) { /* can't encode subdev and higher device bits */ if (dev & dev_m & 0xe0) return -EINVAL; len = 20; dev_m &= 0x1f; - } else if (protocols == RC_BIT_SONY15) { + } else if (protocols == RC_PROTO_BIT_SONY15) { len = 15; subdev_m = 0; } else { @@ -128,7 +129,7 @@ static int img_ir_sony_filter(const struct rc_scancode_filter *in, * http://picprojects.org.uk/projects/sirc/sonysirc.pdf */ struct img_ir_decoder img_ir_sony = { - .type = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20, + .type = RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | RC_PROTO_BIT_SONY20, .control = { .decoden = 1, .code_type = IMG_IR_CODETYPE_PULSELEN, diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index ab560fdaae7c..7b3f31cc63d2 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -148,7 +148,7 @@ struct imon_context { u32 last_keycode; /* last reported input keycode */ u32 rc_scancode; /* the computed remote scancode */ u8 rc_toggle; /* the computed remote toggle bit */ - u64 rc_type; /* iMON or MCE (RC6) IR protocol? */ + u64 rc_proto; /* iMON or MCE (RC6) IR protocol? */ bool release_code; /* some keys send a release code */ u8 display_type; /* store the display type */ @@ -1118,7 +1118,7 @@ static void imon_touch_display_timeout(unsigned long data) * it is not, so we must acquire it prior to calling send_packet, which * requires that the lock is held. */ -static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) +static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) { int retval; struct imon_context *ictx = rc->priv; @@ -1127,25 +1127,25 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - if (*rc_type && !(*rc_type & rc->allowed_protocols)) + if (*rc_proto && !(*rc_proto & rc->allowed_protocols)) dev_warn(dev, "Looks like you're trying to use an IR protocol this device does not support\n"); - if (*rc_type & RC_BIT_RC6_MCE) { + if (*rc_proto & RC_PROTO_BIT_RC6_MCE) { dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); ir_proto_packet[0] = 0x01; - *rc_type = RC_BIT_RC6_MCE; - } else if (*rc_type & RC_BIT_OTHER) { + *rc_proto = RC_PROTO_BIT_RC6_MCE; + } else if (*rc_proto & RC_PROTO_BIT_OTHER) { dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); if (!pad_stabilize) dev_dbg(dev, "PAD stabilize functionality disabled\n"); /* ir_proto_packet[0] = 0x00; // already the default */ - *rc_type = RC_BIT_OTHER; + *rc_proto = RC_PROTO_BIT_OTHER; } else { dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); if (!pad_stabilize) dev_dbg(dev, "PAD stabilize functionality disabled\n"); /* ir_proto_packet[0] = 0x00; // already the default */ - *rc_type = RC_BIT_OTHER; + *rc_proto = RC_PROTO_BIT_OTHER; } memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); @@ -1159,7 +1159,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) if (retval) goto out; - ictx->rc_type = *rc_type; + ictx->rc_proto = *rc_proto; ictx->pad_mouse = false; out: @@ -1435,7 +1435,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) rel_x = buf[2]; rel_y = buf[3]; - if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) { + if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { dir = stabilize((int)rel_x, (int)rel_y, timeout, threshold); @@ -1502,7 +1502,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) buf[0] = 0x01; buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; - if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) { + if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { dir = stabilize((int)rel_x, (int)rel_y, timeout, threshold); if (!dir) { @@ -1706,7 +1706,7 @@ static void imon_incoming_scancode(struct imon_context *ictx, ictx->release_code = false; } else { scancode = be32_to_cpu(*((__be32 *)buf)); - if (ictx->rc_type == RC_BIT_RC6_MCE) { + if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) { ktype = IMON_KEY_IMON; if (buf[0] == 0x80) ktype = IMON_KEY_MCE; @@ -1769,10 +1769,10 @@ static void imon_incoming_scancode(struct imon_context *ictx, if (press_type == 0) rc_keyup(ictx->rdev); else { - if (ictx->rc_type == RC_BIT_RC6_MCE || - ictx->rc_type == RC_BIT_OTHER) + if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || + ictx->rc_proto == RC_PROTO_BIT_OTHER) rc_keydown(ictx->rdev, - ictx->rc_type == RC_BIT_RC6_MCE ? RC_TYPE_RC6_MCE : RC_TYPE_OTHER, + ictx->rc_proto == RC_PROTO_BIT_RC6_MCE ? RC_PROTO_RC6_MCE : RC_PROTO_OTHER, ictx->rc_scancode, ictx->rc_toggle); spin_lock_irqsave(&ictx->kc_lock, flags); ictx->last_keycode = ictx->kc; @@ -1936,7 +1936,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) { u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; - u64 allowed_protos = RC_BIT_OTHER; + u64 allowed_protos = RC_PROTO_BIT_OTHER; switch (ffdc_cfg_byte) { /* iMON Knob, no display, iMON IR + vol knob */ @@ -1967,27 +1967,27 @@ static void imon_get_ffdc_type(struct imon_context *ictx) case 0x9e: dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); detected_display_type = IMON_DISPLAY_TYPE_VFD; - allowed_protos = RC_BIT_RC6_MCE; + allowed_protos = RC_PROTO_BIT_RC6_MCE; break; /* iMON LCD, MCE IR */ case 0x9f: dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR"); detected_display_type = IMON_DISPLAY_TYPE_LCD; - allowed_protos = RC_BIT_RC6_MCE; + allowed_protos = RC_PROTO_BIT_RC6_MCE; break; default: dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); detected_display_type = IMON_DISPLAY_TYPE_VFD; /* We don't know which one it is, allow user to set the * RC6 one from userspace if OTHER wasn't correct. */ - allowed_protos |= RC_BIT_RC6_MCE; + allowed_protos |= RC_PROTO_BIT_RC6_MCE; break; } printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); ictx->display_type = detected_display_type; - ictx->rc_type = allowed_protos; + ictx->rc_proto = allowed_protos; } static void imon_set_display_type(struct imon_context *ictx) @@ -2070,10 +2070,11 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) rdev->priv = ictx; if (ictx->dev_descr->flags & IMON_IR_RAW) - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; else /* iMON PAD or MCE */ - rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; + rdev->allowed_protocols = RC_PROTO_BIT_OTHER | + RC_PROTO_BIT_RC6_MCE; rdev->change_protocol = imon_ir_change_protocol; rdev->driver_name = MOD_NAME; @@ -2086,12 +2087,12 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) if (ictx->product == 0xffdc) { imon_get_ffdc_type(ictx); - rdev->allowed_protocols = ictx->rc_type; + rdev->allowed_protocols = ictx->rc_proto; } imon_set_display_type(ictx); - if (ictx->rc_type == RC_BIT_RC6_MCE || + if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || ictx->dev_descr->flags & IMON_IR_RAW) rdev->map_name = RC_MAP_IMON_MCE; else diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 0e639fb6f7b9..0ce11c41dfae 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -242,7 +242,7 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) clk_prepare_enable(priv->clock); priv->rate = clk_get_rate(priv->clock); - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->priv = priv; rdev->open = hix5hd2_ir_open; rdev->close = hix5hd2_ir_close; diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 674bf156edcb..e2bd68c42edf 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -137,7 +137,7 @@ again: scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | (bitrev8((data->bits >> 0) & 0xff) << 0); IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); - rc_keydown(dev, RC_TYPE_JVC, scancode, data->toggle); + rc_keydown(dev, RC_PROTO_JVC, scancode, data->toggle); data->first = false; data->old_bits = data->bits; } else if (data->bits == data->old_bits) { @@ -193,7 +193,7 @@ static const struct ir_raw_timings_pd ir_jvc_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_jvc_encode(enum rc_type protocol, u32 scancode, +static int ir_jvc_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; @@ -209,7 +209,7 @@ static int ir_jvc_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler jvc_handler = { - .protocols = RC_BIT_JVC, + .protocols = RC_PROTO_BIT_JVC, .decode = ir_jvc_decode, .encode = ir_jvc_encode, }; diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 5de14ae77421..7c572a643656 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -444,14 +444,14 @@ static const struct ir_raw_timings_manchester ir_mce_kbd_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_mce_kbd_encode(enum rc_type protocol, u32 scancode, +static int ir_mce_kbd_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; int len, ret; u64 raw; - if (protocol == RC_TYPE_MCIR2_KBD) { + if (protocol == RC_PROTO_MCIR2_KBD) { raw = scancode | ((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS); len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1; @@ -469,7 +469,7 @@ static int ir_mce_kbd_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler mce_kbd_handler = { - .protocols = RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE, + .protocols = RC_PROTO_BIT_MCIR2_KBD | RC_PROTO_BIT_MCIR2_MSE, .decode = ir_mce_kbd_decode, .encode = ir_mce_kbd_encode, .raw_register = ir_mce_kbd_register, diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 23d2bc8c190d..817c18f2ddd1 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -49,7 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct nec_dec *data = &dev->raw->nec; u32 scancode; - enum rc_type rc_type; + enum rc_proto rc_proto; u8 address, not_address, command, not_command; if (!is_timing_event(ev)) { @@ -158,12 +158,12 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) scancode = ir_nec_bytes_to_scancode(address, not_address, command, not_command, - &rc_type); + &rc_proto); if (data->is_nec_x) data->necx_repeat = true; - rc_keydown(dev, rc_type, scancode, 0); + rc_keydown(dev, rc_proto, scancode, 0); data->state = STATE_INACTIVE; return 0; } @@ -180,19 +180,19 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) * @scancode: a single NEC scancode. * @raw: raw data to be modulated. */ -static u32 ir_nec_scancode_to_raw(enum rc_type protocol, u32 scancode) +static u32 ir_nec_scancode_to_raw(enum rc_proto protocol, u32 scancode) { unsigned int addr, addr_inv, data, data_inv; data = scancode & 0xff; - if (protocol == RC_TYPE_NEC32) { + if (protocol == RC_PROTO_NEC32) { /* 32-bit NEC (used by Apple and TiVo remotes) */ /* scan encoding: aaAAddDD */ addr_inv = (scancode >> 24) & 0xff; addr = (scancode >> 16) & 0xff; data_inv = (scancode >> 8) & 0xff; - } else if (protocol == RC_TYPE_NECX) { + } else if (protocol == RC_PROTO_NECX) { /* Extended NEC */ /* scan encoding AAaaDD */ addr = (scancode >> 16) & 0xff; @@ -236,7 +236,7 @@ static const struct ir_raw_timings_pd ir_nec_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_nec_encode(enum rc_type protocol, u32 scancode, +static int ir_nec_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; @@ -255,7 +255,8 @@ static int ir_nec_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler nec_handler = { - .protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32, + .protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32, .decode = ir_nec_decode, .encode = ir_nec_encode, }; diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index fcfedf95def7..1292f534de43 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -51,7 +51,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) struct rc5_dec *data = &dev->raw->rc5; u8 toggle; u32 scancode; - enum rc_type protocol; + enum rc_proto protocol; if (!is_timing_event(ev)) { if (ev.reset) @@ -124,7 +124,7 @@ again: if (data->is_rc5x && data->count == RC5X_NBITS) { /* RC5X */ u8 xdata, command, system; - if (!(dev->enabled_protocols & RC_BIT_RC5X_20)) { + if (!(dev->enabled_protocols & RC_PROTO_BIT_RC5X_20)) { data->state = STATE_INACTIVE; return 0; } @@ -134,12 +134,12 @@ again: toggle = (data->bits & 0x20000) ? 1 : 0; command += (data->bits & 0x40000) ? 0 : 0x40; scancode = system << 16 | command << 8 | xdata; - protocol = RC_TYPE_RC5X_20; + protocol = RC_PROTO_RC5X_20; } else if (!data->is_rc5x && data->count == RC5_NBITS) { /* RC5 */ u8 command, system; - if (!(dev->enabled_protocols & RC_BIT_RC5)) { + if (!(dev->enabled_protocols & RC_PROTO_BIT_RC5)) { data->state = STATE_INACTIVE; return 0; } @@ -148,12 +148,12 @@ again: toggle = (data->bits & 0x00800) ? 1 : 0; command += (data->bits & 0x01000) ? 0 : 0x40; scancode = system << 8 | command; - protocol = RC_TYPE_RC5; + protocol = RC_PROTO_RC5; } else if (!data->is_rc5x && data->count == RC5_SZ_NBITS) { /* RC5 StreamZap */ u8 command, system; - if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) { + if (!(dev->enabled_protocols & RC_PROTO_BIT_RC5_SZ)) { data->state = STATE_INACTIVE; return 0; } @@ -161,7 +161,7 @@ again: system = (data->bits & 0x02FC0) >> 6; toggle = (data->bits & 0x01000) ? 1 : 0; scancode = system << 6 | command; - protocol = RC_TYPE_RC5_SZ; + protocol = RC_PROTO_RC5_SZ; } else break; @@ -221,7 +221,7 @@ static const struct ir_raw_timings_manchester ir_rc5_sz_timings = { * encoding. In this case all @max events will have been written. * -EINVAL if the scancode is ambiguous or invalid. */ -static int ir_rc5_encode(enum rc_type protocol, u32 scancode, +static int ir_rc5_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { int ret; @@ -229,7 +229,7 @@ static int ir_rc5_encode(enum rc_type protocol, u32 scancode, unsigned int data, xdata, command, commandx, system, pre_space_data; /* Detect protocol and convert scancode to raw data */ - if (protocol == RC_TYPE_RC5) { + if (protocol == RC_PROTO_RC5) { /* decode scancode */ command = (scancode & 0x003f) >> 0; commandx = (scancode & 0x0040) >> 6; @@ -242,7 +242,7 @@ static int ir_rc5_encode(enum rc_type protocol, u32 scancode, RC5_NBITS, data); if (ret < 0) return ret; - } else if (protocol == RC_TYPE_RC5X_20) { + } else if (protocol == RC_PROTO_RC5X_20) { /* decode scancode */ xdata = (scancode & 0x00003f) >> 0; command = (scancode & 0x003f00) >> 8; @@ -264,7 +264,7 @@ static int ir_rc5_encode(enum rc_type protocol, u32 scancode, data); if (ret < 0) return ret; - } else if (protocol == RC_TYPE_RC5_SZ) { + } else if (protocol == RC_PROTO_RC5_SZ) { /* RC5-SZ scancode is raw enough for Manchester as it is */ ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings, RC5_SZ_NBITS, scancode & 0x2fff); @@ -278,7 +278,8 @@ static int ir_rc5_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler rc5_handler = { - .protocols = RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ, + .protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | + RC_PROTO_BIT_RC5_SZ, .decode = ir_rc5_decode, .encode = ir_rc5_encode, }; diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 6fe2268dada0..5d0d2fe3b7a7 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -88,7 +88,7 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) struct rc6_dec *data = &dev->raw->rc6; u32 scancode; u8 toggle; - enum rc_type protocol; + enum rc_proto protocol; if (!is_timing_event(ev)) { if (ev.reset) @@ -229,7 +229,7 @@ again: case RC6_MODE_0: scancode = data->body; toggle = data->toggle; - protocol = RC_TYPE_RC6_0; + protocol = RC_PROTO_RC6_0; IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", scancode, toggle); break; @@ -244,20 +244,20 @@ again: scancode = data->body; switch (data->count) { case 20: - protocol = RC_TYPE_RC6_6A_20; + protocol = RC_PROTO_RC6_6A_20; toggle = 0; break; case 24: - protocol = RC_TYPE_RC6_6A_24; + protocol = RC_PROTO_RC6_6A_24; toggle = 0; break; case 32: if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { - protocol = RC_TYPE_RC6_MCE; + protocol = RC_PROTO_RC6_MCE; toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK); scancode &= ~RC6_6A_MCE_TOGGLE_MASK; } else { - protocol = RC_TYPE_RC6_6A_32; + protocol = RC_PROTO_RC6_6A_32; toggle = 0; } break; @@ -322,13 +322,13 @@ static const struct ir_raw_timings_manchester ir_rc6_timings[4] = { * encoding. In this case all @max events will have been written. * -EINVAL if the scancode is ambiguous or invalid. */ -static int ir_rc6_encode(enum rc_type protocol, u32 scancode, +static int ir_rc6_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { int ret; struct ir_raw_event *e = events; - if (protocol == RC_TYPE_RC6_0) { + if (protocol == RC_PROTO_RC6_0) { /* Modulate the preamble */ ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); if (ret < 0) @@ -358,14 +358,14 @@ static int ir_rc6_encode(enum rc_type protocol, u32 scancode, int bits; switch (protocol) { - case RC_TYPE_RC6_MCE: - case RC_TYPE_RC6_6A_32: + case RC_PROTO_RC6_MCE: + case RC_PROTO_RC6_6A_32: bits = 32; break; - case RC_TYPE_RC6_6A_24: + case RC_PROTO_RC6_6A_24: bits = 24; break; - case RC_TYPE_RC6_6A_20: + case RC_PROTO_RC6_6A_20: bits = 20; break; default: @@ -403,9 +403,9 @@ static int ir_rc6_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler rc6_handler = { - .protocols = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | - RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | - RC_BIT_RC6_MCE, + .protocols = RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | + RC_PROTO_BIT_RC6_MCE, .decode = ir_rc6_decode, .encode = ir_rc6_encode, }; diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index e6a906a34f90..758c60956850 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -161,7 +161,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) scancode = address << 8 | command; IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); - rc_keydown(dev, RC_TYPE_SANYO, scancode, 0); + rc_keydown(dev, RC_PROTO_SANYO, scancode, 0); data->state = STATE_INACTIVE; return 0; } @@ -195,7 +195,7 @@ static const struct ir_raw_timings_pd ir_sanyo_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_sanyo_encode(enum rc_type protocol, u32 scancode, +static int ir_sanyo_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; @@ -215,7 +215,7 @@ static int ir_sanyo_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler sanyo_handler = { - .protocols = RC_BIT_SANYO, + .protocols = RC_PROTO_BIT_SANYO, .decode = ir_sanyo_decode, .encode = ir_sanyo_encode, }; diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index b47e89e2c1bd..ed43a4212479 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -161,7 +161,7 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) scancode = address << 8 | command; IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode); - rc_keydown(dev, RC_TYPE_SHARP, scancode, 0); + rc_keydown(dev, RC_PROTO_SHARP, scancode, 0); data->state = STATE_INACTIVE; return 0; } @@ -196,7 +196,7 @@ static const struct ir_raw_timings_pd ir_sharp_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_sharp_encode(enum rc_type protocol, u32 scancode, +static int ir_sharp_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; @@ -223,7 +223,7 @@ static int ir_sharp_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler sharp_handler = { - .protocols = RC_BIT_SHARP, + .protocols = RC_PROTO_BIT_SHARP, .decode = ir_sharp_decode, .encode = ir_sharp_encode, }; diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 355fa8198f5a..a47ced763031 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -42,7 +42,7 @@ enum sony_state { static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct sony_dec *data = &dev->raw->sony; - enum rc_type protocol; + enum rc_proto protocol; u32 scancode; u8 device, subdevice, function; @@ -121,31 +121,31 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) switch (data->count) { case 12: - if (!(dev->enabled_protocols & RC_BIT_SONY12)) + if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY12)) goto finish_state_machine; device = bitrev8((data->bits << 3) & 0xF8); subdevice = 0; function = bitrev8((data->bits >> 4) & 0xFE); - protocol = RC_TYPE_SONY12; + protocol = RC_PROTO_SONY12; break; case 15: - if (!(dev->enabled_protocols & RC_BIT_SONY15)) + if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY15)) goto finish_state_machine; device = bitrev8((data->bits >> 0) & 0xFF); subdevice = 0; function = bitrev8((data->bits >> 7) & 0xFE); - protocol = RC_TYPE_SONY15; + protocol = RC_PROTO_SONY15; break; case 20: - if (!(dev->enabled_protocols & RC_BIT_SONY20)) + if (!(dev->enabled_protocols & RC_PROTO_BIT_SONY20)) goto finish_state_machine; device = bitrev8((data->bits >> 5) & 0xF8); subdevice = bitrev8((data->bits >> 0) & 0xFF); function = bitrev8((data->bits >> 12) & 0xFE); - protocol = RC_TYPE_SONY20; + protocol = RC_PROTO_SONY20; break; default: IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); @@ -190,17 +190,17 @@ static const struct ir_raw_timings_pl ir_sony_timings = { * -ENOBUFS if there isn't enough space in the array to fit the * encoding. In this case all @max events will have been written. */ -static int ir_sony_encode(enum rc_type protocol, u32 scancode, +static int ir_sony_encode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_event *e = events; u32 raw, len; int ret; - if (protocol == RC_TYPE_SONY12) { + if (protocol == RC_PROTO_SONY12) { raw = (scancode & 0x7f) | ((scancode & 0x1f0000) >> 9); len = 12; - } else if (protocol == RC_TYPE_SONY15) { + } else if (protocol == RC_PROTO_SONY15) { raw = (scancode & 0x7f) | ((scancode & 0xff0000) >> 9); len = 15; } else { @@ -217,7 +217,8 @@ static int ir_sony_encode(enum rc_type protocol, u32 scancode, } static struct ir_raw_handler sony_handler = { - .protocols = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20, + .protocols = RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | + RC_PROTO_BIT_SONY20, .decode = ir_sony_decode, .encode = ir_sony_encode, }; diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c index 18596190bbb8..6f464be1c8d7 100644 --- a/drivers/media/rc/ir-xmp-decoder.c +++ b/drivers/media/rc/ir-xmp-decoder.c @@ -141,7 +141,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) IR_dprintk(1, "XMP scancode 0x%06x\n", scancode); if (toggle == 0) { - rc_keydown(dev, RC_TYPE_XMP, scancode, 0); + rc_keydown(dev, RC_PROTO_XMP, scancode, 0); } else { rc_repeat(dev); IR_dprintk(1, "Repeat last key\n"); @@ -196,7 +196,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) } static struct ir_raw_handler xmp_handler = { - .protocols = RC_BIT_XMP, + .protocols = RC_PROTO_BIT_XMP, .decode = ir_xmp_decode, }; diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index c8eea30b4e50..65e104c7ddfc 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1556,7 +1556,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id /* set up ir-core props */ rdev->priv = itdev; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->open = ite_open; rdev->close = ite_close; rdev->s_idle = ite_s_idle; diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c index 01d901fbfc8b..2d303c2cee3b 100644 --- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c +++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c @@ -66,10 +66,10 @@ static struct rc_map_table adstech_dvb_t_pci[] = { static struct rc_map_list adstech_dvb_t_pci_map = { .map = { - .scan = adstech_dvb_t_pci, - .size = ARRAY_SIZE(adstech_dvb_t_pci), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_ADSTECH_DVB_T_PCI, + .scan = adstech_dvb_t_pci, + .size = ARRAY_SIZE(adstech_dvb_t_pci), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ADSTECH_DVB_T_PCI, } }; diff --git a/drivers/media/rc/keymaps/rc-alink-dtu-m.c b/drivers/media/rc/keymaps/rc-alink-dtu-m.c index 4e6ade8e616f..3818c33734a1 100644 --- a/drivers/media/rc/keymaps/rc-alink-dtu-m.c +++ b/drivers/media/rc/keymaps/rc-alink-dtu-m.c @@ -45,10 +45,10 @@ static struct rc_map_table alink_dtu_m[] = { static struct rc_map_list alink_dtu_m_map = { .map = { - .scan = alink_dtu_m, - .size = ARRAY_SIZE(alink_dtu_m), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_ALINK_DTU_M, + .scan = alink_dtu_m, + .size = ARRAY_SIZE(alink_dtu_m), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_ALINK_DTU_M, } }; diff --git a/drivers/media/rc/keymaps/rc-anysee.c b/drivers/media/rc/keymaps/rc-anysee.c index c735fe10a390..e75e51b34d29 100644 --- a/drivers/media/rc/keymaps/rc-anysee.c +++ b/drivers/media/rc/keymaps/rc-anysee.c @@ -70,10 +70,10 @@ static struct rc_map_table anysee[] = { static struct rc_map_list anysee_map = { .map = { - .scan = anysee, - .size = ARRAY_SIZE(anysee), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_ANYSEE, + .scan = anysee, + .size = ARRAY_SIZE(anysee), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_ANYSEE, } }; diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c index bf9efa007e1c..65bc8957d9c3 100644 --- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c +++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c @@ -57,10 +57,10 @@ static struct rc_map_table apac_viewcomp[] = { static struct rc_map_list apac_viewcomp_map = { .map = { - .scan = apac_viewcomp, - .size = ARRAY_SIZE(apac_viewcomp), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_APAC_VIEWCOMP, + .scan = apac_viewcomp, + .size = ARRAY_SIZE(apac_viewcomp), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_APAC_VIEWCOMP, } }; diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c index 9e674ba5dd4f..530e1d1158d1 100644 --- a/drivers/media/rc/keymaps/rc-asus-pc39.c +++ b/drivers/media/rc/keymaps/rc-asus-pc39.c @@ -68,10 +68,10 @@ static struct rc_map_table asus_pc39[] = { static struct rc_map_list asus_pc39_map = { .map = { - .scan = asus_pc39, - .size = ARRAY_SIZE(asus_pc39), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_ASUS_PC39, + .scan = asus_pc39, + .size = ARRAY_SIZE(asus_pc39), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_ASUS_PC39, } }; diff --git a/drivers/media/rc/keymaps/rc-asus-ps3-100.c b/drivers/media/rc/keymaps/rc-asus-ps3-100.c index e45de35f528f..c91ba332984c 100644 --- a/drivers/media/rc/keymaps/rc-asus-ps3-100.c +++ b/drivers/media/rc/keymaps/rc-asus-ps3-100.c @@ -67,10 +67,10 @@ static struct rc_map_table asus_ps3_100[] = { static struct rc_map_list asus_ps3_100_map = { .map = { - .scan = asus_ps3_100, - .size = ARRAY_SIZE(asus_ps3_100), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_ASUS_PS3_100, + .scan = asus_ps3_100, + .size = ARRAY_SIZE(asus_ps3_100), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_ASUS_PS3_100, } }; diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c index 91392d4cfd6d..11b4bdd2392b 100644 --- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c +++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c @@ -46,10 +46,10 @@ static struct rc_map_table ati_tv_wonder_hd_600[] = { static struct rc_map_list ati_tv_wonder_hd_600_map = { .map = { - .scan = ati_tv_wonder_hd_600, - .size = ARRAY_SIZE(ati_tv_wonder_hd_600), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_ATI_TV_WONDER_HD_600, + .scan = ati_tv_wonder_hd_600, + .size = ARRAY_SIZE(ati_tv_wonder_hd_600), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ATI_TV_WONDER_HD_600, } }; diff --git a/drivers/media/rc/keymaps/rc-ati-x10.c b/drivers/media/rc/keymaps/rc-ati-x10.c index 4bdc709ec54d..11f1eb6ad712 100644 --- a/drivers/media/rc/keymaps/rc-ati-x10.c +++ b/drivers/media/rc/keymaps/rc-ati-x10.c @@ -114,10 +114,10 @@ static struct rc_map_table ati_x10[] = { static struct rc_map_list ati_x10_map = { .map = { - .scan = ati_x10, - .size = ARRAY_SIZE(ati_x10), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_ATI_X10, + .scan = ati_x10, + .size = ARRAY_SIZE(ati_x10), + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_ATI_X10, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c index ff30a71d623e..510dc90ebf49 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c +++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c @@ -52,10 +52,10 @@ static struct rc_map_table avermedia_a16d[] = { static struct rc_map_list avermedia_a16d_map = { .map = { - .scan = avermedia_a16d, - .size = ARRAY_SIZE(avermedia_a16d), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_AVERMEDIA_A16D, + .scan = avermedia_a16d, + .size = ARRAY_SIZE(avermedia_a16d), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_A16D, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c index d7471a6de9b4..4bbc1e68d1b8 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c +++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c @@ -74,10 +74,10 @@ static struct rc_map_table avermedia_cardbus[] = { static struct rc_map_list avermedia_cardbus_map = { .map = { - .scan = avermedia_cardbus, - .size = ARRAY_SIZE(avermedia_cardbus), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_AVERMEDIA_CARDBUS, + .scan = avermedia_cardbus, + .size = ARRAY_SIZE(avermedia_cardbus), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_CARDBUS, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c index e2417d6331fe..f6b8547dbad3 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c +++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c @@ -55,10 +55,10 @@ static struct rc_map_table avermedia_dvbt[] = { static struct rc_map_list avermedia_dvbt_map = { .map = { - .scan = avermedia_dvbt, - .size = ARRAY_SIZE(avermedia_dvbt), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_AVERMEDIA_DVBT, + .scan = avermedia_dvbt, + .size = ARRAY_SIZE(avermedia_dvbt), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA_DVBT, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index 843598a5f1b5..9882e2cde975 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -124,10 +124,10 @@ static struct rc_map_table avermedia_m135a[] = { static struct rc_map_list avermedia_m135a_map = { .map = { - .scan = avermedia_m135a, - .size = ARRAY_SIZE(avermedia_m135a), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_AVERMEDIA_M135A, + .scan = avermedia_m135a, + .size = ARRAY_SIZE(avermedia_m135a), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_AVERMEDIA_M135A, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c index b24e7481ac21..d86126e10375 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c @@ -72,10 +72,10 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = { static struct rc_map_list avermedia_m733a_rm_k6_map = { .map = { - .scan = avermedia_m733a_rm_k6, - .size = ARRAY_SIZE(avermedia_m733a_rm_k6), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_AVERMEDIA_M733A_RM_K6, + .scan = avermedia_m733a_rm_k6, + .size = ARRAY_SIZE(avermedia_m733a_rm_k6), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_AVERMEDIA_M733A_RM_K6, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c index 2583400ca1b4..5d92d36d9174 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c +++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c @@ -56,10 +56,10 @@ static struct rc_map_table avermedia_rm_ks[] = { static struct rc_map_list avermedia_rm_ks_map = { .map = { - .scan = avermedia_rm_ks, - .size = ARRAY_SIZE(avermedia_rm_ks), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_AVERMEDIA_RM_KS, + .scan = avermedia_rm_ks, + .size = ARRAY_SIZE(avermedia_rm_ks), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_AVERMEDIA_RM_KS, } }; diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c index 3f68fbecc188..6503f11c7df5 100644 --- a/drivers/media/rc/keymaps/rc-avermedia.c +++ b/drivers/media/rc/keymaps/rc-avermedia.c @@ -63,10 +63,10 @@ static struct rc_map_table avermedia[] = { static struct rc_map_list avermedia_map = { .map = { - .scan = avermedia, - .size = ARRAY_SIZE(avermedia), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_AVERMEDIA, + .scan = avermedia, + .size = ARRAY_SIZE(avermedia), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERMEDIA, } }; diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c index c35bc5b835c4..fbdd7ada57ce 100644 --- a/drivers/media/rc/keymaps/rc-avertv-303.c +++ b/drivers/media/rc/keymaps/rc-avertv-303.c @@ -62,10 +62,10 @@ static struct rc_map_table avertv_303[] = { static struct rc_map_list avertv_303_map = { .map = { - .scan = avertv_303, - .size = ARRAY_SIZE(avertv_303), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_AVERTV_303, + .scan = avertv_303, + .size = ARRAY_SIZE(avertv_303), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_AVERTV_303, } }; diff --git a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c index ea7f2d0f31eb..18d7dcb869b0 100644 --- a/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c +++ b/drivers/media/rc/keymaps/rc-azurewave-ad-tu700.c @@ -79,10 +79,10 @@ static struct rc_map_table azurewave_ad_tu700[] = { static struct rc_map_list azurewave_ad_tu700_map = { .map = { - .scan = azurewave_ad_tu700, - .size = ARRAY_SIZE(azurewave_ad_tu700), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_AZUREWAVE_AD_TU700, + .scan = azurewave_ad_tu700, + .size = ARRAY_SIZE(azurewave_ad_tu700), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_AZUREWAVE_AD_TU700, } }; diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 1fc344e9daa7..d256743be998 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -85,10 +85,10 @@ static struct rc_map_table behold_columbus[] = { static struct rc_map_list behold_columbus_map = { .map = { - .scan = behold_columbus, - .size = ARRAY_SIZE(behold_columbus), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_BEHOLD_COLUMBUS, + .scan = behold_columbus, + .size = ARRAY_SIZE(behold_columbus), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_BEHOLD_COLUMBUS, } }; diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c index 520a96f2ff86..93dc795adc67 100644 --- a/drivers/media/rc/keymaps/rc-behold.c +++ b/drivers/media/rc/keymaps/rc-behold.c @@ -118,10 +118,10 @@ static struct rc_map_table behold[] = { static struct rc_map_list behold_map = { .map = { - .scan = behold, - .size = ARRAY_SIZE(behold), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_BEHOLD, + .scan = behold, + .size = ARRAY_SIZE(behold), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_BEHOLD, } }; diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c index b196a5f436a3..81ea1424d9e5 100644 --- a/drivers/media/rc/keymaps/rc-budget-ci-old.c +++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c @@ -70,10 +70,10 @@ static struct rc_map_table budget_ci_old[] = { static struct rc_map_list budget_ci_old_map = { .map = { - .scan = budget_ci_old, - .size = ARRAY_SIZE(budget_ci_old), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_BUDGET_CI_OLD, + .scan = budget_ci_old, + .size = ARRAY_SIZE(budget_ci_old), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_BUDGET_CI_OLD, } }; diff --git a/drivers/media/rc/keymaps/rc-cec.c b/drivers/media/rc/keymaps/rc-cec.c index 354c8e724b8e..76d34abb7c85 100644 --- a/drivers/media/rc/keymaps/rc-cec.c +++ b/drivers/media/rc/keymaps/rc-cec.c @@ -160,7 +160,7 @@ static struct rc_map_list cec_map = { .map = { .scan = cec, .size = ARRAY_SIZE(cec), - .rc_type = RC_TYPE_CEC, + .rc_proto = RC_PROTO_CEC, .name = RC_MAP_CEC, } }; diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c index a099c080bf8c..bcb96b3dda85 100644 --- a/drivers/media/rc/keymaps/rc-cinergy-1400.c +++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c @@ -61,10 +61,10 @@ static struct rc_map_table cinergy_1400[] = { static struct rc_map_list cinergy_1400_map = { .map = { - .scan = cinergy_1400, - .size = ARRAY_SIZE(cinergy_1400), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_CINERGY_1400, + .scan = cinergy_1400, + .size = ARRAY_SIZE(cinergy_1400), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_CINERGY_1400, } }; diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c index b0f4328bdd6f..fd56c402aae5 100644 --- a/drivers/media/rc/keymaps/rc-cinergy.c +++ b/drivers/media/rc/keymaps/rc-cinergy.c @@ -55,10 +55,10 @@ static struct rc_map_table cinergy[] = { static struct rc_map_list cinergy_map = { .map = { - .scan = cinergy, - .size = ARRAY_SIZE(cinergy), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_CINERGY, + .scan = cinergy, + .size = ARRAY_SIZE(cinergy), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_CINERGY, } }; diff --git a/drivers/media/rc/keymaps/rc-d680-dmb.c b/drivers/media/rc/keymaps/rc-d680-dmb.c index bb5745d29d8a..2c94b9d88b67 100644 --- a/drivers/media/rc/keymaps/rc-d680-dmb.c +++ b/drivers/media/rc/keymaps/rc-d680-dmb.c @@ -51,10 +51,10 @@ static struct rc_map_table rc_map_d680_dmb_table[] = { static struct rc_map_list d680_dmb_map = { .map = { - .scan = rc_map_d680_dmb_table, - .size = ARRAY_SIZE(rc_map_d680_dmb_table), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_D680_DMB, + .scan = rc_map_d680_dmb_table, + .size = ARRAY_SIZE(rc_map_d680_dmb_table), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_D680_DMB, } }; diff --git a/drivers/media/rc/keymaps/rc-delock-61959.c b/drivers/media/rc/keymaps/rc-delock-61959.c index 01bed864f09d..62de69d78d92 100644 --- a/drivers/media/rc/keymaps/rc-delock-61959.c +++ b/drivers/media/rc/keymaps/rc-delock-61959.c @@ -58,10 +58,10 @@ static struct rc_map_table delock_61959[] = { static struct rc_map_list delock_61959_map = { .map = { - .scan = delock_61959, - .size = ARRAY_SIZE(delock_61959), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DELOCK_61959, + .scan = delock_61959, + .size = ARRAY_SIZE(delock_61959), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DELOCK_61959, } }; diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index a0fa543c9f9e..1b4df106b7b5 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -101,10 +101,10 @@ static struct rc_map_table dib0700_nec_table[] = { static struct rc_map_list dib0700_nec_map = { .map = { - .scan = dib0700_nec_table, - .size = ARRAY_SIZE(dib0700_nec_table), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DIB0700_NEC_TABLE, + .scan = dib0700_nec_table, + .size = ARRAY_SIZE(dib0700_nec_table), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DIB0700_NEC_TABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c index 907941145eb7..b0f8151bb824 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c +++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c @@ -212,10 +212,10 @@ static struct rc_map_table dib0700_rc5_table[] = { static struct rc_map_list dib0700_rc5_map = { .map = { - .scan = dib0700_rc5_table, - .size = ARRAY_SIZE(dib0700_rc5_table), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_DIB0700_RC5_TABLE, + .scan = dib0700_rc5_table, + .size = ARRAY_SIZE(dib0700_rc5_table), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_DIB0700_RC5_TABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c index bed78acb9198..01ca8b39359f 100644 --- a/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c +++ b/drivers/media/rc/keymaps/rc-digitalnow-tinytwin.c @@ -75,10 +75,10 @@ static struct rc_map_table digitalnow_tinytwin[] = { static struct rc_map_list digitalnow_tinytwin_map = { .map = { - .scan = digitalnow_tinytwin, - .size = ARRAY_SIZE(digitalnow_tinytwin), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DIGITALNOW_TINYTWIN, + .scan = digitalnow_tinytwin, + .size = ARRAY_SIZE(digitalnow_tinytwin), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DIGITALNOW_TINYTWIN, } }; diff --git a/drivers/media/rc/keymaps/rc-digittrade.c b/drivers/media/rc/keymaps/rc-digittrade.c index a3b97a1fe223..a54b1d632ca6 100644 --- a/drivers/media/rc/keymaps/rc-digittrade.c +++ b/drivers/media/rc/keymaps/rc-digittrade.c @@ -59,10 +59,10 @@ static struct rc_map_table digittrade[] = { static struct rc_map_list digittrade_map = { .map = { - .scan = digittrade, - .size = ARRAY_SIZE(digittrade), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DIGITTRADE, + .scan = digittrade, + .size = ARRAY_SIZE(digittrade), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DIGITTRADE, } }; diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c index 46e7ae414cc8..c353445d10ed 100644 --- a/drivers/media/rc/keymaps/rc-dm1105-nec.c +++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c @@ -53,10 +53,10 @@ static struct rc_map_table dm1105_nec[] = { static struct rc_map_list dm1105_nec_map = { .map = { - .scan = dm1105_nec, - .size = ARRAY_SIZE(dm1105_nec), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_DM1105_NEC, + .scan = dm1105_nec, + .size = ARRAY_SIZE(dm1105_nec), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DM1105_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c index d2826b46fea2..5bafd5b70f5e 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c @@ -55,10 +55,10 @@ static struct rc_map_table dntv_live_dvb_t[] = { static struct rc_map_list dntv_live_dvb_t_map = { .map = { - .scan = dntv_live_dvb_t, - .size = ARRAY_SIZE(dntv_live_dvb_t), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_DNTV_LIVE_DVB_T, + .scan = dntv_live_dvb_t, + .size = ARRAY_SIZE(dntv_live_dvb_t), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DNTV_LIVE_DVB_T, } }; diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c index 0d74769467b5..360167c8829b 100644 --- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c +++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c @@ -74,10 +74,10 @@ static struct rc_map_table dntv_live_dvbt_pro[] = { static struct rc_map_list dntv_live_dvbt_pro_map = { .map = { - .scan = dntv_live_dvbt_pro, - .size = ARRAY_SIZE(dntv_live_dvbt_pro), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_DNTV_LIVE_DVBT_PRO, + .scan = dntv_live_dvbt_pro, + .size = ARRAY_SIZE(dntv_live_dvbt_pro), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_DNTV_LIVE_DVBT_PRO, } }; diff --git a/drivers/media/rc/keymaps/rc-dtt200u.c b/drivers/media/rc/keymaps/rc-dtt200u.c index 25650e9e4664..c932d8b6c509 100644 --- a/drivers/media/rc/keymaps/rc-dtt200u.c +++ b/drivers/media/rc/keymaps/rc-dtt200u.c @@ -35,10 +35,10 @@ static struct rc_map_table dtt200u_table[] = { static struct rc_map_list dtt200u_map = { .map = { - .scan = dtt200u_table, - .size = ARRAY_SIZE(dtt200u_table), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DTT200U, + .scan = dtt200u_table, + .size = ARRAY_SIZE(dtt200u_table), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DTT200U, } }; diff --git a/drivers/media/rc/keymaps/rc-dvbsky.c b/drivers/media/rc/keymaps/rc-dvbsky.c index c5115a1165d1..d6c0b4c1e20e 100644 --- a/drivers/media/rc/keymaps/rc-dvbsky.c +++ b/drivers/media/rc/keymaps/rc-dvbsky.c @@ -54,10 +54,10 @@ static struct rc_map_table rc5_dvbsky[] = { static struct rc_map_list rc5_dvbsky_map = { .map = { - .scan = rc5_dvbsky, - .size = ARRAY_SIZE(rc5_dvbsky), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_DVBSKY, + .scan = rc5_dvbsky, + .size = ARRAY_SIZE(rc5_dvbsky), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_DVBSKY, } }; diff --git a/drivers/media/rc/keymaps/rc-dvico-mce.c b/drivers/media/rc/keymaps/rc-dvico-mce.c index d1e861f4d095..e4cee190b923 100644 --- a/drivers/media/rc/keymaps/rc-dvico-mce.c +++ b/drivers/media/rc/keymaps/rc-dvico-mce.c @@ -61,10 +61,10 @@ static struct rc_map_table rc_map_dvico_mce_table[] = { static struct rc_map_list dvico_mce_map = { .map = { - .scan = rc_map_dvico_mce_table, - .size = ARRAY_SIZE(rc_map_dvico_mce_table), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DVICO_MCE, + .scan = rc_map_dvico_mce_table, + .size = ARRAY_SIZE(rc_map_dvico_mce_table), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DVICO_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-dvico-portable.c b/drivers/media/rc/keymaps/rc-dvico-portable.c index ac4cb515cbf1..cdd21f54aa61 100644 --- a/drivers/media/rc/keymaps/rc-dvico-portable.c +++ b/drivers/media/rc/keymaps/rc-dvico-portable.c @@ -52,10 +52,10 @@ static struct rc_map_table rc_map_dvico_portable_table[] = { static struct rc_map_list dvico_portable_map = { .map = { - .scan = rc_map_dvico_portable_table, - .size = ARRAY_SIZE(rc_map_dvico_portable_table), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_DVICO_PORTABLE, + .scan = rc_map_dvico_portable_table, + .size = ARRAY_SIZE(rc_map_dvico_portable_table), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_DVICO_PORTABLE, } }; diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c index 7f1e06be175b..18e1a2679c20 100644 --- a/drivers/media/rc/keymaps/rc-em-terratec.c +++ b/drivers/media/rc/keymaps/rc-em-terratec.c @@ -46,10 +46,10 @@ static struct rc_map_table em_terratec[] = { static struct rc_map_list em_terratec_map = { .map = { - .scan = em_terratec, - .size = ARRAY_SIZE(em_terratec), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_EM_TERRATEC, + .scan = em_terratec, + .size = ARRAY_SIZE(em_terratec), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EM_TERRATEC, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c index 4fc3904daf06..72ffd5cb0108 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c @@ -58,10 +58,10 @@ static struct rc_map_table encore_enltv_fm53[] = { static struct rc_map_list encore_enltv_fm53_map = { .map = { - .scan = encore_enltv_fm53, - .size = ARRAY_SIZE(encore_enltv_fm53), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_ENCORE_ENLTV_FM53, + .scan = encore_enltv_fm53, + .size = ARRAY_SIZE(encore_enltv_fm53), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV_FM53, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c index f1914e23d203..e0381e7aa964 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv.c @@ -89,10 +89,10 @@ static struct rc_map_table encore_enltv[] = { static struct rc_map_list encore_enltv_map = { .map = { - .scan = encore_enltv, - .size = ARRAY_SIZE(encore_enltv), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_ENCORE_ENLTV, + .scan = encore_enltv, + .size = ARRAY_SIZE(encore_enltv), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV, } }; diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c index 9c6c55240d18..e9b0bfba319c 100644 --- a/drivers/media/rc/keymaps/rc-encore-enltv2.c +++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c @@ -67,10 +67,10 @@ static struct rc_map_table encore_enltv2[] = { static struct rc_map_list encore_enltv2_map = { .map = { - .scan = encore_enltv2, - .size = ARRAY_SIZE(encore_enltv2), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_ENCORE_ENLTV2, + .scan = encore_enltv2, + .size = ARRAY_SIZE(encore_enltv2), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_ENCORE_ENLTV2, } }; diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c index 2370d2a3deb6..b77c5e908668 100644 --- a/drivers/media/rc/keymaps/rc-evga-indtube.c +++ b/drivers/media/rc/keymaps/rc-evga-indtube.c @@ -38,10 +38,10 @@ static struct rc_map_table evga_indtube[] = { static struct rc_map_list evga_indtube_map = { .map = { - .scan = evga_indtube, - .size = ARRAY_SIZE(evga_indtube), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_EVGA_INDTUBE, + .scan = evga_indtube, + .size = ARRAY_SIZE(evga_indtube), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EVGA_INDTUBE, } }; diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c index b5c96ed84376..5013b3b2aa93 100644 --- a/drivers/media/rc/keymaps/rc-eztv.c +++ b/drivers/media/rc/keymaps/rc-eztv.c @@ -73,10 +73,10 @@ static struct rc_map_table eztv[] = { static struct rc_map_list eztv_map = { .map = { - .scan = eztv, - .size = ARRAY_SIZE(eztv), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_EZTV, + .scan = eztv, + .size = ARRAY_SIZE(eztv), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EZTV, } }; diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c index 25cb89fac03c..418b32521273 100644 --- a/drivers/media/rc/keymaps/rc-flydvb.c +++ b/drivers/media/rc/keymaps/rc-flydvb.c @@ -54,10 +54,10 @@ static struct rc_map_table flydvb[] = { static struct rc_map_list flydvb_map = { .map = { - .scan = flydvb, - .size = ARRAY_SIZE(flydvb), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_FLYDVB, + .scan = flydvb, + .size = ARRAY_SIZE(flydvb), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FLYDVB, } }; diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c index e71377dd0534..93fb87ecf061 100644 --- a/drivers/media/rc/keymaps/rc-flyvideo.c +++ b/drivers/media/rc/keymaps/rc-flyvideo.c @@ -47,10 +47,10 @@ static struct rc_map_table flyvideo[] = { static struct rc_map_list flyvideo_map = { .map = { - .scan = flyvideo, - .size = ARRAY_SIZE(flyvideo), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_FLYVIDEO, + .scan = flyvideo, + .size = ARRAY_SIZE(flyvideo), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FLYVIDEO, } }; diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c index cf0608dc83d5..9ed3f749262b 100644 --- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c +++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c @@ -75,10 +75,10 @@ static struct rc_map_table fusionhdtv_mce[] = { static struct rc_map_list fusionhdtv_mce_map = { .map = { - .scan = fusionhdtv_mce, - .size = ARRAY_SIZE(fusionhdtv_mce), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_FUSIONHDTV_MCE, + .scan = fusionhdtv_mce, + .size = ARRAY_SIZE(fusionhdtv_mce), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_FUSIONHDTV_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c index 03575bdb2eca..3443b721d092 100644 --- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c +++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c @@ -58,10 +58,10 @@ static struct rc_map_table gadmei_rm008z[] = { static struct rc_map_list gadmei_rm008z_map = { .map = { - .scan = gadmei_rm008z, - .size = ARRAY_SIZE(gadmei_rm008z), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_GADMEI_RM008Z, + .scan = gadmei_rm008z, + .size = ARRAY_SIZE(gadmei_rm008z), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GADMEI_RM008Z, } }; diff --git a/drivers/media/rc/keymaps/rc-geekbox.c b/drivers/media/rc/keymaps/rc-geekbox.c index affc4c481888..4aa1b54bb52e 100644 --- a/drivers/media/rc/keymaps/rc-geekbox.c +++ b/drivers/media/rc/keymaps/rc-geekbox.c @@ -31,10 +31,10 @@ static struct rc_map_table geekbox[] = { static struct rc_map_list geekbox_map = { .map = { - .scan = geekbox, - .size = ARRAY_SIZE(geekbox), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_GEEKBOX, + .scan = geekbox, + .size = ARRAY_SIZE(geekbox), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_GEEKBOX, } }; diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c index b2ab13b0dcb1..d140e8d45bcc 100644 --- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c +++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c @@ -61,10 +61,10 @@ static struct rc_map_table genius_tvgo_a11mce[] = { static struct rc_map_list genius_tvgo_a11mce_map = { .map = { - .scan = genius_tvgo_a11mce, - .size = ARRAY_SIZE(genius_tvgo_a11mce), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_GENIUS_TVGO_A11MCE, + .scan = genius_tvgo_a11mce, + .size = ARRAY_SIZE(genius_tvgo_a11mce), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GENIUS_TVGO_A11MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c index 229a36ac7f0a..51230fbb52ba 100644 --- a/drivers/media/rc/keymaps/rc-gotview7135.c +++ b/drivers/media/rc/keymaps/rc-gotview7135.c @@ -56,10 +56,10 @@ static struct rc_map_table gotview7135[] = { static struct rc_map_list gotview7135_map = { .map = { - .scan = gotview7135, - .size = ARRAY_SIZE(gotview7135), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_GOTVIEW7135, + .scan = gotview7135, + .size = ARRAY_SIZE(gotview7135), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_GOTVIEW7135, } }; diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c index 36d57f7c532b..890164b68d64 100644 --- a/drivers/media/rc/keymaps/rc-hauppauge.c +++ b/drivers/media/rc/keymaps/rc-hauppauge.c @@ -269,10 +269,10 @@ static struct rc_map_table rc5_hauppauge_new[] = { static struct rc_map_list rc5_hauppauge_new_map = { .map = { - .scan = rc5_hauppauge_new, - .size = ARRAY_SIZE(rc5_hauppauge_new), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_HAUPPAUGE, + .scan = rc5_hauppauge_new, + .size = ARRAY_SIZE(rc5_hauppauge_new), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_HAUPPAUGE, } }; diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c index f0da960560b0..6a69ce1451f1 100644 --- a/drivers/media/rc/keymaps/rc-imon-mce.c +++ b/drivers/media/rc/keymaps/rc-imon-mce.c @@ -118,11 +118,11 @@ static struct rc_map_table imon_mce[] = { static struct rc_map_list imon_mce_map = { .map = { - .scan = imon_mce, - .size = ARRAY_SIZE(imon_mce), + .scan = imon_mce, + .size = ARRAY_SIZE(imon_mce), /* its RC6, but w/a hardware decoder */ - .rc_type = RC_TYPE_RC6_MCE, - .name = RC_MAP_IMON_MCE, + .rc_proto = RC_PROTO_RC6_MCE, + .name = RC_MAP_IMON_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c index 999c6295c70e..a7296ffbf218 100644 --- a/drivers/media/rc/keymaps/rc-imon-pad.c +++ b/drivers/media/rc/keymaps/rc-imon-pad.c @@ -132,11 +132,11 @@ static struct rc_map_table imon_pad[] = { static struct rc_map_list imon_pad_map = { .map = { - .scan = imon_pad, - .size = ARRAY_SIZE(imon_pad), + .scan = imon_pad, + .size = ARRAY_SIZE(imon_pad), /* actual protocol details unknown, hardware decoder */ - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_IMON_PAD, + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_IMON_PAD, } }; diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c index 9ee154cb0c6b..8cf87a15c4f2 100644 --- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c +++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c @@ -65,10 +65,10 @@ static struct rc_map_table iodata_bctv7e[] = { static struct rc_map_list iodata_bctv7e_map = { .map = { - .scan = iodata_bctv7e, - .size = ARRAY_SIZE(iodata_bctv7e), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_IODATA_BCTV7E, + .scan = iodata_bctv7e, + .size = ARRAY_SIZE(iodata_bctv7e), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_IODATA_BCTV7E, } }; diff --git a/drivers/media/rc/keymaps/rc-it913x-v1.c b/drivers/media/rc/keymaps/rc-it913x-v1.c index 0ac775fd109d..908d14848ae8 100644 --- a/drivers/media/rc/keymaps/rc-it913x-v1.c +++ b/drivers/media/rc/keymaps/rc-it913x-v1.c @@ -71,10 +71,10 @@ static struct rc_map_table it913x_v1_rc[] = { static struct rc_map_list it913x_v1_map = { .map = { - .scan = it913x_v1_rc, - .size = ARRAY_SIZE(it913x_v1_rc), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_IT913X_V1, + .scan = it913x_v1_rc, + .size = ARRAY_SIZE(it913x_v1_rc), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_IT913X_V1, } }; diff --git a/drivers/media/rc/keymaps/rc-it913x-v2.c b/drivers/media/rc/keymaps/rc-it913x-v2.c index bd42a30ec06f..05ab7fa4f90b 100644 --- a/drivers/media/rc/keymaps/rc-it913x-v2.c +++ b/drivers/media/rc/keymaps/rc-it913x-v2.c @@ -70,10 +70,10 @@ static struct rc_map_table it913x_v2_rc[] = { static struct rc_map_list it913x_v2_map = { .map = { - .scan = it913x_v2_rc, - .size = ARRAY_SIZE(it913x_v2_rc), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_IT913X_V2, + .scan = it913x_v2_rc, + .size = ARRAY_SIZE(it913x_v2_rc), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_IT913X_V2, } }; diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c index 60803a732c08..e791f1e1b43b 100644 --- a/drivers/media/rc/keymaps/rc-kaiomy.c +++ b/drivers/media/rc/keymaps/rc-kaiomy.c @@ -64,10 +64,10 @@ static struct rc_map_table kaiomy[] = { static struct rc_map_list kaiomy_map = { .map = { - .scan = kaiomy, - .size = ARRAY_SIZE(kaiomy), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_KAIOMY, + .scan = kaiomy, + .size = ARRAY_SIZE(kaiomy), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_KAIOMY, } }; diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c index ba087eed1ed9..71dce0138f0e 100644 --- a/drivers/media/rc/keymaps/rc-kworld-315u.c +++ b/drivers/media/rc/keymaps/rc-kworld-315u.c @@ -60,10 +60,10 @@ static struct rc_map_table kworld_315u[] = { static struct rc_map_list kworld_315u_map = { .map = { - .scan = kworld_315u, - .size = ARRAY_SIZE(kworld_315u), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_KWORLD_315U, + .scan = kworld_315u, + .size = ARRAY_SIZE(kworld_315u), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_KWORLD_315U, } }; diff --git a/drivers/media/rc/keymaps/rc-kworld-pc150u.c b/drivers/media/rc/keymaps/rc-kworld-pc150u.c index b92e571f4def..3846059060aa 100644 --- a/drivers/media/rc/keymaps/rc-kworld-pc150u.c +++ b/drivers/media/rc/keymaps/rc-kworld-pc150u.c @@ -78,10 +78,10 @@ static struct rc_map_table kworld_pc150u[] = { static struct rc_map_list kworld_pc150u_map = { .map = { - .scan = kworld_pc150u, - .size = ARRAY_SIZE(kworld_pc150u), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_KWORLD_PC150U, + .scan = kworld_pc150u, + .size = ARRAY_SIZE(kworld_pc150u), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_KWORLD_PC150U, } }; diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c index edc868564f99..e0322ed16c94 100644 --- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c +++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c @@ -76,10 +76,10 @@ static struct rc_map_table kworld_plus_tv_analog[] = { static struct rc_map_list kworld_plus_tv_analog_map = { .map = { - .scan = kworld_plus_tv_analog, - .size = ARRAY_SIZE(kworld_plus_tv_analog), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_KWORLD_PLUS_TV_ANALOG, + .scan = kworld_plus_tv_analog, + .size = ARRAY_SIZE(kworld_plus_tv_analog), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_KWORLD_PLUS_TV_ANALOG, } }; diff --git a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c index 03d762d986ee..e534a5601b6d 100644 --- a/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c +++ b/drivers/media/rc/keymaps/rc-leadtek-y04g0051.c @@ -76,10 +76,10 @@ static struct rc_map_table leadtek_y04g0051[] = { static struct rc_map_list leadtek_y04g0051_map = { .map = { - .scan = leadtek_y04g0051, - .size = ARRAY_SIZE(leadtek_y04g0051), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_LEADTEK_Y04G0051, + .scan = leadtek_y04g0051, + .size = ARRAY_SIZE(leadtek_y04g0051), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_LEADTEK_Y04G0051, } }; diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c index 2b0027c41332..9c93f90f5c2b 100644 --- a/drivers/media/rc/keymaps/rc-lme2510.c +++ b/drivers/media/rc/keymaps/rc-lme2510.c @@ -87,10 +87,10 @@ static struct rc_map_table lme2510_rc[] = { static struct rc_map_list lme2510_map = { .map = { - .scan = lme2510_rc, - .size = ARRAY_SIZE(lme2510_rc), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_LME2510, + .scan = lme2510_rc, + .size = ARRAY_SIZE(lme2510_rc), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_LME2510, } }; diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c index 92424ef2aaa6..da566902a4dd 100644 --- a/drivers/media/rc/keymaps/rc-manli.c +++ b/drivers/media/rc/keymaps/rc-manli.c @@ -111,10 +111,10 @@ static struct rc_map_table manli[] = { static struct rc_map_list manli_map = { .map = { - .scan = manli, - .size = ARRAY_SIZE(manli), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_MANLI, + .scan = manli, + .size = ARRAY_SIZE(manli), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MANLI, } }; diff --git a/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c b/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c index 966f9b3c71da..c9973340e546 100644 --- a/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c +++ b/drivers/media/rc/keymaps/rc-medion-x10-digitainer.c @@ -98,10 +98,10 @@ static struct rc_map_table medion_x10_digitainer[] = { static struct rc_map_list medion_x10_digitainer_map = { .map = { - .scan = medion_x10_digitainer, - .size = ARRAY_SIZE(medion_x10_digitainer), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_MEDION_X10_DIGITAINER, + .scan = medion_x10_digitainer, + .size = ARRAY_SIZE(medion_x10_digitainer), + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_MEDION_X10_DIGITAINER, } }; diff --git a/drivers/media/rc/keymaps/rc-medion-x10-or2x.c b/drivers/media/rc/keymaps/rc-medion-x10-or2x.c index b077300ecb5c..103ad88d242c 100644 --- a/drivers/media/rc/keymaps/rc-medion-x10-or2x.c +++ b/drivers/media/rc/keymaps/rc-medion-x10-or2x.c @@ -83,10 +83,10 @@ static struct rc_map_table medion_x10_or2x[] = { static struct rc_map_list medion_x10_or2x_map = { .map = { - .scan = medion_x10_or2x, - .size = ARRAY_SIZE(medion_x10_or2x), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_MEDION_X10_OR2X, + .scan = medion_x10_or2x, + .size = ARRAY_SIZE(medion_x10_or2x), + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_MEDION_X10_OR2X, } }; diff --git a/drivers/media/rc/keymaps/rc-medion-x10.c b/drivers/media/rc/keymaps/rc-medion-x10.c index 479cdb897810..bbffa5dfe420 100644 --- a/drivers/media/rc/keymaps/rc-medion-x10.c +++ b/drivers/media/rc/keymaps/rc-medion-x10.c @@ -93,10 +93,10 @@ static struct rc_map_table medion_x10[] = { static struct rc_map_list medion_x10_map = { .map = { - .scan = medion_x10, - .size = ARRAY_SIZE(medion_x10), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_MEDION_X10, + .scan = medion_x10, + .size = ARRAY_SIZE(medion_x10), + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_MEDION_X10, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c index 2fa71d0d72d7..94aa12d4b73c 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-ii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-ii.c @@ -44,10 +44,10 @@ static struct rc_map_table msi_digivox_ii[] = { static struct rc_map_list msi_digivox_ii_map = { .map = { - .scan = msi_digivox_ii, - .size = ARRAY_SIZE(msi_digivox_ii), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_MSI_DIGIVOX_II, + .scan = msi_digivox_ii, + .size = ARRAY_SIZE(msi_digivox_ii), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_MSI_DIGIVOX_II, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c index 303a0b73175b..8fec0c1dcb12 100644 --- a/drivers/media/rc/keymaps/rc-msi-digivox-iii.c +++ b/drivers/media/rc/keymaps/rc-msi-digivox-iii.c @@ -62,10 +62,10 @@ static struct rc_map_table msi_digivox_iii[] = { static struct rc_map_list msi_digivox_iii_map = { .map = { - .scan = msi_digivox_iii, - .size = ARRAY_SIZE(msi_digivox_iii), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_MSI_DIGIVOX_III, + .scan = msi_digivox_iii, + .size = ARRAY_SIZE(msi_digivox_iii), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_MSI_DIGIVOX_III, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c index fd7a55c56167..dfa0ed1d7667 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c @@ -100,10 +100,10 @@ static struct rc_map_table msi_tvanywhere_plus[] = { static struct rc_map_list msi_tvanywhere_plus_map = { .map = { - .scan = msi_tvanywhere_plus, - .size = ARRAY_SIZE(msi_tvanywhere_plus), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_MSI_TVANYWHERE_PLUS, + .scan = msi_tvanywhere_plus, + .size = ARRAY_SIZE(msi_tvanywhere_plus), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MSI_TVANYWHERE_PLUS, } }; diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c index 4233a8d4d63e..2111816a3f59 100644 --- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c +++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c @@ -46,10 +46,10 @@ static struct rc_map_table msi_tvanywhere[] = { static struct rc_map_list msi_tvanywhere_map = { .map = { - .scan = msi_tvanywhere, - .size = ARRAY_SIZE(msi_tvanywhere), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_MSI_TVANYWHERE, + .scan = msi_tvanywhere, + .size = ARRAY_SIZE(msi_tvanywhere), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_MSI_TVANYWHERE, } }; diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c index 4c50f33c7c41..109b6e1a8b1a 100644 --- a/drivers/media/rc/keymaps/rc-nebula.c +++ b/drivers/media/rc/keymaps/rc-nebula.c @@ -73,10 +73,10 @@ static struct rc_map_table nebula[] = { static struct rc_map_list nebula_map = { .map = { - .scan = nebula, - .size = ARRAY_SIZE(nebula), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_NEBULA, + .scan = nebula, + .size = ARRAY_SIZE(nebula), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_NEBULA, } }; diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index 292bbad35d21..bb2d3a2962c0 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -134,10 +134,10 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = { static struct rc_map_list nec_terratec_cinergy_xs_map = { .map = { - .scan = nec_terratec_cinergy_xs, - .size = ARRAY_SIZE(nec_terratec_cinergy_xs), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_NEC_TERRATEC_CINERGY_XS, + .scan = nec_terratec_cinergy_xs, + .size = ARRAY_SIZE(nec_terratec_cinergy_xs), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_NEC_TERRATEC_CINERGY_XS, } }; diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c index ca1b82a2c54f..cd25df336749 100644 --- a/drivers/media/rc/keymaps/rc-norwood.c +++ b/drivers/media/rc/keymaps/rc-norwood.c @@ -62,10 +62,10 @@ static struct rc_map_table norwood[] = { static struct rc_map_list norwood_map = { .map = { - .scan = norwood, - .size = ARRAY_SIZE(norwood), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_NORWOOD, + .scan = norwood, + .size = ARRAY_SIZE(norwood), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_NORWOOD, } }; diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c index 1fb946024512..140bbc20a764 100644 --- a/drivers/media/rc/keymaps/rc-npgtech.c +++ b/drivers/media/rc/keymaps/rc-npgtech.c @@ -57,10 +57,10 @@ static struct rc_map_table npgtech[] = { static struct rc_map_list npgtech_map = { .map = { - .scan = npgtech, - .size = ARRAY_SIZE(npgtech), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_NPGTECH, + .scan = npgtech, + .size = ARRAY_SIZE(npgtech), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_NPGTECH, } }; diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c index 5ef01ab3fd50..52b4558b7bd0 100644 --- a/drivers/media/rc/keymaps/rc-pctv-sedna.c +++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c @@ -57,10 +57,10 @@ static struct rc_map_table pctv_sedna[] = { static struct rc_map_list pctv_sedna_map = { .map = { - .scan = pctv_sedna, - .size = ARRAY_SIZE(pctv_sedna), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PCTV_SEDNA, + .scan = pctv_sedna, + .size = ARRAY_SIZE(pctv_sedna), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PCTV_SEDNA, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c index a218b471a4ca..973c9c34e304 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-color.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c @@ -71,10 +71,10 @@ static struct rc_map_table pinnacle_color[] = { static struct rc_map_list pinnacle_color_map = { .map = { - .scan = pinnacle_color, - .size = ARRAY_SIZE(pinnacle_color), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PINNACLE_COLOR, + .scan = pinnacle_color, + .size = ARRAY_SIZE(pinnacle_color), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PINNACLE_COLOR, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c index 4a3f467a47a2..22e44b0d2a93 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c @@ -66,10 +66,10 @@ static struct rc_map_table pinnacle_grey[] = { static struct rc_map_list pinnacle_grey_map = { .map = { - .scan = pinnacle_grey, - .size = ARRAY_SIZE(pinnacle_grey), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PINNACLE_GREY, + .scan = pinnacle_grey, + .size = ARRAY_SIZE(pinnacle_grey), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PINNACLE_GREY, } }; diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index e89cc10b68bf..186dcf8e0491 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c @@ -47,10 +47,10 @@ static struct rc_map_table pinnacle_pctv_hd[] = { static struct rc_map_list pinnacle_pctv_hd_map = { .map = { - .scan = pinnacle_pctv_hd, - .size = ARRAY_SIZE(pinnacle_pctv_hd), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_PINNACLE_PCTV_HD, + .scan = pinnacle_pctv_hd, + .size = ARRAY_SIZE(pinnacle_pctv_hd), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_PINNACLE_PCTV_HD, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c index d967c3816fdc..b235ada2e28f 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-002t.c +++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c @@ -54,10 +54,10 @@ static struct rc_map_table pixelview_002t[] = { static struct rc_map_list pixelview_map = { .map = { - .scan = pixelview_002t, - .size = ARRAY_SIZE(pixelview_002t), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_PIXELVIEW_002T, + .scan = pixelview_002t, + .size = ARRAY_SIZE(pixelview_002t), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_PIXELVIEW_002T, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c index 224d0efaa6e5..453d52d663fe 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c +++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c @@ -60,10 +60,10 @@ static struct rc_map_table pixelview_mk12[] = { static struct rc_map_list pixelview_map = { .map = { - .scan = pixelview_mk12, - .size = ARRAY_SIZE(pixelview_mk12), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_PIXELVIEW_MK12, + .scan = pixelview_mk12, + .size = ARRAY_SIZE(pixelview_mk12), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_PIXELVIEW_MK12, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c index 781d788d6b6d..ef97095ec8f1 100644 --- a/drivers/media/rc/keymaps/rc-pixelview-new.c +++ b/drivers/media/rc/keymaps/rc-pixelview-new.c @@ -60,10 +60,10 @@ static struct rc_map_table pixelview_new[] = { static struct rc_map_list pixelview_new_map = { .map = { - .scan = pixelview_new, - .size = ARRAY_SIZE(pixelview_new), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PIXELVIEW_NEW, + .scan = pixelview_new, + .size = ARRAY_SIZE(pixelview_new), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PIXELVIEW_NEW, } }; diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c index 39e6feaa35a3..cfd8f80d3617 100644 --- a/drivers/media/rc/keymaps/rc-pixelview.c +++ b/drivers/media/rc/keymaps/rc-pixelview.c @@ -59,10 +59,10 @@ static struct rc_map_table pixelview[] = { static struct rc_map_list pixelview_map = { .map = { - .scan = pixelview, - .size = ARRAY_SIZE(pixelview), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PIXELVIEW, + .scan = pixelview, + .size = ARRAY_SIZE(pixelview), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PIXELVIEW, } }; diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c index e96fa3ab9f4b..b63f82bcf29a 100644 --- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c +++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c @@ -58,10 +58,10 @@ static struct rc_map_table powercolor_real_angel[] = { static struct rc_map_list powercolor_real_angel_map = { .map = { - .scan = powercolor_real_angel, - .size = ARRAY_SIZE(powercolor_real_angel), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_POWERCOLOR_REAL_ANGEL, + .scan = powercolor_real_angel, + .size = ARRAY_SIZE(powercolor_real_angel), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_POWERCOLOR_REAL_ANGEL, } }; diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c index eef626ee02df..be34c517e4e1 100644 --- a/drivers/media/rc/keymaps/rc-proteus-2309.c +++ b/drivers/media/rc/keymaps/rc-proteus-2309.c @@ -46,10 +46,10 @@ static struct rc_map_table proteus_2309[] = { static struct rc_map_list proteus_2309_map = { .map = { - .scan = proteus_2309, - .size = ARRAY_SIZE(proteus_2309), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PROTEUS_2309, + .scan = proteus_2309, + .size = ARRAY_SIZE(proteus_2309), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PROTEUS_2309, } }; diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c index cec6fe466829..84c40b97ee00 100644 --- a/drivers/media/rc/keymaps/rc-purpletv.c +++ b/drivers/media/rc/keymaps/rc-purpletv.c @@ -58,10 +58,10 @@ static struct rc_map_table purpletv[] = { static struct rc_map_list purpletv_map = { .map = { - .scan = purpletv, - .size = ARRAY_SIZE(purpletv), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PURPLETV, + .scan = purpletv, + .size = ARRAY_SIZE(purpletv), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PURPLETV, } }; diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c index 5ac89ce8c053..be190ddebfc4 100644 --- a/drivers/media/rc/keymaps/rc-pv951.c +++ b/drivers/media/rc/keymaps/rc-pv951.c @@ -55,10 +55,10 @@ static struct rc_map_table pv951[] = { static struct rc_map_list pv951_map = { .map = { - .scan = pv951, - .size = ARRAY_SIZE(pv951), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_PV951, + .scan = pv951, + .size = ARRAY_SIZE(pv951), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_PV951, } }; diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c index 5be567506bcd..0d87b20a0c43 100644 --- a/drivers/media/rc/keymaps/rc-rc6-mce.c +++ b/drivers/media/rc/keymaps/rc-rc6-mce.c @@ -96,10 +96,10 @@ static struct rc_map_table rc6_mce[] = { static struct rc_map_list rc6_mce_map = { .map = { - .scan = rc6_mce, - .size = ARRAY_SIZE(rc6_mce), - .rc_type = RC_TYPE_RC6_MCE, - .name = RC_MAP_RC6_MCE, + .scan = rc6_mce, + .size = ARRAY_SIZE(rc6_mce), + .rc_proto = RC_PROTO_RC6_MCE, + .name = RC_MAP_RC6_MCE, } }; diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c index 9f778bd091db..957fa21747ea 100644 --- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c +++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c @@ -55,10 +55,10 @@ static struct rc_map_table real_audio_220_32_keys[] = { static struct rc_map_list real_audio_220_32_keys_map = { .map = { - .scan = real_audio_220_32_keys, - .size = ARRAY_SIZE(real_audio_220_32_keys), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_REAL_AUDIO_220_32_KEYS, + .scan = real_audio_220_32_keys, + .size = ARRAY_SIZE(real_audio_220_32_keys), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_REAL_AUDIO_220_32_KEYS, } }; diff --git a/drivers/media/rc/keymaps/rc-reddo.c b/drivers/media/rc/keymaps/rc-reddo.c index b80b336e9284..3b37acc7b144 100644 --- a/drivers/media/rc/keymaps/rc-reddo.c +++ b/drivers/media/rc/keymaps/rc-reddo.c @@ -62,10 +62,10 @@ static struct rc_map_table reddo[] = { static struct rc_map_list reddo_map = { .map = { - .scan = reddo, - .size = ARRAY_SIZE(reddo), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_REDDO, + .scan = reddo, + .size = ARRAY_SIZE(reddo), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_REDDO, } }; diff --git a/drivers/media/rc/keymaps/rc-snapstream-firefly.c b/drivers/media/rc/keymaps/rc-snapstream-firefly.c index c7f33ec719b4..30630a6f76ac 100644 --- a/drivers/media/rc/keymaps/rc-snapstream-firefly.c +++ b/drivers/media/rc/keymaps/rc-snapstream-firefly.c @@ -83,10 +83,10 @@ static struct rc_map_table snapstream_firefly[] = { static struct rc_map_list snapstream_firefly_map = { .map = { - .scan = snapstream_firefly, - .size = ARRAY_SIZE(snapstream_firefly), - .rc_type = RC_TYPE_OTHER, - .name = RC_MAP_SNAPSTREAM_FIREFLY, + .scan = snapstream_firefly, + .size = ARRAY_SIZE(snapstream_firefly), + .rc_proto = RC_PROTO_OTHER, + .name = RC_MAP_SNAPSTREAM_FIREFLY, } }; diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c index 23c061174ed7..b53bca9e4576 100644 --- a/drivers/media/rc/keymaps/rc-streamzap.c +++ b/drivers/media/rc/keymaps/rc-streamzap.c @@ -57,10 +57,10 @@ static struct rc_map_table streamzap[] = { static struct rc_map_list streamzap_map = { .map = { - .scan = streamzap, - .size = ARRAY_SIZE(streamzap), - .rc_type = RC_TYPE_RC5_SZ, - .name = RC_MAP_STREAMZAP, + .scan = streamzap, + .size = ARRAY_SIZE(streamzap), + .rc_proto = RC_PROTO_RC5_SZ, + .name = RC_MAP_STREAMZAP, } }; diff --git a/drivers/media/rc/keymaps/rc-su3000.c b/drivers/media/rc/keymaps/rc-su3000.c index 8dbd3e9bc951..d9af7e3c55d9 100644 --- a/drivers/media/rc/keymaps/rc-su3000.c +++ b/drivers/media/rc/keymaps/rc-su3000.c @@ -51,10 +51,10 @@ static struct rc_map_table su3000[] = { static struct rc_map_list su3000_map = { .map = { - .scan = su3000, - .size = ARRAY_SIZE(su3000), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_SU3000, + .scan = su3000, + .size = ARRAY_SIZE(su3000), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_SU3000, } }; diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c index 24ce2a252502..05facc043272 100644 --- a/drivers/media/rc/keymaps/rc-tbs-nec.c +++ b/drivers/media/rc/keymaps/rc-tbs-nec.c @@ -52,10 +52,10 @@ static struct rc_map_table tbs_nec[] = { static struct rc_map_list tbs_nec_map = { .map = { - .scan = tbs_nec, - .size = ARRAY_SIZE(tbs_nec), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TBS_NEC, + .scan = tbs_nec, + .size = ARRAY_SIZE(tbs_nec), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TBS_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-technisat-ts35.c b/drivers/media/rc/keymaps/rc-technisat-ts35.c index 3328cbefabad..dff7021734ba 100644 --- a/drivers/media/rc/keymaps/rc-technisat-ts35.c +++ b/drivers/media/rc/keymaps/rc-technisat-ts35.c @@ -53,10 +53,10 @@ static struct rc_map_table technisat_ts35[] = { static struct rc_map_list technisat_ts35_map = { .map = { - .scan = technisat_ts35, - .size = ARRAY_SIZE(technisat_ts35), - .rc_type = RC_TYPE_UNKNOWN, - .name = RC_MAP_TECHNISAT_TS35, + .scan = technisat_ts35, + .size = ARRAY_SIZE(technisat_ts35), + .rc_proto = RC_PROTO_UNKNOWN, + .name = RC_MAP_TECHNISAT_TS35, } }; diff --git a/drivers/media/rc/keymaps/rc-technisat-usb2.c b/drivers/media/rc/keymaps/rc-technisat-usb2.c index 02c9c243c060..58b3baf5ee96 100644 --- a/drivers/media/rc/keymaps/rc-technisat-usb2.c +++ b/drivers/media/rc/keymaps/rc-technisat-usb2.c @@ -66,10 +66,10 @@ static struct rc_map_table technisat_usb2[] = { static struct rc_map_list technisat_usb2_map = { .map = { - .scan = technisat_usb2, - .size = ARRAY_SIZE(technisat_usb2), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_TECHNISAT_USB2, + .scan = technisat_usb2, + .size = ARRAY_SIZE(technisat_usb2), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_TECHNISAT_USB2, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c index 7958f458527a..7ae88ccf1def 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-c-pci.c @@ -65,10 +65,10 @@ static struct rc_map_table terratec_cinergy_c_pci[] = { static struct rc_map_list terratec_cinergy_c_pci_map = { .map = { - .scan = terratec_cinergy_c_pci, - .size = ARRAY_SIZE(terratec_cinergy_c_pci), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TERRATEC_CINERGY_C_PCI, + .scan = terratec_cinergy_c_pci, + .size = ARRAY_SIZE(terratec_cinergy_c_pci), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_C_PCI, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c index 1e096bbda4a0..bf0171b05ac2 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-s2-hd.c @@ -63,10 +63,10 @@ static struct rc_map_table terratec_cinergy_s2_hd[] = { static struct rc_map_list terratec_cinergy_s2_hd_map = { .map = { - .scan = terratec_cinergy_s2_hd, - .size = ARRAY_SIZE(terratec_cinergy_s2_hd), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TERRATEC_CINERGY_S2_HD, + .scan = terratec_cinergy_s2_hd, + .size = ARRAY_SIZE(terratec_cinergy_s2_hd), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_S2_HD, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c index 97eb83ab5a35..3d0f6f7e5bea 100644 --- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c @@ -69,10 +69,10 @@ static struct rc_map_table terratec_cinergy_xs[] = { static struct rc_map_list terratec_cinergy_xs_map = { .map = { - .scan = terratec_cinergy_xs, - .size = ARRAY_SIZE(terratec_cinergy_xs), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TERRATEC_CINERGY_XS, + .scan = terratec_cinergy_xs, + .size = ARRAY_SIZE(terratec_cinergy_xs), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TERRATEC_CINERGY_XS, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-slim-2.c b/drivers/media/rc/keymaps/rc-terratec-slim-2.c index 4c149ef712dc..df57e0a45820 100644 --- a/drivers/media/rc/keymaps/rc-terratec-slim-2.c +++ b/drivers/media/rc/keymaps/rc-terratec-slim-2.c @@ -49,10 +49,10 @@ static struct rc_map_table terratec_slim_2[] = { static struct rc_map_list terratec_slim_2_map = { .map = { - .scan = terratec_slim_2, - .size = ARRAY_SIZE(terratec_slim_2), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_TERRATEC_SLIM_2, + .scan = terratec_slim_2, + .size = ARRAY_SIZE(terratec_slim_2), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TERRATEC_SLIM_2, } }; diff --git a/drivers/media/rc/keymaps/rc-terratec-slim.c b/drivers/media/rc/keymaps/rc-terratec-slim.c index 3d8a19cdb5a2..628272c58d65 100644 --- a/drivers/media/rc/keymaps/rc-terratec-slim.c +++ b/drivers/media/rc/keymaps/rc-terratec-slim.c @@ -56,10 +56,10 @@ static struct rc_map_table terratec_slim[] = { static struct rc_map_list terratec_slim_map = { .map = { - .scan = terratec_slim, - .size = ARRAY_SIZE(terratec_slim), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_TERRATEC_SLIM, + .scan = terratec_slim, + .size = ARRAY_SIZE(terratec_slim), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TERRATEC_SLIM, } }; diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c index 38e0c0875596..31f8a0fd1f2c 100644 --- a/drivers/media/rc/keymaps/rc-tevii-nec.c +++ b/drivers/media/rc/keymaps/rc-tevii-nec.c @@ -65,10 +65,10 @@ static struct rc_map_table tevii_nec[] = { static struct rc_map_list tevii_nec_map = { .map = { - .scan = tevii_nec, - .size = ARRAY_SIZE(tevii_nec), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TEVII_NEC, + .scan = tevii_nec, + .size = ARRAY_SIZE(tevii_nec), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TEVII_NEC, } }; diff --git a/drivers/media/rc/keymaps/rc-tivo.c b/drivers/media/rc/keymaps/rc-tivo.c index 5cc1b456e329..1962e33c8f4e 100644 --- a/drivers/media/rc/keymaps/rc-tivo.c +++ b/drivers/media/rc/keymaps/rc-tivo.c @@ -75,10 +75,10 @@ static struct rc_map_table tivo[] = { static struct rc_map_list tivo_map = { .map = { - .scan = tivo, - .size = ARRAY_SIZE(tivo), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_TIVO, + .scan = tivo, + .size = ARRAY_SIZE(tivo), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TIVO, } }; diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand-02.c b/drivers/media/rc/keymaps/rc-total-media-in-hand-02.c index 47270f72ebf0..eeeca142f7b1 100644 --- a/drivers/media/rc/keymaps/rc-total-media-in-hand-02.c +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand-02.c @@ -62,10 +62,10 @@ static struct rc_map_table total_media_in_hand_02[] = { static struct rc_map_list total_media_in_hand_02_map = { .map = { - .scan = total_media_in_hand_02, - .size = ARRAY_SIZE(total_media_in_hand_02), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_TOTAL_MEDIA_IN_HAND_02, + .scan = total_media_in_hand_02, + .size = ARRAY_SIZE(total_media_in_hand_02), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_TOTAL_MEDIA_IN_HAND_02, } }; diff --git a/drivers/media/rc/keymaps/rc-total-media-in-hand.c b/drivers/media/rc/keymaps/rc-total-media-in-hand.c index 5b9f9ec13680..bc73bee309d8 100644 --- a/drivers/media/rc/keymaps/rc-total-media-in-hand.c +++ b/drivers/media/rc/keymaps/rc-total-media-in-hand.c @@ -62,10 +62,10 @@ static struct rc_map_table total_media_in_hand[] = { static struct rc_map_list total_media_in_hand_map = { .map = { - .scan = total_media_in_hand, - .size = ARRAY_SIZE(total_media_in_hand), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_TOTAL_MEDIA_IN_HAND, + .scan = total_media_in_hand, + .size = ARRAY_SIZE(total_media_in_hand), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TOTAL_MEDIA_IN_HAND, } }; diff --git a/drivers/media/rc/keymaps/rc-trekstor.c b/drivers/media/rc/keymaps/rc-trekstor.c index f9a2e0fabb9f..63f966219342 100644 --- a/drivers/media/rc/keymaps/rc-trekstor.c +++ b/drivers/media/rc/keymaps/rc-trekstor.c @@ -57,10 +57,10 @@ static struct rc_map_table trekstor[] = { static struct rc_map_list trekstor_map = { .map = { - .scan = trekstor, - .size = ARRAY_SIZE(trekstor), - .rc_type = RC_TYPE_NEC, - .name = RC_MAP_TREKSTOR, + .scan = trekstor, + .size = ARRAY_SIZE(trekstor), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_TREKSTOR, } }; diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c index c766d3b2b6b0..374c230705d2 100644 --- a/drivers/media/rc/keymaps/rc-tt-1500.c +++ b/drivers/media/rc/keymaps/rc-tt-1500.c @@ -59,10 +59,10 @@ static struct rc_map_table tt_1500[] = { static struct rc_map_list tt_1500_map = { .map = { - .scan = tt_1500, - .size = ARRAY_SIZE(tt_1500), - .rc_type = RC_TYPE_RC5, - .name = RC_MAP_TT_1500, + .scan = tt_1500, + .size = ARRAY_SIZE(tt_1500), + .rc_proto = RC_PROTO_RC5, + .name = RC_MAP_TT_1500, } }; diff --git a/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c b/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c index 202500cb3061..240d720d440c 100644 --- a/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c +++ b/drivers/media/rc/keymaps/rc-twinhan-dtv-cab-ci.c @@ -75,10 +75,10 @@ static struct rc_map_table twinhan_dtv_cab_ci[] = { static struct rc_map_list twinhan_dtv_cab_ci_map = { .map = { - .scan = twinhan_dtv_cab_ci, - .size = ARRAY_SIZE(twinhan_dtv_cab_ci), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TWINHAN_DTV_CAB_CI, + .scan = twinhan_dtv_cab_ci, + .size = ARRAY_SIZE(twinhan_dtv_cab_ci), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TWINHAN_DTV_CAB_CI, } }; diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c index 509299b90c90..2275b37c61d2 100644 --- a/drivers/media/rc/keymaps/rc-twinhan1027.c +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -64,10 +64,10 @@ static struct rc_map_table twinhan_vp1027[] = { static struct rc_map_list twinhan_vp1027_map = { .map = { - .scan = twinhan_vp1027, - .size = ARRAY_SIZE(twinhan_vp1027), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_TWINHAN_VP1027_DVBS, + .scan = twinhan_vp1027, + .size = ARRAY_SIZE(twinhan_vp1027), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_TWINHAN_VP1027_DVBS, } }; diff --git a/drivers/media/rc/keymaps/rc-videomate-m1f.c b/drivers/media/rc/keymaps/rc-videomate-m1f.c index 23ee05e53949..fe02e047bd01 100644 --- a/drivers/media/rc/keymaps/rc-videomate-m1f.c +++ b/drivers/media/rc/keymaps/rc-videomate-m1f.c @@ -69,10 +69,10 @@ static struct rc_map_table videomate_k100[] = { static struct rc_map_list videomate_k100_map = { .map = { - .scan = videomate_k100, - .size = ARRAY_SIZE(videomate_k100), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_VIDEOMATE_K100, + .scan = videomate_k100, + .size = ARRAY_SIZE(videomate_k100), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_K100, } }; diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c index 8a354775a2d8..b4f103269872 100644 --- a/drivers/media/rc/keymaps/rc-videomate-s350.c +++ b/drivers/media/rc/keymaps/rc-videomate-s350.c @@ -62,10 +62,10 @@ static struct rc_map_table videomate_s350[] = { static struct rc_map_list videomate_s350_map = { .map = { - .scan = videomate_s350, - .size = ARRAY_SIZE(videomate_s350), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_VIDEOMATE_S350, + .scan = videomate_s350, + .size = ARRAY_SIZE(videomate_s350), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_S350, } }; diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c index eb0cda7766c4..c431fdf44057 100644 --- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c +++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c @@ -64,10 +64,10 @@ static struct rc_map_table videomate_tv_pvr[] = { static struct rc_map_list videomate_tv_pvr_map = { .map = { - .scan = videomate_tv_pvr, - .size = ARRAY_SIZE(videomate_tv_pvr), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_VIDEOMATE_TV_PVR, + .scan = videomate_tv_pvr, + .size = ARRAY_SIZE(videomate_tv_pvr), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_VIDEOMATE_TV_PVR, } }; diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index c1dd598e828e..5a437e61bd5d 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -59,10 +59,10 @@ static struct rc_map_table winfast_usbii_deluxe[] = { static struct rc_map_list winfast_usbii_deluxe_map = { .map = { - .scan = winfast_usbii_deluxe, - .size = ARRAY_SIZE(winfast_usbii_deluxe), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_WINFAST_USBII_DELUXE, + .scan = winfast_usbii_deluxe, + .size = ARRAY_SIZE(winfast_usbii_deluxe), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_WINFAST_USBII_DELUXE, } }; diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c index 8a779da1e973..53685d1f9a47 100644 --- a/drivers/media/rc/keymaps/rc-winfast.c +++ b/drivers/media/rc/keymaps/rc-winfast.c @@ -79,10 +79,10 @@ static struct rc_map_table winfast[] = { static struct rc_map_list winfast_map = { .map = { - .scan = winfast, - .size = ARRAY_SIZE(winfast), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_WINFAST, + .scan = winfast, + .size = ARRAY_SIZE(winfast), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_WINFAST, } }; diff --git a/drivers/media/rc/keymaps/rc-zx-irdec.c b/drivers/media/rc/keymaps/rc-zx-irdec.c index cc889df47eb8..5bf3ab002afc 100644 --- a/drivers/media/rc/keymaps/rc-zx-irdec.c +++ b/drivers/media/rc/keymaps/rc-zx-irdec.c @@ -57,7 +57,7 @@ static struct rc_map_list zx_irdec_map = { .map = { .scan = zx_irdec_table, .size = ARRAY_SIZE(zx_irdec_table), - .rc_type = RC_TYPE_NEC, + .rc_proto = RC_PROTO_NEC, .name = RC_MAP_ZX_IRDEC, } }; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 60258889b162..bf7aaff3aa37 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1267,7 +1267,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) usb_to_input_id(ir->usbdev, &rc->input_id); rc->dev.parent = dev; rc->priv = ir; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->timeout = MS_TO_NS(100); if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index dfe3da487be0..f2204eb77e2a 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -143,7 +143,7 @@ static int meson_ir_probe(struct platform_device *pdev) ir->rc->input_id.bustype = BUS_HOST; map_name = of_get_property(node, "linux,rc-map-name", NULL); ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; - ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); ir->rc->timeout = MS_TO_NS(200); ir->rc->driver_name = DRIVER_NAME; diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index da4461fabce6..e88eb64e8e69 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -353,7 +353,7 @@ static int mtk_ir_probe(struct platform_device *pdev) ir->rc->map_name = map_name ?: RC_MAP_EMPTY; ir->rc->dev.parent = dev; ir->rc->driver_name = MTK_IR_DEV; - ir->rc->allowed_protocols = RC_BIT_ALL; + ir->rc->allowed_protocols = RC_PROTO_BIT_ALL; ir->rc->rx_resolution = MTK_IR_SAMPLE; ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1); diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 5249cb58ea73..5e1d866a61a5 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -1023,8 +1023,8 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; - rdev->allowed_wakeup_protocols = RC_BIT_ALL_IR_ENCODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + rdev->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER; rdev->encode_wakeup = true; rdev->open = nvt_open; rdev->close = nvt_close; diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 5e5b10fbc47e..7da9c96cb058 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -27,7 +27,7 @@ struct ir_raw_handler { u64 protocols; /* which are handled by this handler */ int (*decode)(struct rc_dev *dev, struct ir_raw_event event); - int (*encode)(enum rc_type protocol, u32 scancode, + int (*encode)(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max); /* These two should only be used by the lirc decoder */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 1761be8c7028..f495709e28fb 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -213,7 +213,7 @@ ir_raw_get_allowed_protocols(void) return atomic64_read(&available_protocols); } -static int change_protocol(struct rc_dev *dev, u64 *rc_type) +static int change_protocol(struct rc_dev *dev, u64 *rc_proto) { /* the caller will update dev->enabled_protocols */ return 0; @@ -450,7 +450,7 @@ EXPORT_SYMBOL(ir_raw_gen_pl); * -EINVAL if the scancode is ambiguous or invalid, or if no * compatible encoder was found. */ -int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode, +int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max) { struct ir_raw_handler *handler; diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 46cc9c29d68a..3822d9ebcb46 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -226,8 +226,8 @@ static int __init loop_init(void) rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_EMPTY; rc->priv = &loopdev; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; - rc->allowed_wakeup_protocols = RC_BIT_ALL_IR_ENCODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + rc->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER; rc->encode_wakeup = true; rc->timeout = 100 * 1000 * 1000; /* 100 ms */ rc->min_timeout = 1; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f2d3cc450d08..981cccd6b988 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -35,48 +35,48 @@ static const struct { unsigned int repeat_period; unsigned int scancode_bits; } protocols[] = { - [RC_TYPE_UNKNOWN] = { .name = "unknown", .repeat_period = 250 }, - [RC_TYPE_OTHER] = { .name = "other", .repeat_period = 250 }, - [RC_TYPE_RC5] = { .name = "rc-5", + [RC_PROTO_UNKNOWN] = { .name = "unknown", .repeat_period = 250 }, + [RC_PROTO_OTHER] = { .name = "other", .repeat_period = 250 }, + [RC_PROTO_RC5] = { .name = "rc-5", .scancode_bits = 0x1f7f, .repeat_period = 164 }, - [RC_TYPE_RC5X_20] = { .name = "rc-5x-20", + [RC_PROTO_RC5X_20] = { .name = "rc-5x-20", .scancode_bits = 0x1f7f3f, .repeat_period = 164 }, - [RC_TYPE_RC5_SZ] = { .name = "rc-5-sz", + [RC_PROTO_RC5_SZ] = { .name = "rc-5-sz", .scancode_bits = 0x2fff, .repeat_period = 164 }, - [RC_TYPE_JVC] = { .name = "jvc", + [RC_PROTO_JVC] = { .name = "jvc", .scancode_bits = 0xffff, .repeat_period = 250 }, - [RC_TYPE_SONY12] = { .name = "sony-12", + [RC_PROTO_SONY12] = { .name = "sony-12", .scancode_bits = 0x1f007f, .repeat_period = 100 }, - [RC_TYPE_SONY15] = { .name = "sony-15", + [RC_PROTO_SONY15] = { .name = "sony-15", .scancode_bits = 0xff007f, .repeat_period = 100 }, - [RC_TYPE_SONY20] = { .name = "sony-20", + [RC_PROTO_SONY20] = { .name = "sony-20", .scancode_bits = 0x1fff7f, .repeat_period = 100 }, - [RC_TYPE_NEC] = { .name = "nec", + [RC_PROTO_NEC] = { .name = "nec", .scancode_bits = 0xffff, .repeat_period = 160 }, - [RC_TYPE_NECX] = { .name = "nec-x", + [RC_PROTO_NECX] = { .name = "nec-x", .scancode_bits = 0xffffff, .repeat_period = 160 }, - [RC_TYPE_NEC32] = { .name = "nec-32", + [RC_PROTO_NEC32] = { .name = "nec-32", .scancode_bits = 0xffffffff, .repeat_period = 160 }, - [RC_TYPE_SANYO] = { .name = "sanyo", + [RC_PROTO_SANYO] = { .name = "sanyo", .scancode_bits = 0x1fffff, .repeat_period = 250 }, - [RC_TYPE_MCIR2_KBD] = { .name = "mcir2-kbd", + [RC_PROTO_MCIR2_KBD] = { .name = "mcir2-kbd", .scancode_bits = 0xffff, .repeat_period = 150 }, - [RC_TYPE_MCIR2_MSE] = { .name = "mcir2-mse", + [RC_PROTO_MCIR2_MSE] = { .name = "mcir2-mse", .scancode_bits = 0x1fffff, .repeat_period = 150 }, - [RC_TYPE_RC6_0] = { .name = "rc-6-0", + [RC_PROTO_RC6_0] = { .name = "rc-6-0", .scancode_bits = 0xffff, .repeat_period = 164 }, - [RC_TYPE_RC6_6A_20] = { .name = "rc-6-6a-20", + [RC_PROTO_RC6_6A_20] = { .name = "rc-6-6a-20", .scancode_bits = 0xfffff, .repeat_period = 164 }, - [RC_TYPE_RC6_6A_24] = { .name = "rc-6-6a-24", + [RC_PROTO_RC6_6A_24] = { .name = "rc-6-6a-24", .scancode_bits = 0xffffff, .repeat_period = 164 }, - [RC_TYPE_RC6_6A_32] = { .name = "rc-6-6a-32", + [RC_PROTO_RC6_6A_32] = { .name = "rc-6-6a-32", .scancode_bits = 0xffffffff, .repeat_period = 164 }, - [RC_TYPE_RC6_MCE] = { .name = "rc-6-mce", + [RC_PROTO_RC6_MCE] = { .name = "rc-6-mce", .scancode_bits = 0xffff7fff, .repeat_period = 164 }, - [RC_TYPE_SHARP] = { .name = "sharp", + [RC_PROTO_SHARP] = { .name = "sharp", .scancode_bits = 0x1fff, .repeat_period = 250 }, - [RC_TYPE_XMP] = { .name = "xmp", .repeat_period = 250 }, - [RC_TYPE_CEC] = { .name = "cec", .repeat_period = 550 }, + [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 }, + [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 550 }, }; /* Used to keep track of known keymaps */ @@ -156,10 +156,10 @@ static struct rc_map_table empty[] = { static struct rc_map_list empty_map = { .map = { - .scan = empty, - .size = ARRAY_SIZE(empty), - .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ - .name = RC_MAP_EMPTY, + .scan = empty, + .size = ARRAY_SIZE(empty), + .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .name = RC_MAP_EMPTY, } }; @@ -167,7 +167,7 @@ static struct rc_map_list empty_map = { * ir_create_table() - initializes a scancode table * @rc_map: the rc_map to initialize * @name: name to assign to the table - * @rc_type: ir type to assign to the new table + * @rc_proto: ir type to assign to the new table * @size: initial size of the table * @return: zero on success or a negative error code * @@ -175,12 +175,12 @@ static struct rc_map_list empty_map = { * memory to hold at least the specified number of elements. */ static int ir_create_table(struct rc_map *rc_map, - const char *name, u64 rc_type, size_t size) + const char *name, u64 rc_proto, size_t size) { rc_map->name = kstrdup(name, GFP_KERNEL); if (!rc_map->name) return -ENOMEM; - rc_map->rc_type = rc_type; + rc_map->rc_proto = rc_proto; rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table)); rc_map->size = rc_map->alloc / sizeof(struct rc_map_table); rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL); @@ -435,7 +435,7 @@ static int ir_setkeytable(struct rc_dev *dev, int rc; rc = ir_create_table(rc_map, from->name, - from->rc_type, from->size); + from->rc_proto, from->size); if (rc) return rc; @@ -688,7 +688,7 @@ EXPORT_SYMBOL_GPL(rc_repeat); * This function is used internally to register a keypress, it must be * called with keylock held. */ -static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol, +static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, u32 keycode, u8 toggle) { bool new_event = (!dev->keypressed || @@ -730,7 +730,8 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol, * This routine is used to signal that a key has been pressed on the * remote control. */ -void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle) +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, + u8 toggle) { unsigned long flags; u32 keycode = rc_g_keycode_from_table(dev, scancode); @@ -759,7 +760,7 @@ EXPORT_SYMBOL_GPL(rc_keydown); * This routine is used to signal that a key has been pressed on the * remote control. The driver must manually call rc_keyup() at a later stage. */ -void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol, +void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, u8 toggle) { unsigned long flags; @@ -782,7 +783,7 @@ static int rc_validate_filter(struct rc_dev *dev, struct rc_scancode_filter *filter) { u32 mask, s = filter->data; - enum rc_type protocol = dev->wakeup_protocol; + enum rc_proto protocol = dev->wakeup_protocol; if (protocol >= ARRAY_SIZE(protocols)) return -EINVAL; @@ -790,19 +791,19 @@ static int rc_validate_filter(struct rc_dev *dev, mask = protocols[protocol].scancode_bits; switch (protocol) { - case RC_TYPE_NECX: + case RC_PROTO_NECX: if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0) return -EINVAL; break; - case RC_TYPE_NEC32: + case RC_PROTO_NEC32: if ((((s >> 24) ^ ~(s >> 16)) & 0xff) == 0) return -EINVAL; break; - case RC_TYPE_RC6_MCE: + case RC_PROTO_RC6_MCE: if ((s & 0xffff0000) != 0x800f0000) return -EINVAL; break; - case RC_TYPE_RC6_6A_32: + case RC_PROTO_RC6_6A_32: if ((s & 0xffff0000) == 0x800f0000) return -EINVAL; break; @@ -890,30 +891,30 @@ static const struct { const char *name; const char *module_name; } proto_names[] = { - { RC_BIT_NONE, "none", NULL }, - { RC_BIT_OTHER, "other", NULL }, - { RC_BIT_UNKNOWN, "unknown", NULL }, - { RC_BIT_RC5 | - RC_BIT_RC5X_20, "rc-5", "ir-rc5-decoder" }, - { RC_BIT_NEC | - RC_BIT_NECX | - RC_BIT_NEC32, "nec", "ir-nec-decoder" }, - { RC_BIT_RC6_0 | - RC_BIT_RC6_6A_20 | - RC_BIT_RC6_6A_24 | - RC_BIT_RC6_6A_32 | - RC_BIT_RC6_MCE, "rc-6", "ir-rc6-decoder" }, - { RC_BIT_JVC, "jvc", "ir-jvc-decoder" }, - { RC_BIT_SONY12 | - RC_BIT_SONY15 | - RC_BIT_SONY20, "sony", "ir-sony-decoder" }, - { RC_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" }, - { RC_BIT_SANYO, "sanyo", "ir-sanyo-decoder" }, - { RC_BIT_SHARP, "sharp", "ir-sharp-decoder" }, - { RC_BIT_MCIR2_KBD | - RC_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, - { RC_BIT_XMP, "xmp", "ir-xmp-decoder" }, - { RC_BIT_CEC, "cec", NULL }, + { RC_PROTO_BIT_NONE, "none", NULL }, + { RC_PROTO_BIT_OTHER, "other", NULL }, + { RC_PROTO_BIT_UNKNOWN, "unknown", NULL }, + { RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC5X_20, "rc-5", "ir-rc5-decoder" }, + { RC_PROTO_BIT_NEC | + RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32, "nec", "ir-nec-decoder" }, + { RC_PROTO_BIT_RC6_0 | + RC_PROTO_BIT_RC6_6A_20 | + RC_PROTO_BIT_RC6_6A_24 | + RC_PROTO_BIT_RC6_6A_32 | + RC_PROTO_BIT_RC6_MCE, "rc-6", "ir-rc6-decoder" }, + { RC_PROTO_BIT_JVC, "jvc", "ir-jvc-decoder" }, + { RC_PROTO_BIT_SONY12 | + RC_PROTO_BIT_SONY15 | + RC_PROTO_BIT_SONY20, "sony", "ir-sony-decoder" }, + { RC_PROTO_BIT_RC5_SZ, "rc-5-sz", "ir-rc5-decoder" }, + { RC_PROTO_BIT_SANYO, "sanyo", "ir-sanyo-decoder" }, + { RC_PROTO_BIT_SHARP, "sharp", "ir-sharp-decoder" }, + { RC_PROTO_BIT_MCIR2_KBD | + RC_PROTO_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, + { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, + { RC_PROTO_BIT_CEC, "cec", NULL }, }; /** @@ -1083,8 +1084,9 @@ static void ir_raw_load_modules(u64 *protocols) int i, ret; for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (proto_names[i].type == RC_BIT_NONE || - proto_names[i].type & (RC_BIT_OTHER | RC_BIT_UNKNOWN)) + if (proto_names[i].type == RC_PROTO_BIT_NONE || + proto_names[i].type & (RC_PROTO_BIT_OTHER | + RC_PROTO_BIT_UNKNOWN)) continue; available = ir_raw_get_allowed_protocols(); @@ -1302,7 +1304,7 @@ static ssize_t store_filter(struct device *device, * Refuse to set a filter unless a protocol is enabled * and the filter is valid for that protocol */ - if (dev->wakeup_protocol != RC_TYPE_UNKNOWN) + if (dev->wakeup_protocol != RC_PROTO_UNKNOWN) ret = rc_validate_filter(dev, &new_filter); else ret = -EINVAL; @@ -1349,7 +1351,7 @@ static ssize_t show_wakeup_protocols(struct device *device, { struct rc_dev *dev = to_rc_dev(device); u64 allowed; - enum rc_type enabled; + enum rc_proto enabled; char *tmp = buf; int i; @@ -1398,7 +1400,7 @@ static ssize_t store_wakeup_protocols(struct device *device, const char *buf, size_t len) { struct rc_dev *dev = to_rc_dev(device); - enum rc_type protocol; + enum rc_proto protocol; ssize_t rc; u64 allowed; int i; @@ -1408,7 +1410,7 @@ static ssize_t store_wakeup_protocols(struct device *device, allowed = dev->allowed_wakeup_protocols; if (sysfs_streq(buf, "none")) { - protocol = RC_TYPE_UNKNOWN; + protocol = RC_PROTO_UNKNOWN; } else { for (i = 0; i < ARRAY_SIZE(protocols); i++) { if ((allowed & (1ULL << i)) && @@ -1438,7 +1440,7 @@ static ssize_t store_wakeup_protocols(struct device *device, dev->wakeup_protocol = protocol; IR_dprintk(1, "Wakeup protocol changed to %d\n", protocol); - if (protocol == RC_TYPE_RC6_MCE) + if (protocol == RC_PROTO_RC6_MCE) dev->scancode_wakeup_filter.data = 0x800f0000; else dev->scancode_wakeup_filter.data = 0; @@ -1619,7 +1621,7 @@ static int rc_prepare_rx_device(struct rc_dev *dev) { int rc; struct rc_map *rc_map; - u64 rc_type; + u64 rc_proto; if (!dev->map_name) return -EINVAL; @@ -1634,17 +1636,17 @@ static int rc_prepare_rx_device(struct rc_dev *dev) if (rc) return rc; - rc_type = BIT_ULL(rc_map->rc_type); + rc_proto = BIT_ULL(rc_map->rc_proto); if (dev->change_protocol) { - rc = dev->change_protocol(dev, &rc_type); + rc = dev->change_protocol(dev, &rc_proto); if (rc < 0) goto out_table; - dev->enabled_protocols = rc_type; + dev->enabled_protocols = rc_proto; } if (dev->driver_type == RC_DRIVER_IR_RAW) - ir_raw_load_modules(&rc_type); + ir_raw_load_modules(&rc_proto); set_bit(EV_KEY, dev->input_dev->evbit); set_bit(EV_REP, dev->input_dev->evbit); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 29fa37b99553..6784cb9fc4e7 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -956,7 +956,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) usb_to_input_id(rr3->udev, &rc->input_id); rc->dev.parent = dev; rc->priv = rr3; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT); rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT); rc->timeout = US_TO_NS(redrat3_get_timeout(rr3)); diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 9a5e9fa01196..4b8d5f38baf6 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -537,7 +537,7 @@ static int serial_ir_probe(struct platform_device *dev) rcdev->open = serial_ir_open; rcdev->close = serial_ir_close; rcdev->dev.parent = &serial_ir.pdev->dev; - rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rcdev->driver_name = KBUILD_MODNAME; rcdev->map_name = RC_MAP_RC6_MCE; rcdev->min_timeout = 1; diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index 83b4410664af..bc906fb128d5 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -315,7 +315,7 @@ static int sir_ir_probe(struct platform_device *dev) rcdev->input_id.product = 0x0001; rcdev->input_id.version = 0x0100; rcdev->tx_ir = sir_tx_ir; - rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rcdev->driver_name = KBUILD_MODNAME; rcdev->map_name = RC_MAP_RC6_MCE; rcdev->timeout = IR_DEFAULT_TIMEOUT; diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index dc15dc8a7d21..a8e39c635f34 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -290,7 +290,7 @@ static int st_rc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rc_dev); st_rc_hardware_init(rc_dev); - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* rx sampling rate is 10Mhz */ rdev->rx_resolution = 100; rdev->timeout = US_TO_NS(MAX_SYMB_TIME); diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 829f2b348a46..f03a174ddf9d 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -304,7 +304,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) usb_to_input_id(sz->usbdev, &rdev->input_id); rdev->dev.parent = dev; rdev->priv = sz; - rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rdev->driver_name = DRIVER_NAME; rdev->map_name = RC_MAP_STREAMZAP; diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index f619b76273be..97f367b446c4 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -224,7 +224,7 @@ static int sunxi_ir_probe(struct platform_device *pdev) ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL); ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY; ir->rc->dev.parent = dev; - ir->rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; ir->rc->rx_resolution = SUNXI_IR_SAMPLE; ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); ir->rc->driver_name = SUNXI_IR_DEV; diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 5002a91e830e..aafea3c5170b 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -313,7 +313,7 @@ static int ttusbir_probe(struct usb_interface *intf, rc->input_phys = tt->phys; usb_to_input_id(tt->udev, &rc->input_id); rc->dev.parent = &intf->dev; - rc->allowed_protocols = RC_BIT_ALL_IR_DECODER; + rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->priv = tt; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_TT_1500; diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index a18eb232ed81..3ca7ab48293d 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -697,7 +697,7 @@ wbcir_shutdown(struct pnp_dev *device) } switch (rc->wakeup_protocol) { - case RC_TYPE_RC5: + case RC_PROTO_RC5: /* Mask = 13 bits, ex toggle */ mask[0] = (mask_sc & 0x003f); mask[0] |= (mask_sc & 0x0300) >> 2; @@ -714,7 +714,7 @@ wbcir_shutdown(struct pnp_dev *device) proto = IR_PROTOCOL_RC5; break; - case RC_TYPE_NEC: + case RC_PROTO_NEC: mask[1] = bitrev8(mask_sc); mask[0] = mask[1]; mask[3] = bitrev8(mask_sc >> 8); @@ -728,7 +728,7 @@ wbcir_shutdown(struct pnp_dev *device) proto = IR_PROTOCOL_NEC; break; - case RC_TYPE_NECX: + case RC_PROTO_NECX: mask[1] = bitrev8(mask_sc); mask[0] = mask[1]; mask[2] = bitrev8(mask_sc >> 8); @@ -742,7 +742,7 @@ wbcir_shutdown(struct pnp_dev *device) proto = IR_PROTOCOL_NEC; break; - case RC_TYPE_NEC32: + case RC_PROTO_NEC32: mask[0] = bitrev8(mask_sc); mask[1] = bitrev8(mask_sc >> 8); mask[2] = bitrev8(mask_sc >> 16); @@ -756,7 +756,7 @@ wbcir_shutdown(struct pnp_dev *device) proto = IR_PROTOCOL_NEC; break; - case RC_TYPE_RC6_0: + case RC_PROTO_RC6_0: /* Command */ match[0] = wbcir_to_rc6cells(wake_sc >> 0); mask[0] = wbcir_to_rc6cells(mask_sc >> 0); @@ -779,9 +779,9 @@ wbcir_shutdown(struct pnp_dev *device) proto = IR_PROTOCOL_RC6; break; - case RC_TYPE_RC6_6A_24: - case RC_TYPE_RC6_6A_32: - case RC_TYPE_RC6_MCE: + case RC_PROTO_RC6_6A_24: + case RC_PROTO_RC6_6A_32: + case RC_PROTO_RC6_MCE: i = 0; /* Command */ @@ -800,13 +800,13 @@ wbcir_shutdown(struct pnp_dev *device) match[i] = wbcir_to_rc6cells(wake_sc >> 16); mask[i++] = wbcir_to_rc6cells(mask_sc >> 16); - if (rc->wakeup_protocol == RC_TYPE_RC6_6A_20) { + if (rc->wakeup_protocol == RC_PROTO_RC6_6A_20) { rc6_csl = 52; } else { match[i] = wbcir_to_rc6cells(wake_sc >> 20); mask[i++] = wbcir_to_rc6cells(mask_sc >> 20); - if (rc->wakeup_protocol == RC_TYPE_RC6_6A_24) { + if (rc->wakeup_protocol == RC_PROTO_RC6_6A_24) { rc6_csl = 60; } else { /* Customer range bit and bits 15 - 8 */ @@ -1086,12 +1086,13 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->timeout = IR_DEFAULT_TIMEOUT; data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; data->dev->rx_resolution = US_TO_NS(2); - data->dev->allowed_protocols = RC_BIT_ALL_IR_DECODER; - data->dev->allowed_wakeup_protocols = RC_BIT_NEC | RC_BIT_NECX | - RC_BIT_NEC32 | RC_BIT_RC5 | RC_BIT_RC6_0 | - RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE; - data->dev->wakeup_protocol = RC_TYPE_RC6_MCE; + data->dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + data->dev->allowed_wakeup_protocols = RC_PROTO_BIT_NEC | + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | + RC_PROTO_BIT_RC6_MCE; + data->dev->wakeup_protocol = RC_PROTO_RC6_MCE; data->dev->scancode_wakeup_filter.data = 0x800f040c; data->dev->scancode_wakeup_filter.mask = 0xffff7fff; data->dev->s_wakeup_filter = wbcir_set_wakeup_filter; diff --git a/drivers/media/rc/zx-irdec.c b/drivers/media/rc/zx-irdec.c index 9452bac9262c..12d322ec8a29 100644 --- a/drivers/media/rc/zx-irdec.c +++ b/drivers/media/rc/zx-irdec.c @@ -54,7 +54,7 @@ static irqreturn_t zx_irdec_irq(int irq, void *dev_id) u8 address, not_address; u8 command, not_command; u32 rawcode, scancode; - enum rc_type rc_type; + enum rc_proto rc_proto; /* Clear interrupt */ writel(1, irdec->base + ZX_IR_INTSTCLR); @@ -73,8 +73,8 @@ static irqreturn_t zx_irdec_irq(int irq, void *dev_id) scancode = ir_nec_bytes_to_scancode(address, not_address, command, not_command, - &rc_type); - rc_keydown(irdec->rcd, rc_type, scancode, 0); + &rc_proto); + rc_keydown(irdec->rcd, rc_proto, scancode, 0); done: return IRQ_HANDLED; @@ -114,7 +114,8 @@ static int zx_irdec_probe(struct platform_device *pdev) rcd->input_phys = DRIVER_NAME "/input0"; rcd->input_id.bustype = BUS_HOST; rcd->map_name = RC_MAP_ZX_IRDEC; - rcd->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + rcd->allowed_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32; rcd->driver_name = DRIVER_NAME; rcd->device_name = DRIVER_NAME; diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 9ae42ebefa8a..7996eb83a54e 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -343,8 +343,8 @@ int au0828_rc_register(struct au0828_dev *dev) rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct); rc->dev.parent = &dev->usbdev->dev; rc->driver_name = "au0828-input"; - rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | - RC_BIT_RC5; + rc->allowed_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5; /* all done */ err = rc_register_device(rc); diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c index eecf074b0a48..02ebeb16055f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-input.c +++ b/drivers/media/usb/cx231xx/cx231xx-input.c @@ -24,7 +24,7 @@ #define MODULE_NAME "cx231xx-input" -static int get_key_isdbt(struct IR_i2c *ir, enum rc_type *protocol, +static int get_key_isdbt(struct IR_i2c *ir, enum rc_proto *protocol, u32 *pscancode, u8 *toggle) { int rc; @@ -50,7 +50,7 @@ static int get_key_isdbt(struct IR_i2c *ir, enum rc_type *protocol, dev_dbg(&ir->rc->dev, "cmd %02x, scan = %02x\n", cmd, scancode); - *protocol = RC_TYPE_OTHER; + *protocol = RC_PROTO_OTHER; *pscancode = scancode; *toggle = 0; return 1; @@ -91,7 +91,7 @@ int cx231xx_ir_init(struct cx231xx *dev) /* The i2c micro-controller only outputs the cmd part of NEC protocol */ dev->init_data.rc_dev->scancode_mask = 0xff; dev->init_data.rc_dev->driver_name = "cx231xx"; - dev->init_data.type = RC_BIT_NEC; + dev->init_data.type = RC_PROTO_BIT_NEC; info.addr = 0x30; /* Load and bind ir-kbd-i2c */ diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 23bbbf367b51..8013659c41b1 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -1237,7 +1237,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { - enum rc_type proto; + enum rc_proto proto; dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", __func__, 4, buf + 12); @@ -1253,13 +1253,13 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* NEC */ state->rc_keycode = RC_SCANCODE_NEC(buf[12], buf[14]); - proto = RC_TYPE_NEC; + proto = RC_PROTO_NEC; } else { /* NEC extended*/ state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 | buf[13], buf[14]); - proto = RC_TYPE_NECX; + proto = RC_PROTO_NECX; } } else { /* 32 bit NEC */ @@ -1267,7 +1267,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) buf[13] << 16 | buf[14] << 8 | buf[15]); - proto = RC_TYPE_NEC32; + proto = RC_PROTO_NEC32; } rc_keydown(d->rc_dev, proto, state->rc_keycode, 0); } else { @@ -1336,7 +1336,8 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) if (!rc->map_name) rc->map_name = RC_MAP_EMPTY; - rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + rc->allowed_protos = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32; rc->query = af9015_rc_query; rc->interval = 500; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index ccf4a5c68877..666d319d3d1a 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1828,7 +1828,7 @@ static int af9035_rc_query(struct dvb_usb_device *d) { struct usb_interface *intf = d->intf; int ret; - enum rc_type proto; + enum rc_proto proto; u32 key; u8 buf[4]; struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, buf }; @@ -1843,17 +1843,17 @@ static int af9035_rc_query(struct dvb_usb_device *d) if ((buf[0] + buf[1]) == 0xff) { /* NEC standard 16bit */ key = RC_SCANCODE_NEC(buf[0], buf[2]); - proto = RC_TYPE_NEC; + proto = RC_PROTO_NEC; } else { /* NEC extended 24bit */ key = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]); - proto = RC_TYPE_NECX; + proto = RC_PROTO_NECX; } } else { /* NEC full code 32bit */ key = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]); - proto = RC_TYPE_NEC32; + proto = RC_PROTO_NEC32; } dev_dbg(&intf->dev, "%*ph\n", 4, buf); @@ -1881,11 +1881,11 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) switch (state->ir_type) { case 0: /* NEC */ default: - rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | - RC_BIT_NEC32; + rc->allowed_protos = RC_PROTO_BIT_NEC | + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32; break; case 1: /* RC6 */ - rc->allowed_protos = RC_BIT_RC6_MCE; + rc->allowed_protos = RC_PROTO_BIT_RC6_MCE; break; } diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index 6795c0c609b1..20ee7eea2a91 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -1142,7 +1142,7 @@ static int anysee_rc_query(struct dvb_usb_device *d) if (ircode[0]) { dev_dbg(&d->udev->dev, "%s: key pressed %02x\n", __func__, ircode[1]); - rc_keydown(d->rc_dev, RC_TYPE_NEC, + rc_keydown(d->rc_dev, RC_PROTO_NEC, RC_SCANCODE_NEC(0x08, ircode[1]), 0); } @@ -1151,7 +1151,7 @@ static int anysee_rc_query(struct dvb_usb_device *d) static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_PROTO_BIT_NEC; rc->query = anysee_rc_query; rc->interval = 250; /* windows driver uses 500ms */ diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 72f26300c236..1414d59e85ba 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -208,7 +208,7 @@ static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d_to_priv(d); unsigned code; - enum rc_type proto; + enum rc_proto proto; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); @@ -218,18 +218,18 @@ static int az6007_rc_query(struct dvb_usb_device *d) if ((st->data[3] ^ st->data[4]) == 0xff) { if ((st->data[1] ^ st->data[2]) == 0xff) { code = RC_SCANCODE_NEC(st->data[1], st->data[3]); - proto = RC_TYPE_NEC; + proto = RC_PROTO_NEC; } else { code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2], st->data[3]); - proto = RC_TYPE_NECX; + proto = RC_PROTO_NECX; } } else { code = RC_SCANCODE_NEC32(st->data[1] << 24 | st->data[2] << 16 | st->data[3] << 8 | st->data[4]); - proto = RC_TYPE_NEC32; + proto = RC_PROTO_NEC32; } rc_keydown(d->rc_dev, proto, code, st->data[5]); @@ -241,7 +241,8 @@ static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { pr_debug("Getting az6007 Remote Control properties\n"); - rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + rc->allowed_protos = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32; rc->query = az6007_rc_query; rc->interval = 400; diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 35f27e2e4e28..0005bdb2207d 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -138,7 +138,7 @@ struct dvb_usb_driver_info { struct dvb_usb_rc { const char *map_name; u64 allowed_protos; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto); int (*query) (struct dvb_usb_device *d); unsigned int interval; enum rc_driver_type driver_type; diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 5730760e4e93..131b6c08e199 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -211,7 +211,7 @@ static int dvbsky_rc_query(struct dvb_usb_device *d) rc5_system = (code & 0x7C0) >> 6; toggle = (code & 0x800) ? 1 : 0; scancode = rc5_system << 8 | rc5_command; - rc_keydown(d->rc_dev, RC_TYPE_RC5, scancode, toggle); + rc_keydown(d->rc_dev, RC_PROTO_RC5, scancode, toggle); } return 0; } @@ -223,7 +223,7 @@ static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) return 0; } - rc->allowed_protos = RC_BIT_RC5; + rc->allowed_protos = RC_PROTO_BIT_RC5; rc->query = dvbsky_rc_query; rc->interval = 300; return 0; diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index a91fdad8f8d4..5e320fa4a795 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -347,8 +347,8 @@ static void lme2510_int_response(struct urb *lme_urb) ibuf[5]); deb_info(1, "INT Key = 0x%08x", key); - rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC32, key, - 0); + rc_keydown(adap_to_d(adap)->rc_dev, RC_PROTO_NEC32, key, + 0); break; case 0xbb: switch (st->tuner_config) { @@ -1232,7 +1232,7 @@ static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, static int lme2510_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { - rc->allowed_protos = RC_BIT_NEC32; + rc->allowed_protos = RC_PROTO_BIT_NEC32; return 0; } diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index e16ca07acf1d..95a7b9123f8e 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1631,24 +1631,24 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) goto err; if (buf[4] & 0x01) { - enum rc_type proto; + enum rc_proto proto; if (buf[2] == (u8) ~buf[3]) { if (buf[0] == (u8) ~buf[1]) { /* NEC standard (16 bit) */ rc_code = RC_SCANCODE_NEC(buf[0], buf[2]); - proto = RC_TYPE_NEC; + proto = RC_PROTO_NEC; } else { /* NEC extended (24 bit) */ rc_code = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]); - proto = RC_TYPE_NECX; + proto = RC_PROTO_NECX; } } else { /* NEC full (32 bit) */ rc_code = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]); - proto = RC_TYPE_NEC32; + proto = RC_PROTO_NEC32; } rc_keydown(d->rc_dev, proto, rc_code, 0); @@ -1673,7 +1673,8 @@ static int rtl2831u_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { rc->map_name = RC_MAP_EMPTY; - rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; + rc->allowed_protos = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32; rc->query = rtl2831u_rc_query; rc->interval = 400; @@ -1778,7 +1779,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d, /* load empty to enable rc */ if (!rc->map_name) rc->map_name = RC_MAP_EMPTY; - rc->allowed_protos = RC_BIT_ALL_IR_DECODER; + rc->allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; rc->driver_type = RC_DRIVER_IR_RAW; rc->query = rtl2832u_rc_query; rc->interval = 200; diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 99a3f3625944..37dea0adc695 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -458,7 +458,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d) cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); if (ircode[2] || ircode[3]) - rc_keydown(d->rc_dev, RC_TYPE_NEC, + rc_keydown(d->rc_dev, RC_PROTO_NEC, RC_SCANCODE_NEC(~ircode[2] & 0xff, ircode[3]), 0); return 0; } @@ -473,7 +473,7 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d) return 0; if (ircode[1] || ircode[2]) - rc_keydown(d->rc_dev, RC_TYPE_NEC, + rc_keydown(d->rc_dev, RC_PROTO_NEC, RC_SCANCODE_NEC(~ircode[1] & 0xff, ircode[2]), 0); return 0; } @@ -486,7 +486,7 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d) return 0; if (ircode[0] || ircode[1]) - rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, + rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, RC_SCANCODE_RC5(ircode[0], ircode[1]), 0); return 0; } @@ -1646,7 +1646,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { .rc_codes = RC_MAP_DVICO_PORTABLE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1703,7 +1703,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { .rc_codes = RC_MAP_DVICO_MCE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1768,7 +1768,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .rc_codes = RC_MAP_DVICO_PORTABLE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1824,7 +1824,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { .rc_codes = RC_MAP_DVICO_PORTABLE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -1879,7 +1879,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { .rc_codes = RC_MAP_DVICO_MCE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_bluebird2_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .num_device_descs = 1, @@ -1933,7 +1933,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { .rc_codes = RC_MAP_DVICO_PORTABLE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_bluebird2_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .num_device_descs = 1, @@ -1989,7 +1989,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope .rc_codes = RC_MAP_DVICO_PORTABLE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .num_device_descs = 1, @@ -2088,7 +2088,7 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { .rc_codes = RC_MAP_DVICO_MCE, .module_name = KBUILD_MODNAME, .rc_query = cxusb_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .num_device_descs = 1, @@ -2142,7 +2142,7 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { .rc_codes = RC_MAP_D680_DMB, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_PROTO_BIT_UNKNOWN, }, .num_device_descs = 1, @@ -2197,7 +2197,7 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { .rc_codes = RC_MAP_D680_DMB, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_PROTO_BIT_UNKNOWN, }, .num_device_descs = 1, @@ -2251,7 +2251,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_PROTO_BIT_UNKNOWN, }, .num_device_descs = 1, @@ -2305,7 +2305,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = { .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, .module_name = KBUILD_MODNAME, .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_PROTO_BIT_UNKNOWN, }, .num_device_descs = 1, diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h index 8fd8f5b489d2..f89ab3b5a6c4 100644 --- a/drivers/media/usb/dvb-usb/dib0700.h +++ b/drivers/media/usb/dvb-usb/dib0700.h @@ -64,7 +64,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold); -extern int dib0700_change_protocol(struct rc_dev *dev, u64 *rc_type); +extern int dib0700_change_protocol(struct rc_dev *dev, u64 *rc_proto); extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz); extern int dib0700_device_count; diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index bea1b4764a66..1ee7ec558293 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -638,7 +638,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return ret; } -int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type) +int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_proto) { struct dvb_usb_device *d = rc->priv; struct dib0700_state *st = d->priv; @@ -654,19 +654,19 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type) st->buf[2] = 0; /* Set the IR mode */ - if (*rc_type & RC_BIT_RC5) { + if (*rc_proto & RC_PROTO_BIT_RC5) { new_proto = 1; - *rc_type = RC_BIT_RC5; - } else if (*rc_type & RC_BIT_NEC) { + *rc_proto = RC_PROTO_BIT_RC5; + } else if (*rc_proto & RC_PROTO_BIT_NEC) { new_proto = 0; - *rc_type = RC_BIT_NEC; - } else if (*rc_type & RC_BIT_RC6_MCE) { + *rc_proto = RC_PROTO_BIT_NEC; + } else if (*rc_proto & RC_PROTO_BIT_RC6_MCE) { if (st->fw_version < 0x10200) { ret = -EINVAL; goto out; } new_proto = 2; - *rc_type = RC_BIT_RC6_MCE; + *rc_proto = RC_PROTO_BIT_RC6_MCE; } else { ret = -EINVAL; goto out; @@ -680,7 +680,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type) goto out; } - d->props.rc.core.protocol = *rc_type; + d->props.rc.core.protocol = *rc_proto; out: mutex_unlock(&d->usb_mutex); @@ -712,7 +712,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) { struct dvb_usb_device *d = purb->context; struct dib0700_rc_response *poll_reply; - enum rc_type protocol; + enum rc_proto protocol; u32 keycode; u8 toggle; @@ -745,7 +745,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) purb->actual_length); switch (d->props.rc.core.protocol) { - case RC_BIT_NEC: + case RC_PROTO_BIT_NEC: toggle = 0; /* NEC protocol sends repeat code as 0 0 0 FF */ @@ -764,25 +764,25 @@ static void dib0700_rc_urb_completion(struct urb *purb) poll_reply->nec.not_system << 16 | poll_reply->nec.data << 8 | poll_reply->nec.not_data); - protocol = RC_TYPE_NEC32; + protocol = RC_PROTO_NEC32; } else if ((poll_reply->nec.system ^ poll_reply->nec.not_system) != 0xff) { deb_data("NEC extended protocol\n"); keycode = RC_SCANCODE_NECX(poll_reply->nec.system << 8 | poll_reply->nec.not_system, poll_reply->nec.data); - protocol = RC_TYPE_NECX; + protocol = RC_PROTO_NECX; } else { deb_data("NEC normal protocol\n"); keycode = RC_SCANCODE_NEC(poll_reply->nec.system, poll_reply->nec.data); - protocol = RC_TYPE_NEC; + protocol = RC_PROTO_NEC; } break; default: deb_data("RC5 protocol\n"); - protocol = RC_TYPE_RC5; + protocol = RC_PROTO_RC5; toggle = poll_reply->report_id; keycode = RC_SCANCODE_RC5(poll_reply->rc5.system, poll_reply->rc5.data); diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 6a57fc6d3472..6020170fe99a 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -514,7 +514,7 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) */ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) { - enum rc_type protocol; + enum rc_proto protocol; u32 scancode; u8 toggle; int i; @@ -547,7 +547,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ switch (d->props.rc.core.protocol) { - case RC_BIT_NEC: + case RC_PROTO_BIT_NEC: /* NEC protocol sends repeat code as 0 0 0 FF */ if ((st->buf[3 - 2] == 0x00) && (st->buf[3 - 3] == 0x00) && (st->buf[3] == 0xff)) { @@ -555,14 +555,14 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) return 0; } - protocol = RC_TYPE_NEC; + protocol = RC_PROTO_NEC; scancode = RC_SCANCODE_NEC(st->buf[3 - 2], st->buf[3 - 3]); toggle = 0; break; default: /* RC-5 protocol changes toggle bit on new keypress */ - protocol = RC_TYPE_RC5; + protocol = RC_PROTO_RC5; scancode = RC_SCANCODE_RC5(st->buf[3 - 2], st->buf[3 - 3]); toggle = st->buf[3 - 1]; break; @@ -3909,9 +3909,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_interval = DEFAULT_RC_INTERVAL, .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -3949,9 +3949,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_interval = DEFAULT_RC_INTERVAL, .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4014,9 +4014,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_interval = DEFAULT_RC_INTERVAL, .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4059,9 +4059,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4140,9 +4140,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4185,9 +4185,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4242,9 +4242,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4308,9 +4308,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4357,9 +4357,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_NEC_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4430,9 +4430,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4466,9 +4466,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4542,9 +4542,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4586,9 +4586,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_NEC_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4635,9 +4635,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4672,9 +4672,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4709,9 +4709,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4746,9 +4746,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4783,9 +4783,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4820,9 +4820,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4871,9 +4871,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4906,9 +4906,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4943,9 +4943,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -4981,9 +4981,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, @@ -5035,9 +5035,9 @@ struct dvb_usb_device_properties dib0700_devices[] = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, .module_name = "dib0700", .rc_query = dib0700_rc_query_old_firmware, - .allowed_protos = RC_BIT_RC5 | - RC_BIT_RC6_MCE | - RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_NEC, .change_protocol = dib0700_change_protocol, }, }, diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c index fcbff7fb0c4e..512370786696 100644 --- a/drivers/media/usb/dvb-usb/dtt200u.c +++ b/drivers/media/usb/dvb-usb/dtt200u.c @@ -100,14 +100,14 @@ static int dtt200u_rc_query(struct dvb_usb_device *d) goto ret; if (st->data[0] == 1) { - enum rc_type proto = RC_TYPE_NEC; + enum rc_proto proto = RC_PROTO_NEC; scancode = st->data[1]; if ((u8) ~st->data[1] != st->data[2]) { /* Extended NEC */ scancode = scancode << 8; scancode |= st->data[2]; - proto = RC_TYPE_NECX; + proto = RC_PROTO_NECX; } scancode = scancode << 8; scancode |= st->data[3]; @@ -213,7 +213,7 @@ static struct dvb_usb_device_properties dtt200u_properties = { .rc_interval = 300, .rc_codes = RC_MAP_DTT200U, .rc_query = dtt200u_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -265,7 +265,7 @@ static struct dvb_usb_device_properties wt220u_properties = { .rc_interval = 300, .rc_codes = RC_MAP_DTT200U, .rc_query = dtt200u_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -317,7 +317,7 @@ static struct dvb_usb_device_properties wt220u_fc_properties = { .rc_interval = 300, .rc_codes = RC_MAP_DTT200U, .rc_query = dtt200u_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, @@ -369,7 +369,7 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = { .rc_interval = 300, .rc_codes = RC_MAP_DTT200U, .rc_query = dtt200u_rc_query, - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, }, .generic_bulk_ctrl_endpoint = 0x01, diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h index 67f898b6f6d0..72468fdffa18 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -202,7 +202,7 @@ struct dvb_rc { u64 protocol; u64 allowed_protos; enum rc_driver_type driver_type; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto); char *module_name; int (*rc_query) (struct dvb_usb_device *d); int rc_interval; diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 57b187240110..11109b1e641f 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1671,7 +1671,7 @@ static int dw2102_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0], 0); + rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0); } } @@ -1692,7 +1692,8 @@ static int prof_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0]^0xff, 0); + rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff, + 0); } } @@ -1713,7 +1714,7 @@ static int su3000_rc_query(struct dvb_usb_device *d) if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", __func__, key[0], key[1]); - rc_keydown(d->rc_dev, RC_TYPE_RC5, + rc_keydown(d->rc_dev, RC_PROTO_RC5, RC_SCANCODE_RC5(key[1], key[0]), 0); } } @@ -1912,7 +1913,7 @@ static struct dvb_usb_device_properties dw2102_properties = { .rc_interval = 150, .rc_codes = RC_MAP_DM1105_NEC, .module_name = "dw2102", - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, .rc_query = dw2102_rc_query, }, @@ -1967,7 +1968,7 @@ static struct dvb_usb_device_properties dw2104_properties = { .rc_interval = 150, .rc_codes = RC_MAP_DM1105_NEC, .module_name = "dw2102", - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, .rc_query = dw2102_rc_query, }, @@ -2018,7 +2019,7 @@ static struct dvb_usb_device_properties dw3101_properties = { .rc_interval = 150, .rc_codes = RC_MAP_DM1105_NEC, .module_name = "dw2102", - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, .rc_query = dw2102_rc_query, }, @@ -2067,7 +2068,7 @@ static struct dvb_usb_device_properties s6x0_properties = { .rc_interval = 150, .rc_codes = RC_MAP_TEVII_NEC, .module_name = "dw2102", - .allowed_protos = RC_BIT_NEC, + .allowed_protos = RC_PROTO_BIT_NEC, .rc_query = dw2102_rc_query, }, @@ -2161,7 +2162,7 @@ static struct dvb_usb_device_properties su3000_properties = { .rc_interval = 150, .rc_codes = RC_MAP_SU3000, .module_name = "dw2102", - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, .rc_query = su3000_rc_query, }, @@ -2230,7 +2231,7 @@ static struct dvb_usb_device_properties t220_properties = { .rc_interval = 150, .rc_codes = RC_MAP_SU3000, .module_name = "dw2102", - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, .rc_query = su3000_rc_query, }, @@ -2279,7 +2280,7 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { .rc_interval = 250, .rc_codes = RC_MAP_TT_1500, .module_name = "dw2102", - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, .rc_query = su3000_rc_query, }, diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c index 70672e1e5ec7..32081c2ce0da 100644 --- a/drivers/media/usb/dvb-usb/m920x.c +++ b/drivers/media/usb/dvb-usb/m920x.c @@ -241,7 +241,7 @@ static int m920x_rc_core_query(struct dvb_usb_device *d) else if (state == REMOTE_KEY_REPEAT) rc_repeat(d->rc_dev); else - rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, rc_state[1], 0); + rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, rc_state[1], 0); out: kfree(rc_state); @@ -1208,7 +1208,7 @@ static struct dvb_usb_device_properties vp7049_properties = { .rc_interval = 150, .rc_codes = RC_MAP_TWINHAN_VP1027_DVBS, .rc_query = m920x_rc_core_query, - .allowed_protos = RC_BIT_UNKNOWN, + .allowed_protos = RC_PROTO_BIT_UNKNOWN, }, .size_of_priv = sizeof(struct m920x_state), diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index d54ebe7e0215..601ade7ca48d 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -600,7 +600,7 @@ static int pctv452e_rc_query(struct dvb_usb_device *d) info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[6], rx[7]); - rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0); + rc_keydown(d->rc_dev, RC_PROTO_RC5, state->last_rc_key, 0); } else if (state->last_rc_key) { rc_keyup(d->rc_dev); state->last_rc_key = 0; @@ -958,7 +958,7 @@ static struct dvb_usb_device_properties pctv452e_properties = { .rc.core = { .rc_codes = RC_MAP_DIB0700_RC5_TABLE, - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, .rc_query = pctv452e_rc_query, .rc_interval = 100, }, @@ -1011,7 +1011,7 @@ static struct dvb_usb_device_properties tt_connect_s2_3600_properties = { .rc.core = { .rc_codes = RC_MAP_TT_1500, - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, .rc_query = pctv452e_rc_query, .rc_interval = 100, }, diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 9f7dd1afcb15..18d0f8f5283f 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -749,7 +749,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = { .rc_codes = RC_MAP_TECHNISAT_USB2, .module_name = "technisat-usb2", .rc_query = technisat_usb2_rc_query, - .allowed_protos = RC_BIT_ALL_IR_DECODER, + .allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER, .driver_type = RC_DRIVER_IR_RAW, } }; diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c index 9e0d6a4166d2..e7020f245f53 100644 --- a/drivers/media/usb/dvb-usb/ttusb2.c +++ b/drivers/media/usb/dvb-usb/ttusb2.c @@ -459,7 +459,7 @@ static int tt3650_rc_query(struct dvb_usb_device *d) /* got a "press" event */ st->last_rc_key = RC_SCANCODE_RC5(rx[3], rx[2]); deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]); - rc_keydown(d->rc_dev, RC_TYPE_RC5, st->last_rc_key, rx[1]); + rc_keydown(d->rc_dev, RC_PROTO_RC5, st->last_rc_key, rx[1]); } else if (st->last_rc_key) { rc_keyup(d->rc_dev); st->last_rc_key = 0; @@ -766,7 +766,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */ .rc_codes = RC_MAP_TT_1500, .rc_query = tt3650_rc_query, - .allowed_protos = RC_BIT_RC5, + .allowed_protos = RC_PROTO_BIT_RC5, }, .num_adapters = 1, diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index d8746b96a0f8..046223de1e91 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -55,7 +55,7 @@ struct em28xx_ir_poll_result { unsigned int toggle_bit:1; unsigned int read_count:7; - enum rc_type protocol; + enum rc_proto protocol; u32 scancode; }; @@ -70,11 +70,12 @@ struct em28xx_IR { struct delayed_work work; unsigned int full_code:1; unsigned int last_readcount; - u64 rc_type; + u64 rc_proto; struct i2c_client *i2c_client; - int (*get_key_i2c)(struct i2c_client *ir, enum rc_type *protocol, u32 *scancode); + int (*get_key_i2c)(struct i2c_client *ir, enum rc_proto *protocol, + u32 *scancode); int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); }; @@ -83,7 +84,7 @@ struct em28xx_IR { **********************************************************/ static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, - enum rc_type *protocol, u32 *scancode) + enum rc_proto *protocol, u32 *scancode) { unsigned char b; @@ -101,13 +102,13 @@ static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, /* keep old data */ return 1; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = b; return 1; } static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, - enum rc_type *protocol, u32 *scancode) + enum rc_proto *protocol, u32 *scancode) { unsigned char buf[2]; int size; @@ -131,13 +132,14 @@ static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, * So, the code translation is not complete. Yet, it is enough to * work with the provided RC5 IR. */ - *protocol = RC_TYPE_RC5; + *protocol = RC_PROTO_RC5; *scancode = (bitrev8(buf[1]) & 0x1f) << 8 | bitrev8(buf[0]) >> 2; return 1; } static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, - enum rc_type *protocol, u32 *scancode) + enum rc_proto *protocol, + u32 *scancode) { unsigned char buf[3]; @@ -149,13 +151,14 @@ static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, if (buf[0] != 0x00) return 0; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = buf[2] & 0x3f; return 1; } static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, - enum rc_type *protocol, u32 *scancode) + enum rc_proto *protocol, + u32 *scancode) { unsigned char subaddr, keydetect, key; @@ -175,7 +178,7 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, if (key == 0x00) return 0; - *protocol = RC_TYPE_UNKNOWN; + *protocol = RC_PROTO_UNKNOWN; *scancode = key; return 1; } @@ -207,19 +210,19 @@ static int default_polling_getkey(struct em28xx_IR *ir, poll_result->read_count = (msg[0] & 0x7f); /* Remote Control Address/Data (Regs 0x46/0x47) */ - switch (ir->rc_type) { - case RC_BIT_RC5: - poll_result->protocol = RC_TYPE_RC5; + switch (ir->rc_proto) { + case RC_PROTO_BIT_RC5: + poll_result->protocol = RC_PROTO_RC5; poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]); break; - case RC_BIT_NEC: - poll_result->protocol = RC_TYPE_NEC; + case RC_PROTO_BIT_NEC: + poll_result->protocol = RC_PROTO_NEC; poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[2]); break; default: - poll_result->protocol = RC_TYPE_UNKNOWN; + poll_result->protocol = RC_PROTO_UNKNOWN; poll_result->scancode = msg[1] << 8 | msg[2]; break; } @@ -252,37 +255,37 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, * Remote Control Address (Reg 0x52) * Remote Control Data (Reg 0x53-0x55) */ - switch (ir->rc_type) { - case RC_BIT_RC5: - poll_result->protocol = RC_TYPE_RC5; + switch (ir->rc_proto) { + case RC_PROTO_BIT_RC5: + poll_result->protocol = RC_PROTO_RC5; poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]); break; - case RC_BIT_NEC: + case RC_PROTO_BIT_NEC: poll_result->scancode = msg[1] << 8 | msg[2]; if ((msg[3] ^ msg[4]) != 0xff) { /* 32 bits NEC */ - poll_result->protocol = RC_TYPE_NEC32; + poll_result->protocol = RC_PROTO_NEC32; poll_result->scancode = RC_SCANCODE_NEC32((msg[1] << 24) | (msg[2] << 16) | (msg[3] << 8) | (msg[4])); } else if ((msg[1] ^ msg[2]) != 0xff) { /* 24 bits NEC */ - poll_result->protocol = RC_TYPE_NECX; + poll_result->protocol = RC_PROTO_NECX; poll_result->scancode = RC_SCANCODE_NECX(msg[1] << 8 | msg[2], msg[3]); } else { /* Normal NEC */ - poll_result->protocol = RC_TYPE_NEC; + poll_result->protocol = RC_PROTO_NEC; poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[3]); } break; - case RC_BIT_RC6_0: - poll_result->protocol = RC_TYPE_RC6_0; + case RC_PROTO_BIT_RC6_0: + poll_result->protocol = RC_PROTO_RC6_0; poll_result->scancode = RC_SCANCODE_RC6_0(msg[1], msg[2]); break; default: - poll_result->protocol = RC_TYPE_UNKNOWN; + poll_result->protocol = RC_PROTO_UNKNOWN; poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) | (msg[3] << 8) | msg[4]; break; @@ -298,7 +301,7 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) { static u32 scancode; - enum rc_type protocol; + enum rc_proto protocol; int rc; rc = ir->get_key_i2c(ir->i2c_client, &protocol, &scancode); @@ -338,7 +341,7 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) poll_result.toggle_bit); else rc_keydown(ir->rc, - RC_TYPE_UNKNOWN, + RC_PROTO_UNKNOWN, poll_result.scancode & 0xff, poll_result.toggle_bit); @@ -383,70 +386,71 @@ static void em28xx_ir_stop(struct rc_dev *rc) cancel_delayed_work_sync(&ir->work); } -static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) +static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) { struct em28xx_IR *ir = rc_dev->priv; struct em28xx *dev = ir->dev; /* Adjust xclk based on IR table for RC5/NEC tables */ - if (*rc_type & RC_BIT_RC5) { + if (*rc_proto & RC_PROTO_BIT_RC5) { dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; ir->full_code = 1; - *rc_type = RC_BIT_RC5; - } else if (*rc_type & RC_BIT_NEC) { + *rc_proto = RC_PROTO_BIT_RC5; + } else if (*rc_proto & RC_PROTO_BIT_NEC) { dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; ir->full_code = 1; - *rc_type = RC_BIT_NEC; - } else if (*rc_type & RC_BIT_UNKNOWN) { - *rc_type = RC_BIT_UNKNOWN; + *rc_proto = RC_PROTO_BIT_NEC; + } else if (*rc_proto & RC_PROTO_BIT_UNKNOWN) { + *rc_proto = RC_PROTO_BIT_UNKNOWN; } else { - *rc_type = ir->rc_type; + *rc_proto = ir->rc_proto; return -EINVAL; } em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, EM28XX_XCLK_IR_RC5_MODE); - ir->rc_type = *rc_type; + ir->rc_proto = *rc_proto; return 0; } -static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) +static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) { struct em28xx_IR *ir = rc_dev->priv; struct em28xx *dev = ir->dev; u8 ir_config = EM2874_IR_RC5; /* Adjust xclk and set type based on IR table for RC5/NEC/RC6 tables */ - if (*rc_type & RC_BIT_RC5) { + if (*rc_proto & RC_PROTO_BIT_RC5) { dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; ir->full_code = 1; - *rc_type = RC_BIT_RC5; - } else if (*rc_type & RC_BIT_NEC) { + *rc_proto = RC_PROTO_BIT_RC5; + } else if (*rc_proto & RC_PROTO_BIT_NEC) { dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY; ir->full_code = 1; - *rc_type = RC_BIT_NEC; - } else if (*rc_type & RC_BIT_RC6_0) { + *rc_proto = RC_PROTO_BIT_NEC; + } else if (*rc_proto & RC_PROTO_BIT_RC6_0) { dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; ir_config = EM2874_IR_RC6_MODE_0; ir->full_code = 1; - *rc_type = RC_BIT_RC6_0; - } else if (*rc_type & RC_BIT_UNKNOWN) { - *rc_type = RC_BIT_UNKNOWN; + *rc_proto = RC_PROTO_BIT_RC6_0; + } else if (*rc_proto & RC_PROTO_BIT_UNKNOWN) { + *rc_proto = RC_PROTO_BIT_UNKNOWN; } else { - *rc_type = ir->rc_type; + *rc_proto = ir->rc_proto; return -EINVAL; } em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, EM28XX_XCLK_IR_RC5_MODE); - ir->rc_type = *rc_type; + ir->rc_proto = *rc_proto; return 0; } -static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) + +static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) { struct em28xx_IR *ir = rc_dev->priv; struct em28xx *dev = ir->dev; @@ -455,12 +459,12 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) switch (dev->chip_id) { case CHIP_ID_EM2860: case CHIP_ID_EM2883: - return em2860_ir_change_protocol(rc_dev, rc_type); + return em2860_ir_change_protocol(rc_dev, rc_proto); case CHIP_ID_EM2884: case CHIP_ID_EM2874: case CHIP_ID_EM28174: case CHIP_ID_EM28178: - return em2874_ir_change_protocol(rc_dev, rc_type); + return em2874_ir_change_protocol(rc_dev, rc_proto); default: dev_err(&ir->dev->intf->dev, "Unrecognized em28xx chip id 0x%02x: IR not supported\n", @@ -686,7 +690,7 @@ static int em28xx_ir_init(struct em28xx *dev) struct em28xx_IR *ir; struct rc_dev *rc; int err = -ENOMEM; - u64 rc_type; + u64 rc_proto; u16 i2c_rc_dev_addr = 0; if (dev->is_audio_only) { @@ -749,7 +753,7 @@ static int em28xx_ir_init(struct em28xx *dev) case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: rc->map_name = RC_MAP_HAUPPAUGE; ir->get_key_i2c = em28xx_get_key_em_haup; - rc->allowed_protocols = RC_BIT_RC5; + rc->allowed_protocols = RC_PROTO_BIT_RC5; break; case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: rc->map_name = RC_MAP_WINFAST_USBII_DELUXE; @@ -771,7 +775,8 @@ static int em28xx_ir_init(struct em28xx *dev) switch (dev->chip_id) { case CHIP_ID_EM2860: case CHIP_ID_EM2883: - rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC; + rc->allowed_protocols = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_NEC; ir->get_key = default_polling_getkey; break; case CHIP_ID_EM2884: @@ -779,8 +784,9 @@ static int em28xx_ir_init(struct em28xx *dev) case CHIP_ID_EM28174: case CHIP_ID_EM28178: ir->get_key = em2874_polling_getkey; - rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC | - RC_BIT_NECX | RC_BIT_NEC32 | RC_BIT_RC6_0; + rc->allowed_protocols = RC_PROTO_BIT_RC5 | + RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | + RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC6_0; break; default: err = -ENODEV; @@ -791,8 +797,8 @@ static int em28xx_ir_init(struct em28xx *dev) rc->map_name = dev->board.ir_codes; /* By default, keep protocol field untouched */ - rc_type = RC_BIT_UNKNOWN; - err = em28xx_ir_change_protocol(rc, &rc_type); + rc_proto = RC_PROTO_BIT_UNKNOWN; + err = em28xx_ir_change_protocol(rc, &rc_proto); if (err) goto error; } diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c index fcab55038d99..b9074b978ae3 100644 --- a/drivers/media/usb/hdpvr/hdpvr-i2c.c +++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c @@ -55,7 +55,8 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev) /* Our default information for ir-kbd-i2c.c to use */ init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_BIT_RC5 | RC_BIT_RC6_MCE | RC_BIT_RC6_6A_32; + init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_RC6_6A_32; init_data->name = "HD-PVR"; init_data->polling_interval = 405; /* ms, duplicated from Windows */ hdpvr_ir_rx_i2c_board_info.platform_data = init_data; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c index 20a52b785fff..e3c8f9414e45 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c @@ -567,7 +567,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; - init_data->type = RC_BIT_RC5; + init_data->type = RC_PROTO_BIT_RC5; init_data->name = hdw->hdw_desc->description; init_data->polling_interval = 100; /* ms From ir-kbd-i2c */ /* IR Receiver */ @@ -580,11 +580,11 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) break; case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ - init_data->ir_codes = RC_MAP_HAUPPAUGE; + init_data->ir_codes = RC_MAP_HAUPPAUGE; init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_BIT_RC5 | RC_BIT_RC6_MCE | - RC_BIT_RC6_6A_32; - init_data->name = hdw->hdw_desc->description; + init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | + RC_PROTO_BIT_RC6_6A_32; + init_data->name = hdw->hdw_desc->description; /* IR Receiver */ info.addr = 0x71; info.platform_data = init_data; diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c index 83e33aef0105..91889ad9cdd7 100644 --- a/drivers/media/usb/tm6000/tm6000-input.c +++ b/drivers/media/usb/tm6000/tm6000-input.c @@ -66,7 +66,7 @@ struct tm6000_IR { struct urb *int_urb; /* IR device properties */ - u64 rc_type; + u64 rc_proto; }; void tm6000_ir_wait(struct tm6000_core *dev, u8 state) @@ -103,13 +103,13 @@ static int tm6000_ir_config(struct tm6000_IR *ir) * IR, in order to discard such decoding */ - switch (ir->rc_type) { - case RC_BIT_NEC: + switch (ir->rc_proto) { + case RC_PROTO_BIT_NEC: leader = 900; /* ms */ pulse = 700; /* ms - the actual value would be 562 */ break; default: - case RC_BIT_RC5: + case RC_PROTO_BIT_RC5: leader = 900; /* ms - from the NEC decoding */ pulse = 1780; /* ms - The actual value would be 1776 */ break; @@ -117,12 +117,12 @@ static int tm6000_ir_config(struct tm6000_IR *ir) pulse = ir_clock_mhz * pulse; leader = ir_clock_mhz * leader; - if (ir->rc_type == RC_BIT_NEC) + if (ir->rc_proto == RC_PROTO_BIT_NEC) leader = leader | 0x8000; dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n", __func__, - (ir->rc_type == RC_BIT_NEC) ? "NEC" : "RC-5", + (ir->rc_proto == RC_PROTO_BIT_NEC) ? "NEC" : "RC-5", ir_clock_mhz, leader, pulse); /* Remote WAKEUP = enable, normal mode, from IR decoder output */ @@ -162,24 +162,24 @@ static void tm6000_ir_keydown(struct tm6000_IR *ir, { u8 device, command; u32 scancode; - enum rc_type protocol; + enum rc_proto protocol; if (len < 1) return; command = buf[0]; device = (len > 1 ? buf[1] : 0x0); - switch (ir->rc_type) { - case RC_BIT_RC5: - protocol = RC_TYPE_RC5; + switch (ir->rc_proto) { + case RC_PROTO_BIT_RC5: + protocol = RC_PROTO_RC5; scancode = RC_SCANCODE_RC5(device, command); break; - case RC_BIT_NEC: - protocol = RC_TYPE_NEC; + case RC_PROTO_BIT_NEC: + protocol = RC_PROTO_NEC; scancode = RC_SCANCODE_NEC(device, command); break; default: - protocol = RC_TYPE_OTHER; + protocol = RC_PROTO_OTHER; scancode = RC_SCANCODE_OTHER(device << 8 | command); break; } @@ -311,7 +311,7 @@ static void tm6000_ir_stop(struct rc_dev *rc) cancel_delayed_work_sync(&ir->work); } -static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) +static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) { struct tm6000_IR *ir = rc->priv; @@ -320,7 +320,7 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type) dprintk(2, "%s\n",__func__); - ir->rc_type = *rc_type; + ir->rc_proto = *rc_proto; tm6000_ir_config(ir); /* TODO */ @@ -409,7 +409,7 @@ int tm6000_ir_init(struct tm6000_core *dev) struct tm6000_IR *ir; struct rc_dev *rc; int err = -ENOMEM; - u64 rc_type; + u64 rc_proto; if (!enable_ir) return -ENODEV; @@ -433,7 +433,7 @@ int tm6000_ir_init(struct tm6000_core *dev) ir->rc = rc; /* input setup */ - rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC; + rc->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_NEC; /* Needed, in order to support NEC remotes with 24 or 32 bits */ rc->scancode_mask = 0xffff; rc->priv = ir; @@ -455,8 +455,8 @@ int tm6000_ir_init(struct tm6000_core *dev) usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys)); - rc_type = RC_BIT_UNKNOWN; - tm6000_ir_change_protocol(rc, &rc_type); + rc_proto = RC_PROTO_BIT_UNKNOWN; + tm6000_ir_change_protocol(rc, &rc_proto); rc->device_name = ir->name; rc->input_phys = ir->phys; diff --git a/include/media/i2c/ir-kbd-i2c.h b/include/media/i2c/ir-kbd-i2c.h index d8564354debb..ac8c55617a79 100644 --- a/include/media/i2c/ir-kbd-i2c.h +++ b/include/media/i2c/ir-kbd-i2c.h @@ -20,7 +20,8 @@ struct IR_i2c { struct delayed_work work; char name[32]; char phys[32]; - int (*get_key)(struct IR_i2c *ir, enum rc_type *protocol, + int (*get_key)(struct IR_i2c *ir, + enum rc_proto *protocol, u32 *scancode, u8 *toggle); }; @@ -38,14 +39,15 @@ enum ir_kbd_get_key_fn { struct IR_i2c_init_data { char *ir_codes; const char *name; - u64 type; /* RC_BIT_RC5, etc */ + u64 type; /* RC_PROTO_BIT_RC5, etc */ u32 polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */ /* * Specify either a function pointer or a value indicating one of * ir_kbd_i2c's internal get_key functions */ - int (*get_key)(struct IR_i2c *ir, enum rc_type *protocol, + int (*get_key)(struct IR_i2c *ir, + enum rc_proto *protocol, u32 *scancode, u8 *toggle); enum ir_kbd_get_key_fn internal_get_key_func; diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 5be527ff851d..314a1edb6189 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -87,11 +87,12 @@ enum rc_filter_type { * @idle: used to keep track of RX state * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed * wakeup protocols is the set of all raw encoders - * @allowed_protocols: bitmask with the supported RC_BIT_* protocols - * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols - * @allowed_wakeup_protocols: bitmask with the supported RC_BIT_* wakeup protocols - * @wakeup_protocol: the enabled RC_TYPE_* wakeup protocol or - * RC_TYPE_UNKNOWN if disabled. + * @allowed_protocols: bitmask with the supported RC_PROTO_BIT_* protocols + * @enabled_protocols: bitmask with the enabled RC_PROTO_BIT_* protocols + * @allowed_wakeup_protocols: bitmask with the supported RC_PROTO_BIT_* wakeup + * protocols + * @wakeup_protocol: the enabled RC_PROTO_* wakeup protocol or + * RC_PROTO_UNKNOWN if disabled. * @scancode_filter: scancode filter * @scancode_wakeup_filter: scancode wakeup filters * @scancode_mask: some hardware decoders are not capable of providing the full @@ -154,7 +155,7 @@ struct rc_dev { u64 allowed_protocols; u64 enabled_protocols; u64 allowed_wakeup_protocols; - enum rc_type wakeup_protocol; + enum rc_proto wakeup_protocol; struct rc_scancode_filter scancode_filter; struct rc_scancode_filter scancode_wakeup_filter; u32 scancode_mask; @@ -165,7 +166,7 @@ struct rc_dev { unsigned long keyup_jiffies; struct timer_list timer_keyup; u32 last_keycode; - enum rc_type last_protocol; + enum rc_proto last_protocol; u32 last_scancode; u8 last_toggle; u32 timeout; @@ -173,7 +174,7 @@ struct rc_dev { u32 max_timeout; u32 rx_resolution; u32 tx_resolution; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); + int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto); int (*open)(struct rc_dev *dev); void (*close)(struct rc_dev *dev); int (*s_tx_mask)(struct rc_dev *dev, u32 mask); @@ -262,8 +263,10 @@ int rc_open(struct rc_dev *rdev); void rc_close(struct rc_dev *rdev); void rc_repeat(struct rc_dev *dev); -void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle); -void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle); +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, + u8 toggle); +void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol, + u32 scancode, u8 toggle); void rc_keyup(struct rc_dev *dev); u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode); @@ -304,7 +307,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev); void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); -int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode, +int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, struct ir_raw_event *events, unsigned int max); static inline void ir_raw_event_reset(struct rc_dev *dev) @@ -335,7 +338,7 @@ static inline u32 ir_extract_bits(u32 data, u32 mask) /* Get NEC scancode and protocol type from address and command bytes */ static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address, u8 command, u8 not_command, - enum rc_type *protocol) + enum rc_proto *protocol) { u32 scancode; @@ -347,17 +350,17 @@ static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address, address << 16 | not_command << 8 | command; - *protocol = RC_TYPE_NEC32; + *protocol = RC_PROTO_NEC32; } else if ((address ^ not_address) != 0xff) { /* Extended NEC */ scancode = address << 16 | not_address << 8 | command; - *protocol = RC_TYPE_NECX; + *protocol = RC_PROTO_NECX; } else { /* Normal NEC */ scancode = address << 8 | command; - *protocol = RC_TYPE_NEC; + *protocol = RC_PROTO_NEC; } return scancode; diff --git a/include/media/rc-map.h b/include/media/rc-map.h index c69482852f29..2a160e6e823c 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -12,113 +12,122 @@ #include /** - * enum rc_type - type of the Remote Controller protocol + * enum rc_proto - the Remote Controller protocol * - * @RC_TYPE_UNKNOWN: Protocol not known - * @RC_TYPE_OTHER: Protocol known but proprietary - * @RC_TYPE_RC5: Philips RC5 protocol - * @RC_TYPE_RC5X_20: Philips RC5x 20 bit protocol - * @RC_TYPE_RC5_SZ: StreamZap variant of RC5 - * @RC_TYPE_JVC: JVC protocol - * @RC_TYPE_SONY12: Sony 12 bit protocol - * @RC_TYPE_SONY15: Sony 15 bit protocol - * @RC_TYPE_SONY20: Sony 20 bit protocol - * @RC_TYPE_NEC: NEC protocol - * @RC_TYPE_NECX: Extended NEC protocol - * @RC_TYPE_NEC32: NEC 32 bit protocol - * @RC_TYPE_SANYO: Sanyo protocol - * @RC_TYPE_MCIR2_KBD: RC6-ish MCE keyboard - * @RC_TYPE_MCIR2_MSE: RC6-ish MCE mouse - * @RC_TYPE_RC6_0: Philips RC6-0-16 protocol - * @RC_TYPE_RC6_6A_20: Philips RC6-6A-20 protocol - * @RC_TYPE_RC6_6A_24: Philips RC6-6A-24 protocol - * @RC_TYPE_RC6_6A_32: Philips RC6-6A-32 protocol - * @RC_TYPE_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol - * @RC_TYPE_SHARP: Sharp protocol - * @RC_TYPE_XMP: XMP protocol - * @RC_TYPE_CEC: CEC protocol + * @RC_PROTO_UNKNOWN: Protocol not known + * @RC_PROTO_OTHER: Protocol known but proprietary + * @RC_PROTO_RC5: Philips RC5 protocol + * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol + * @RC_PROTO_RC5_SZ: StreamZap variant of RC5 + * @RC_PROTO_JVC: JVC protocol + * @RC_PROTO_SONY12: Sony 12 bit protocol + * @RC_PROTO_SONY15: Sony 15 bit protocol + * @RC_PROTO_SONY20: Sony 20 bit protocol + * @RC_PROTO_NEC: NEC protocol + * @RC_PROTO_NECX: Extended NEC protocol + * @RC_PROTO_NEC32: NEC 32 bit protocol + * @RC_PROTO_SANYO: Sanyo protocol + * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard + * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse + * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol + * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_PROTO_SHARP: Sharp protocol + * @RC_PROTO_XMP: XMP protocol + * @RC_PROTO_CEC: CEC protocol */ -enum rc_type { - RC_TYPE_UNKNOWN = 0, - RC_TYPE_OTHER = 1, - RC_TYPE_RC5 = 2, - RC_TYPE_RC5X_20 = 3, - RC_TYPE_RC5_SZ = 4, - RC_TYPE_JVC = 5, - RC_TYPE_SONY12 = 6, - RC_TYPE_SONY15 = 7, - RC_TYPE_SONY20 = 8, - RC_TYPE_NEC = 9, - RC_TYPE_NECX = 10, - RC_TYPE_NEC32 = 11, - RC_TYPE_SANYO = 12, - RC_TYPE_MCIR2_KBD = 13, - RC_TYPE_MCIR2_MSE = 14, - RC_TYPE_RC6_0 = 15, - RC_TYPE_RC6_6A_20 = 16, - RC_TYPE_RC6_6A_24 = 17, - RC_TYPE_RC6_6A_32 = 18, - RC_TYPE_RC6_MCE = 19, - RC_TYPE_SHARP = 20, - RC_TYPE_XMP = 21, - RC_TYPE_CEC = 22, +enum rc_proto { + RC_PROTO_UNKNOWN = 0, + RC_PROTO_OTHER = 1, + RC_PROTO_RC5 = 2, + RC_PROTO_RC5X_20 = 3, + RC_PROTO_RC5_SZ = 4, + RC_PROTO_JVC = 5, + RC_PROTO_SONY12 = 6, + RC_PROTO_SONY15 = 7, + RC_PROTO_SONY20 = 8, + RC_PROTO_NEC = 9, + RC_PROTO_NECX = 10, + RC_PROTO_NEC32 = 11, + RC_PROTO_SANYO = 12, + RC_PROTO_MCIR2_KBD = 13, + RC_PROTO_MCIR2_MSE = 14, + RC_PROTO_RC6_0 = 15, + RC_PROTO_RC6_6A_20 = 16, + RC_PROTO_RC6_6A_24 = 17, + RC_PROTO_RC6_6A_32 = 18, + RC_PROTO_RC6_MCE = 19, + RC_PROTO_SHARP = 20, + RC_PROTO_XMP = 21, + RC_PROTO_CEC = 22, }; -#define RC_BIT_NONE 0ULL -#define RC_BIT_UNKNOWN BIT_ULL(RC_TYPE_UNKNOWN) -#define RC_BIT_OTHER BIT_ULL(RC_TYPE_OTHER) -#define RC_BIT_RC5 BIT_ULL(RC_TYPE_RC5) -#define RC_BIT_RC5X_20 BIT_ULL(RC_TYPE_RC5X_20) -#define RC_BIT_RC5_SZ BIT_ULL(RC_TYPE_RC5_SZ) -#define RC_BIT_JVC BIT_ULL(RC_TYPE_JVC) -#define RC_BIT_SONY12 BIT_ULL(RC_TYPE_SONY12) -#define RC_BIT_SONY15 BIT_ULL(RC_TYPE_SONY15) -#define RC_BIT_SONY20 BIT_ULL(RC_TYPE_SONY20) -#define RC_BIT_NEC BIT_ULL(RC_TYPE_NEC) -#define RC_BIT_NECX BIT_ULL(RC_TYPE_NECX) -#define RC_BIT_NEC32 BIT_ULL(RC_TYPE_NEC32) -#define RC_BIT_SANYO BIT_ULL(RC_TYPE_SANYO) -#define RC_BIT_MCIR2_KBD BIT_ULL(RC_TYPE_MCIR2_KBD) -#define RC_BIT_MCIR2_MSE BIT_ULL(RC_TYPE_MCIR2_MSE) -#define RC_BIT_RC6_0 BIT_ULL(RC_TYPE_RC6_0) -#define RC_BIT_RC6_6A_20 BIT_ULL(RC_TYPE_RC6_6A_20) -#define RC_BIT_RC6_6A_24 BIT_ULL(RC_TYPE_RC6_6A_24) -#define RC_BIT_RC6_6A_32 BIT_ULL(RC_TYPE_RC6_6A_32) -#define RC_BIT_RC6_MCE BIT_ULL(RC_TYPE_RC6_MCE) -#define RC_BIT_SHARP BIT_ULL(RC_TYPE_SHARP) -#define RC_BIT_XMP BIT_ULL(RC_TYPE_XMP) -#define RC_BIT_CEC BIT_ULL(RC_TYPE_CEC) +#define RC_PROTO_BIT_NONE 0ULL +#define RC_PROTO_BIT_UNKNOWN BIT_ULL(RC_PROTO_UNKNOWN) +#define RC_PROTO_BIT_OTHER BIT_ULL(RC_PROTO_OTHER) +#define RC_PROTO_BIT_RC5 BIT_ULL(RC_PROTO_RC5) +#define RC_PROTO_BIT_RC5X_20 BIT_ULL(RC_PROTO_RC5X_20) +#define RC_PROTO_BIT_RC5_SZ BIT_ULL(RC_PROTO_RC5_SZ) +#define RC_PROTO_BIT_JVC BIT_ULL(RC_PROTO_JVC) +#define RC_PROTO_BIT_SONY12 BIT_ULL(RC_PROTO_SONY12) +#define RC_PROTO_BIT_SONY15 BIT_ULL(RC_PROTO_SONY15) +#define RC_PROTO_BIT_SONY20 BIT_ULL(RC_PROTO_SONY20) +#define RC_PROTO_BIT_NEC BIT_ULL(RC_PROTO_NEC) +#define RC_PROTO_BIT_NECX BIT_ULL(RC_PROTO_NECX) +#define RC_PROTO_BIT_NEC32 BIT_ULL(RC_PROTO_NEC32) +#define RC_PROTO_BIT_SANYO BIT_ULL(RC_PROTO_SANYO) +#define RC_PROTO_BIT_MCIR2_KBD BIT_ULL(RC_PROTO_MCIR2_KBD) +#define RC_PROTO_BIT_MCIR2_MSE BIT_ULL(RC_PROTO_MCIR2_MSE) +#define RC_PROTO_BIT_RC6_0 BIT_ULL(RC_PROTO_RC6_0) +#define RC_PROTO_BIT_RC6_6A_20 BIT_ULL(RC_PROTO_RC6_6A_20) +#define RC_PROTO_BIT_RC6_6A_24 BIT_ULL(RC_PROTO_RC6_6A_24) +#define RC_PROTO_BIT_RC6_6A_32 BIT_ULL(RC_PROTO_RC6_6A_32) +#define RC_PROTO_BIT_RC6_MCE BIT_ULL(RC_PROTO_RC6_MCE) +#define RC_PROTO_BIT_SHARP BIT_ULL(RC_PROTO_SHARP) +#define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) +#define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) -#define RC_BIT_ALL (RC_BIT_UNKNOWN | RC_BIT_OTHER | \ - RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | \ - RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ - RC_BIT_XMP | RC_BIT_CEC) +#define RC_PROTO_BIT_ALL \ + (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ + RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | \ + RC_PROTO_BIT_MCIR2_KBD | RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC) /* All rc protocols for which we have decoders */ -#define RC_BIT_ALL_IR_DECODER \ - (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ - RC_BIT_XMP) +#define RC_PROTO_BIT_ALL_IR_DECODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \ + RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ + RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ + RC_PROTO_BIT_XMP) -#define RC_BIT_ALL_IR_ENCODER \ - (RC_BIT_RC5 | RC_BIT_RC5X_20 | RC_BIT_RC5_SZ | \ - RC_BIT_JVC | \ - RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ - RC_BIT_SANYO | RC_BIT_MCIR2_KBD | RC_BIT_MCIR2_MSE | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | \ - RC_BIT_SHARP) +#define RC_PROTO_BIT_ALL_IR_ENCODER \ + (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ + RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \ + RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \ + RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \ + RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \ + RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \ + RC_PROTO_BIT_MCIR2_MSE | \ + RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ + RC_PROTO_BIT_RC6_6A_24 | \ + RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ + RC_PROTO_BIT_SHARP) #define RC_SCANCODE_UNKNOWN(x) (x) #define RC_SCANCODE_OTHER(x) (x) @@ -148,8 +157,8 @@ struct rc_map_table { * @size: Max number of entries * @len: Number of entries that are in use * @alloc: size of \*scan, in bytes - * @rc_type: type of the remote controller protocol, as defined at - * enum &rc_type + * @rc_proto: type of the remote controller protocol, as defined at + * enum &rc_proto * @name: name of the key map table * @lock: lock to protect access to this structure */ @@ -158,7 +167,7 @@ struct rc_map { unsigned int size; unsigned int len; unsigned int alloc; - enum rc_type rc_type; + enum rc_proto rc_proto; const char *name; spinlock_t lock; }; -- cgit v1.2.3 From c16ad5de39843e9faa02270de08feeda05850caa Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 08:59:11 -0400 Subject: media: stv0910: declare global list_head stvlist static Cleans up smatch warning: symbol 'stvlist' was not declared. Should it be static? Patch originally submitted by Colin Ian King , remainder after the merge of all other stv0910 fixes. Cc: Colin Ian King Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index d0a8ed36b899..d1ae9553f74c 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -34,7 +34,7 @@ #define BER_SRC_S 0x20 #define BER_SRC_S2 0x20 -LIST_HEAD(stvlist); +static LIST_HEAD(stvlist); enum receive_mode { RCVMODE_NONE, RCVMODE_DVBS, RCVMODE_DVBS2, RCVMODE_AUTO }; -- cgit v1.2.3 From 7112b490af28a979af82e4ba9a4be4b81182b7cd Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Sun, 20 Aug 2017 08:59:12 -0400 Subject: media: stv6111: return NULL instead of plain integer Fixes: stv6111.c:665:24: warning: Using plain integer as NULL pointer Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv6111.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c index 9a59fa318207..e3e90070e293 100644 --- a/drivers/media/dvb-frontends/stv6111.c +++ b/drivers/media/dvb-frontends/stv6111.c @@ -669,7 +669,7 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 0); if (stat < 0) { kfree(state); - return 0; + return NULL; } fe->tuner_priv = state; return fe; -- cgit v1.2.3 From 214824156cc18038beffd7ae592d2613042109a2 Mon Sep 17 00:00:00 2001 From: Jemma Denson Date: Sat, 19 Aug 2017 07:38:26 -0400 Subject: media: isl6421: add checks for current overflow This Kaffeine's BZ: https://bugs.kde.org/show_bug.cgi?id=374693 affects SkyStar S2 PCI DVB-S/S2 rev 3.3 device. It could be due to a Kernel bug. While checking the Isil 6421, comparing with its manual, available at: http://www.intersil.com/content/dam/Intersil/documents/isl6/isl6421a.pdf It was noticed that, if the output load is highly capacitive, a different approach is recomended when energizing the LNBf. Also, it is possible to detect if a current overload is happening, by checking an special flag. Add support for it. Tested on Skystar S2. Changes respect override_or option so should still work fine on cx88 based cards which disable dynamic current limit. Changes since v1: v2 - fixed incorrect checking of i2c return values v3 - fix if logic to check if dcl needs re-enabling - respect override_or values which aim to disable dcl - only do long sleep on overload if dcl enabled - add short sleep before re-enabling dcl - only check overload and potentially return EINVAL if device is on v4 - revert v3 sleep logic changes to remove tuning delays Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jemma Denson --- drivers/media/dvb-frontends/isl6421.c | 76 +++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c index 838b42771a05..3f3487887672 100644 --- a/drivers/media/dvb-frontends/isl6421.c +++ b/drivers/media/dvb-frontends/isl6421.c @@ -38,35 +38,101 @@ struct isl6421 { u8 override_and; struct i2c_adapter *i2c; u8 i2c_addr; + bool is_off; }; static int isl6421_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) { + int ret; + u8 buf; + bool is_off; struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; + struct i2c_msg msg[2] = { + { + .addr = isl6421->i2c_addr, + .flags = 0, + .buf = &isl6421->config, + .len = 1, + }, { + .addr = isl6421->i2c_addr, + .flags = I2C_M_RD, + .buf = &buf, + .len = 1, + } + + }; isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); switch(voltage) { case SEC_VOLTAGE_OFF: + is_off = true; break; case SEC_VOLTAGE_13: + is_off = false; isl6421->config |= ISL6421_EN1; break; case SEC_VOLTAGE_18: + is_off = false; isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); break; default: return -EINVAL; } + /* + * If LNBf were not powered on, disable dynamic current limit, as, + * according with datasheet, highly capacitive load on the output may + * cause a difficult start-up. + */ + if (isl6421->is_off && !is_off) + isl6421->config |= ISL6421_DCL; + isl6421->config |= isl6421->override_or; isl6421->config &= isl6421->override_and; - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; + ret = i2c_transfer(isl6421->i2c, msg, 2); + if (ret < 0) + return ret; + if (ret != 2) + return -EIO; + + /* Store off status now incase future commands fail */ + isl6421->is_off = is_off; + + /* On overflow, the device will try again after 900 ms (typically) */ + if (!is_off && (buf & ISL6421_OLF1)) + msleep(1000); + + /* Re-enable dynamic current limit */ + if ((isl6421->config & ISL6421_DCL) && + !(isl6421->override_or & ISL6421_DCL)) { + isl6421->config &= ~ISL6421_DCL; + + ret = i2c_transfer(isl6421->i2c, msg, 2); + if (ret < 0) + return ret; + if (ret != 2) + return -EIO; + } + + /* Check if overload flag is active. If so, disable power */ + if (!is_off && (buf & ISL6421_OLF1)) { + isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); + ret = i2c_transfer(isl6421->i2c, msg, 1); + if (ret < 0) + return ret; + if (ret != 1) + return -EIO; + isl6421->is_off = true; + + dev_warn(&isl6421->i2c->dev, + "Overload current detected. disabling LNBf power\n"); + return -EINVAL; + } + + return 0; } static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) @@ -148,6 +214,8 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter return NULL; } + isl6421->is_off = true; + /* install release callback */ fe->ops.release_sec = isl6421_release; -- cgit v1.2.3 From 0779b8855c746c90b85bfe6e16d5dfa2a6a46655 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Sun, 20 Aug 2017 10:17:15 -0400 Subject: media: ddbridge: fix semicolon.cocci warnings drivers/media/pci/ddbridge/ddbridge-maxs8.c:145:2-3: Unneeded semicolon drivers/media/pci/ddbridge/ddbridge-maxs8.c:173:2-3: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Fixes: a43dbe430fb4 ("media: ddbridge: support MaxLinear MXL5xx based cards (MaxS4/8)") CC: Daniel Scheller Signed-off-by: Fengguang Wu Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-maxs8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.c b/drivers/media/pci/ddbridge/ddbridge-maxs8.c index 10716ee8cf59..f8a53bc7c86c 100644 --- a/drivers/media/pci/ddbridge/ddbridge-maxs8.c +++ b/drivers/media/pci/ddbridge/ddbridge-maxs8.c @@ -142,7 +142,7 @@ static int lnb_set_tone(struct ddb *dev, u32 link, u32 input, default: s = -EINVAL; break; - }; + } if (!s) s = lnb_command(dev, link, input, LNB_CMD_NOP); return s; @@ -170,7 +170,7 @@ static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input, default: s = -EINVAL; break; - }; + } dev->link[link].lnb.oldvoltage[input] = voltage; return s; } -- cgit v1.2.3 From 152b0a9a3d62f90e6784a5d35ffc3f552f1c2c54 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Aug 2017 07:41:41 -0400 Subject: media: cec: ensure that adap_enable(false) is called from cec_delete_adapter() When the adapter is removed the cec_delete_adapter() call attempts to set the physical address to INVALID by calling __cec_s_phys_addr() and so disabling the adapter. However, __cec_s_phys_addr checks if the device node was unregistered and just returns in that case. This means that the adap_enable callback is never called with 'false' to disable the CEC adapter. Most drivers don't care, but some need to do cleanup here. Change the test so the adapter is correctly disabled, even when the device node is unregistered. Signed-off-by: Hans Verkuil Reported-by: Tomi Valkeinen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-adap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 9f8b64f2b253..dd769e40416f 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -1448,7 +1448,9 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) */ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) { - if (phys_addr == adap->phys_addr || adap->devnode.unregistered) + if (phys_addr == adap->phys_addr) + return; + if (phys_addr != CEC_PHYS_ADDR_INVALID && adap->devnode.unregistered) return; dprintk(1, "new physical address %x.%x.%x.%x\n", -- cgit v1.2.3 From 28e11b15b6606c3308f87f7c9c4c9e404eddde6d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Aug 2017 06:53:10 -0400 Subject: media: cec: replace pin->cur_value by adap->cec_pin_is_high The current CEC pin value (0 or 1) was part of the cec_pin struct, but that assumes that CEC pin monitoring can only be used with a driver that uses the low-level CEC pin framework. But hardware that has both a high-level API and can monitor the CEC pin at low-level at the same time does not need to depend on the cec pin framework. To support such devices remove the cur_value field from struct cec_pin and add a cec_pin_is_high field to cec_adapter. This also makes it possible to drop the '#ifdef CONFIG_CEC_PIN' in cec-api.c. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/cec-api.c | 6 ++---- drivers/media/cec/cec-core.c | 1 + drivers/media/cec/cec-pin.c | 5 ++--- include/media/cec-pin.h | 1 - include/media/cec.h | 1 + 5 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 87649b0c6381..a079f7fe018c 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -444,15 +444,13 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh, if (mode_follower == CEC_MODE_FOLLOWER) adap->follower_cnt++; if (mode_follower == CEC_MODE_MONITOR_PIN) { -#ifdef CONFIG_CEC_PIN struct cec_event ev = { .flags = CEC_EVENT_FL_INITIAL_STATE, }; - ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_CEC_HIGH : - CEC_EVENT_PIN_CEC_LOW; + ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH : + CEC_EVENT_PIN_CEC_LOW; cec_queue_event_fh(fh, &ev, 0); -#endif adap->monitor_pin_cnt++; } if (mode_follower == CEC_MODE_EXCL_FOLLOWER || diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index e9db90997b0a..648136e552d5 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -227,6 +227,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, return ERR_PTR(-ENOMEM); strlcpy(adap->name, name, sizeof(adap->name)); adap->phys_addr = CEC_PHYS_ADDR_INVALID; + adap->cec_pin_is_high = true; adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; adap->capabilities = caps; diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index 970774de3dcd..c003b8eac617 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -88,10 +88,10 @@ static const struct cec_state states[CEC_PIN_STATES] = { static void cec_pin_update(struct cec_pin *pin, bool v, bool force) { - if (!force && v == pin->cur_value) + if (!force && v == pin->adap->cec_pin_is_high) return; - pin->cur_value = v; + pin->adap->cec_pin_is_high = v; if (atomic_read(&pin->work_pin_events) < CEC_NUM_PIN_EVENTS) { pin->work_pin_is_high[pin->work_pin_events_wr] = v; pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); @@ -781,7 +781,6 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, if (pin == NULL) return ERR_PTR(-ENOMEM); pin->ops = pin_ops; - pin->cur_value = true; hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pin->timer.function = cec_pin_timer; init_waitqueue_head(&pin->kthread_waitq); diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h index d28d07fa312e..f09cc9579d53 100644 --- a/include/media/cec-pin.h +++ b/include/media/cec-pin.h @@ -128,7 +128,6 @@ struct cec_pin { u16 la_mask; bool enabled; bool monitor_all; - bool cur_value; bool rx_eom; bool enable_irq_failed; enum cec_pin_state state; diff --git a/include/media/cec.h b/include/media/cec.h index 60b26fc18464..df6b3bd31284 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -180,6 +180,7 @@ struct cec_adapter { bool needs_hpd; bool is_configuring; bool is_configured; + bool cec_pin_is_high; u32 monitor_all_cnt; u32 monitor_pin_cnt; u32 follower_cnt; -- cgit v1.2.3 From 4f88b0de7803240fa315025ef5ea2d85b2ca16bd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Aug 2017 07:15:25 -0400 Subject: media: vivid: add CEC pin monitoring emulation Add support to emulate CEC pin monitoring. There are few hardware devices that support this, so being able to emulate it here helps developing software for this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-cec.c | 65 +++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index 43992fa92a88..b55d278d38a7 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c @@ -22,6 +22,15 @@ #include "vivid-core.h" #include "vivid-cec.h" +#define CEC_TIM_START_BIT_TOTAL 4500 +#define CEC_TIM_START_BIT_LOW 3700 +#define CEC_TIM_START_BIT_HIGH 800 +#define CEC_TIM_DATA_BIT_TOTAL 2400 +#define CEC_TIM_DATA_BIT_0_LOW 1500 +#define CEC_TIM_DATA_BIT_0_HIGH 900 +#define CEC_TIM_DATA_BIT_1_LOW 600 +#define CEC_TIM_DATA_BIT_1_HIGH 1800 + void vivid_cec_bus_free_work(struct vivid_dev *dev) { spin_lock(&dev->cec_slock); @@ -64,6 +73,58 @@ static bool vivid_cec_find_dest_adap(struct vivid_dev *dev, return false; } +static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts, + const struct cec_msg *msg, bool nacked) +{ + unsigned int len = nacked ? 1 : msg->len; + unsigned int i; + bool bit; + + if (adap == NULL) + return; + ts = ktime_sub_us(ts, (CEC_TIM_START_BIT_TOTAL + + len * 10 * CEC_TIM_DATA_BIT_TOTAL)); + cec_queue_pin_cec_event(adap, false, ts); + ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW); + cec_queue_pin_cec_event(adap, true, ts); + ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH); + + for (i = 0; i < 10 * len; i++) { + switch (i % 10) { + case 0 ... 7: + bit = msg->msg[i / 10] & (0x80 >> (i % 10)); + break; + case 8: /* EOM */ + bit = i / 10 == msg->len - 1; + break; + case 9: /* ACK */ + bit = cec_msg_is_broadcast(msg) ^ nacked; + break; + } + cec_queue_pin_cec_event(adap, false, ts); + if (bit) + ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW); + else + ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW); + cec_queue_pin_cec_event(adap, true, ts); + if (bit) + ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH); + else + ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_HIGH); + } +} + +static void vivid_cec_pin_events(struct vivid_dev *dev, + const struct cec_msg *msg, bool nacked) +{ + ktime_t ts = ktime_get(); + unsigned int i; + + vivid_cec_pin_adap_events(dev->cec_rx_adap, ts, msg, nacked); + for (i = 0; i < MAX_OUTPUTS; i++) + vivid_cec_pin_adap_events(dev->cec_tx_adap[i], ts, msg, nacked); +} + static void vivid_cec_xfer_done_worker(struct work_struct *work) { struct vivid_cec_work *cw = @@ -84,6 +145,7 @@ static void vivid_cec_xfer_done_worker(struct work_struct *work) dev->cec_xfer_start_jiffies = 0; list_del(&cw->list); spin_unlock(&dev->cec_slock); + vivid_cec_pin_events(dev, &cw->msg, !valid_dest); cec_transmit_attempt_done(cw->adap, cw->tx_status); /* Broadcast message */ @@ -118,6 +180,7 @@ static void vivid_cec_xfer_try_worker(struct work_struct *work) static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable) { + adap->cec_pin_is_high = true; return 0; } @@ -219,7 +282,7 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, bool is_source) { char name[sizeof(dev->vid_out_dev.name) + 2]; - u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN; snprintf(name, sizeof(name), "%s%d", is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name, -- cgit v1.2.3 From b0704f8541af36b21483bc1ea639da248ff429d7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Aug 2017 07:39:42 -0400 Subject: media: vivid: fix incorrect HDMI input/output CEC logging Only the first HDMI input has a CEC adapter, so just report 'HDMI 0' as the HDMI input name. For the HDMI outputs use bus_cnt instead of i as the output number. The HDMI name now corresponds to what 'v4l2-ctl --list-outputs' reports. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vivid/vivid-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index ef344b9a48af..5f316a5e38db 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -1201,8 +1201,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) goto unreg_dev; } cec_s_phys_addr(adap, 0, false); - v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input %d\n", - dev_name(&adap->devnode.dev), i); + v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI input 0\n", + dev_name(&adap->devnode.dev)); } #endif @@ -1255,13 +1255,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) dev->cec_tx_adap[bus_cnt] = NULL; goto unreg_dev; } + v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n", + dev_name(&adap->devnode.dev), bus_cnt); bus_cnt++; if (bus_cnt <= out_type_counter[HDMI]) cec_s_phys_addr(adap, bus_cnt << 12, false); else cec_s_phys_addr(adap, 0x1000, false); - v4l2_info(&dev->v4l2_dev, "CEC adapter %s registered for HDMI output %d\n", - dev_name(&adap->devnode.dev), i); } #endif -- cgit v1.2.3 From c06f6be6a7fd894204dea60f1d5fdb243f9a5138 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Aug 2017 06:41:54 -0400 Subject: media: stih-cec: use CEC_CAP_DEFAULTS Use the new CEC_CAP_DEFAULTS define in this driver. This also adds the CEC_CAP_RC capability which was missing here (and this is also the reason for this new define, to avoid missing such capabilities). Signed-off-by: Hans Verkuil Acked-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/cec/stih-cec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c index dccbdaebb7a8..70160df36de9 100644 --- a/drivers/media/platform/sti/cec/stih-cec.c +++ b/drivers/media/platform/sti/cec/stih-cec.c @@ -351,9 +351,7 @@ static int stih_cec_probe(struct platform_device *pdev) } cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, - CEC_NAME, - CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | - CEC_CAP_TRANSMIT, CEC_MAX_LOG_ADDRS); + CEC_NAME, CEC_CAP_DEFAULTS, CEC_MAX_LOG_ADDRS); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; -- cgit v1.2.3 From 43298e768cfc2b9c810e55425e948bf6f767cc75 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 4 Aug 2017 06:41:55 -0400 Subject: media: stm32-cec: use CEC_CAP_DEFAULTS Use the new CEC_CAP_DEFAULTS define in this driver. Signed-off-by: Hans Verkuil Acked-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-cec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c index 9ab896b01ee8..0e5aa17bdd40 100644 --- a/drivers/media/platform/stm32/stm32-cec.c +++ b/drivers/media/platform/stm32/stm32-cec.c @@ -246,9 +246,7 @@ static const struct regmap_config stm32_cec_regmap_cfg = { static int stm32_cec_probe(struct platform_device *pdev) { - u32 caps = CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH | - CEC_CAP_TRANSMIT | CEC_CAP_RC | CEC_CAP_PHYS_ADDR | - CEC_MODE_MONITOR_ALL; + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL; struct resource *res; struct stm32_cec *cec; void __iomem *mmio; -- cgit v1.2.3 From d746cf89b4b7e60f5b7239b3ef8e8af01d11f604 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Fri, 18 Aug 2017 12:06:58 -0400 Subject: media: usb: make i2c_algorithm const Make these const as they are only used in a copy operation or are stored in the algo field of i2c_adapter structure, which is const. Signed-off-by: Bhumika Goyal Acked-by: Mike Isely Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-i2c.c | 2 +- drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c index 42b352bb4f02..a028e3682d1c 100644 --- a/drivers/media/usb/au0828/au0828-i2c.c +++ b/drivers/media/usb/au0828/au0828-i2c.c @@ -329,7 +329,7 @@ static u32 au0828_functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } -static struct i2c_algorithm au0828_i2c_algo_template = { +static const struct i2c_algorithm au0828_i2c_algo_template = { .master_xfer = i2c_xfer, .functionality = au0828_functionality, }; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c index e3c8f9414e45..694dc75ce89b 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c @@ -514,7 +514,7 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; } -static struct i2c_algorithm pvr2_i2c_algo_template = { +static const struct i2c_algorithm pvr2_i2c_algo_template = { .master_xfer = pvr2_i2c_xfer, .functionality = pvr2_i2c_functionality, }; -- cgit v1.2.3 From ea9b0f31c1acd35b6905dbfa7dd19c01592470f6 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 19 Aug 2017 04:22:14 -0400 Subject: media: i2c: make device_type const Make this const as it is only stored in the type field of a device structure, which is const. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/soc_camera/mt9t031.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 714fb3555b34..4802d30e47de 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -592,7 +592,7 @@ static const struct dev_pm_ops mt9t031_dev_pm_ops = { .runtime_resume = mt9t031_runtime_resume, }; -static struct device_type mt9t031_dev_type = { +static const struct device_type mt9t031_dev_type = { .name = "MT9T031", .pm = &mt9t031_dev_pm_ops, }; -- cgit v1.2.3 From e5fffebe6d39cf8ad0a7628822d9c3a519523135 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 19 Aug 2017 06:34:13 -0400 Subject: media: pci: make i2c_adapter const Make these const as they are only used in a copy operation. Done using Coccinelle Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-i2c.c | 2 +- drivers/media/pci/cx18/cx18-i2c.c | 2 +- drivers/media/pci/cx23885/cx23885-i2c.c | 2 +- drivers/media/pci/cx25821/cx25821-i2c.c | 2 +- drivers/media/pci/ivtv/ivtv-i2c.c | 4 ++-- drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c | 2 +- drivers/media/pci/saa7134/saa7134-i2c.c | 2 +- drivers/media/pci/saa7164/saa7164-i2c.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cobalt/cobalt-i2c.c b/drivers/media/pci/cobalt/cobalt-i2c.c index ad16b89b8d0c..1a5c55673ea8 100644 --- a/drivers/media/pci/cobalt/cobalt-i2c.c +++ b/drivers/media/pci/cobalt/cobalt-i2c.c @@ -301,7 +301,7 @@ static u32 cobalt_func(struct i2c_adapter *adap) } /* template for i2c-bit-algo */ -static struct i2c_adapter cobalt_i2c_adap_template = { +static const struct i2c_adapter cobalt_i2c_adap_template = { .name = "cobalt i2c driver", .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c index b89fbcbfb491..af56d56eae08 100644 --- a/drivers/media/pci/cx18/cx18-i2c.c +++ b/drivers/media/pci/cx18/cx18-i2c.c @@ -206,7 +206,7 @@ static int cx18_getsda(void *data) } /* template for i2c-bit-algo */ -static struct i2c_adapter cx18_i2c_adap_template = { +static const struct i2c_adapter cx18_i2c_adap_template = { .name = "cx18 i2c driver", .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c index 8528032090f2..0f21467ae88e 100644 --- a/drivers/media/pci/cx23885/cx23885-i2c.c +++ b/drivers/media/pci/cx23885/cx23885-i2c.c @@ -264,7 +264,7 @@ static const struct i2c_algorithm cx23885_i2c_algo_template = { /* ----------------------------------------------------------------------- */ -static struct i2c_adapter cx23885_i2c_adap_template = { +static const struct i2c_adapter cx23885_i2c_adap_template = { .name = "cx23885", .owner = THIS_MODULE, .algo = &cx23885_i2c_algo_template, diff --git a/drivers/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c index 263a1cf36ef1..000049d3c71b 100644 --- a/drivers/media/pci/cx25821/cx25821-i2c.c +++ b/drivers/media/pci/cx25821/cx25821-i2c.c @@ -285,7 +285,7 @@ static const struct i2c_algorithm cx25821_i2c_algo_template = { #endif }; -static struct i2c_adapter cx25821_i2c_adap_template = { +static const struct i2c_adapter cx25821_i2c_adap_template = { .name = "cx25821", .owner = THIS_MODULE, .algo = &cx25821_i2c_algo_template, diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c index 69b4fa6f0362..5a35e366f4c0 100644 --- a/drivers/media/pci/ivtv/ivtv-i2c.c +++ b/drivers/media/pci/ivtv/ivtv-i2c.c @@ -632,7 +632,7 @@ static const struct i2c_algorithm ivtv_algo = { }; /* template for our-bit banger */ -static struct i2c_adapter ivtv_i2c_adap_hw_template = { +static const struct i2c_adapter ivtv_i2c_adap_hw_template = { .name = "ivtv i2c driver", .algo = &ivtv_algo, .algo_data = NULL, /* filled from template */ @@ -682,7 +682,7 @@ static int ivtv_getsda_old(void *data) } /* template for i2c-bit-algo */ -static struct i2c_adapter ivtv_i2c_adap_template = { +static const struct i2c_adapter ivtv_i2c_adap_template = { .name = "ivtv i2c driver", .algo = NULL, /* set by i2c-algo-bit */ .algo_data = NULL, /* filled from template */ diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c b/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c index b49e4f9788e8..b13e319d24b7 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_i2c.c @@ -300,7 +300,7 @@ static const struct i2c_algorithm netup_i2c_algorithm = { .functionality = netup_i2c_func, }; -static struct i2c_adapter netup_i2c_adapter = { +static const struct i2c_adapter netup_i2c_adapter = { .owner = THIS_MODULE, .name = NETUP_UNIDVB_NAME, .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index 9d0e69eae036..8f2ed632840f 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -339,7 +339,7 @@ static const struct i2c_algorithm saa7134_algo = { .functionality = functionality, }; -static struct i2c_adapter saa7134_adap_template = { +static const struct i2c_adapter saa7134_adap_template = { .owner = THIS_MODULE, .name = "saa7134", .algo = &saa7134_algo, diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c index 430f6789f222..4bcde7c79dc3 100644 --- a/drivers/media/pci/saa7164/saa7164-i2c.c +++ b/drivers/media/pci/saa7164/saa7164-i2c.c @@ -78,7 +78,7 @@ static const struct i2c_algorithm saa7164_i2c_algo_template = { /* ----------------------------------------------------------------------- */ -static struct i2c_adapter saa7164_i2c_adap_template = { +static const struct i2c_adapter saa7164_i2c_adap_template = { .name = "saa7164", .owner = THIS_MODULE, .algo = &saa7164_i2c_algo_template, -- cgit v1.2.3 From 9a5c43b3d22f17125044f17256a125d2bd13559d Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 19 Aug 2017 06:34:14 -0400 Subject: media: radio-usb-si4713: make i2c_adapter const Make this const as it is only used in a copy operation. Done using Coccinelle Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/radio-usb-si4713.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c index febc9c1e78ff..a115db24667b 100644 --- a/drivers/media/radio/si4713/radio-usb-si4713.c +++ b/drivers/media/radio/si4713/radio-usb-si4713.c @@ -409,7 +409,7 @@ static const struct i2c_algorithm si4713_algo = { /* This name value shows up in the sysfs filename associated with this I2C adapter */ -static struct i2c_adapter si4713_i2c_adapter_template = { +static const struct i2c_adapter si4713_i2c_adapter_template = { .name = "si4713-i2c", .owner = THIS_MODULE, .algo = &si4713_algo, -- cgit v1.2.3 From 6843868fd092406b544064e4db1ca902af13cf48 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 19 Aug 2017 06:34:15 -0400 Subject: media: usb: make i2c_adapter const Make these const as they are only used in a copy operation. Done using Coccinelle Signed-off-by: Bhumika Goyal Acked-by: Mike Isely Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-i2c.c | 2 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 2 +- drivers/media/usb/em28xx/em28xx-i2c.c | 2 +- drivers/media/usb/hdpvr/hdpvr-i2c.c | 2 +- drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c | 2 +- drivers/media/usb/stk1160/stk1160-i2c.c | 2 +- drivers/media/usb/usbvision/usbvision-i2c.c | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c index a028e3682d1c..ef7d1b830ca3 100644 --- a/drivers/media/usb/au0828/au0828-i2c.c +++ b/drivers/media/usb/au0828/au0828-i2c.c @@ -336,7 +336,7 @@ static const struct i2c_algorithm au0828_i2c_algo_template = { /* ----------------------------------------------------------------------- */ -static struct i2c_adapter au0828_i2c_adap_template = { +static const struct i2c_adapter au0828_i2c_adap_template = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, .algo = &au0828_i2c_algo_template, diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 8ce6b815d16d..23648dab7be8 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -459,7 +459,7 @@ static const struct i2c_algorithm cx231xx_algo = { .functionality = functionality, }; -static struct i2c_adapter cx231xx_adap_template = { +static const struct i2c_adapter cx231xx_adap_template = { .owner = THIS_MODULE, .name = "cx231xx", .algo = &cx231xx_algo, diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 60b195c157b8..66c5012a628a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -876,7 +876,7 @@ static const struct i2c_algorithm em28xx_algo = { .functionality = functionality, }; -static struct i2c_adapter em28xx_adap_template = { +static const struct i2c_adapter em28xx_adap_template = { .owner = THIS_MODULE, .name = "em28xx", .algo = &em28xx_algo, diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c index b9074b978ae3..1db49ed5eaf1 100644 --- a/drivers/media/usb/hdpvr/hdpvr-i2c.c +++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c @@ -185,7 +185,7 @@ static const struct i2c_algorithm hdpvr_algo = { .functionality = hdpvr_functionality, }; -static struct i2c_adapter hdpvr_i2c_adapter_template = { +static const struct i2c_adapter hdpvr_i2c_adapter_template = { .name = "Hauppage HD PVR I2C", .owner = THIS_MODULE, .algo = &hdpvr_algo, diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c index 694dc75ce89b..ff7b4d1d385d 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c @@ -519,7 +519,7 @@ static const struct i2c_algorithm pvr2_i2c_algo_template = { .functionality = pvr2_i2c_functionality, }; -static struct i2c_adapter pvr2_i2c_adap_template = { +static const struct i2c_adapter pvr2_i2c_adap_template = { .owner = THIS_MODULE, .class = 0, }; diff --git a/drivers/media/usb/stk1160/stk1160-i2c.c b/drivers/media/usb/stk1160/stk1160-i2c.c index 3f2517be02bb..2c70173e3c82 100644 --- a/drivers/media/usb/stk1160/stk1160-i2c.c +++ b/drivers/media/usb/stk1160/stk1160-i2c.c @@ -240,7 +240,7 @@ static const struct i2c_algorithm algo = { .functionality = functionality, }; -static struct i2c_adapter adap_template = { +static const struct i2c_adapter adap_template = { .owner = THIS_MODULE, .name = "stk1160", .algo = &algo, diff --git a/drivers/media/usb/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c index 68acafb6bb95..837bd4d9db41 100644 --- a/drivers/media/usb/usbvision/usbvision-i2c.c +++ b/drivers/media/usb/usbvision/usbvision-i2c.c @@ -173,7 +173,7 @@ static const struct i2c_algorithm usbvision_algo = { /* ----------------------------------------------------------------------- */ /* usbvision specific I2C functions */ /* ----------------------------------------------------------------------- */ -static struct i2c_adapter i2c_adap_template; +static const struct i2c_adapter i2c_adap_template; int usbvision_i2c_register(struct usb_usbvision *usbvision) { @@ -441,7 +441,7 @@ static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char add return rdcount; } -static struct i2c_adapter i2c_adap_template = { +static const struct i2c_adapter i2c_adap_template = { .owner = THIS_MODULE, .name = "usbvision", }; -- cgit v1.2.3 From 99b1ddf94d2b25fdfac5d0989a08228870bd4e00 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:42 -0400 Subject: media: ad9389b: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ad9389b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index 50f354144ee7..a056d6cdaaaa 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -1208,7 +1208,7 @@ static int ad9389b_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -static struct i2c_device_id ad9389b_id[] = { +static const struct i2c_device_id ad9389b_id[] = { { "ad9389b", 0 }, { "ad9889b", 0 }, { } -- cgit v1.2.3 From 4bd7466bf73a3b2e7a0308eb510a9746a84ab7dd Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:43 -0400 Subject: media: adv7511: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7511.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index aef02c994df9..2817bafc67bf 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -1985,7 +1985,7 @@ static int adv7511_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -static struct i2c_device_id adv7511_id[] = { +static const struct i2c_device_id adv7511_id[] = { { "adv7511", 0 }, { } }; -- cgit v1.2.3 From 77c6cba38575beba4247c2b3f39cb562fc3a51d1 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:44 -0400 Subject: media: adv7842: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 1bf6129fab62..65f34e7e146f 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3607,7 +3607,7 @@ static int adv7842_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -static struct i2c_device_id adv7842_id[] = { +static const struct i2c_device_id adv7842_id[] = { { "adv7842", 0 }, { } }; -- cgit v1.2.3 From e749d1f1cebb2ad9af01e744bad1d16194146fbd Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:45 -0400 Subject: media: saa7127: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/saa7127.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c index 99c303002e90..01784d441ae6 100644 --- a/drivers/media/i2c/saa7127.c +++ b/drivers/media/i2c/saa7127.c @@ -806,7 +806,7 @@ static int saa7127_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -static struct i2c_device_id saa7127_id[] = { +static const struct i2c_device_id saa7127_id[] = { { "saa7127_auto", 0 }, /* auto-detection */ { "saa7126", SAA7127 }, { "saa7127", SAA7127 }, -- cgit v1.2.3 From 2f8dfed83c825b510c6912a3c2e6540ae8e9f27b Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:46 -0400 Subject: media: tc358743: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tc358743.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 5788af238b86..e6f5c363ccab 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2013,7 +2013,7 @@ static int tc358743_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id tc358743_id[] = { +static const struct i2c_device_id tc358743_id[] = { {"tc358743", 0}, {} }; -- cgit v1.2.3 From e0ee62c49fdd8f6780abcc980c4b24e05e3a0af3 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sat, 19 Aug 2017 15:20:47 -0400 Subject: media: ths8200: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ths8200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 42340e364cea..498ad2368cbc 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -483,7 +483,7 @@ static int ths8200_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id ths8200_id[] = { +static const struct i2c_device_id ths8200_id[] = { { "ths8200", 0 }, {}, }; -- cgit v1.2.3 From 62d625c93ca1f6d3a36ea803a37f34b7d5ae82ce Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:02 -0400 Subject: media: venus: mark venc and vdec PM functions as __maybe_unused Without PM support gcc could warns about unused functions, thus mark runtime_suspend/resume as __maybe_unused. Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/vdec.c | 6 ++---- drivers/media/platform/qcom/venus/venc.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index eb0c1c51cfef..44d4848e878a 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1103,8 +1103,7 @@ static int vdec_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int vdec_runtime_suspend(struct device *dev) +static __maybe_unused int vdec_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); @@ -1118,7 +1117,7 @@ static int vdec_runtime_suspend(struct device *dev) return 0; } -static int vdec_runtime_resume(struct device *dev) +static __maybe_unused int vdec_runtime_resume(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); int ret; @@ -1132,7 +1131,6 @@ static int vdec_runtime_resume(struct device *dev) return ret; } -#endif static const struct dev_pm_ops vdec_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 39748e7a08e4..3f79da018402 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1224,8 +1224,7 @@ static int venc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int venc_runtime_suspend(struct device *dev) +static __maybe_unused int venc_runtime_suspend(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); @@ -1239,7 +1238,7 @@ static int venc_runtime_suspend(struct device *dev) return 0; } -static int venc_runtime_resume(struct device *dev) +static __maybe_unused int venc_runtime_resume(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); int ret; @@ -1253,7 +1252,6 @@ static int venc_runtime_resume(struct device *dev) return ret; } -#endif static const struct dev_pm_ops venc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -- cgit v1.2.3 From 5c2c165905026a8ec2779710e5fe63d8086587e1 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:03 -0400 Subject: media: venus: fill missing video_device name This fills missing (forgotten) video device name with appropriate string so that udev can distinguishes between decoder and encoder devices. Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/vdec.c | 1 + drivers/media/platform/qcom/venus/venc.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 44d4848e878a..32a1feb2fe6a 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1069,6 +1069,7 @@ static int vdec_probe(struct platform_device *pdev) if (!vdev) return -ENOMEM; + strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name)); vdev->release = video_device_release; vdev->fops = &vdec_fops; vdev->ioctl_ops = &vdec_ioctl_ops; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 3f79da018402..7eb346869d28 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1190,6 +1190,7 @@ static int venc_probe(struct platform_device *pdev) if (!vdev) return -ENOMEM; + strlcpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); vdev->release = video_device_release; vdev->fops = &venc_fops; vdev->ioctl_ops = &venc_ioctl_ops; -- cgit v1.2.3 From d8db57c26f1c9bf7de3f6bf462a78cc555d9d390 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:04 -0400 Subject: media: venus: add helper to check supported codecs Adds a helper function to runtime check supported encoder and decoder codecs depending on venus version and platform. Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/helpers.c | 49 +++++++++++++++++++++++++++++ drivers/media/platform/qcom/venus/helpers.h | 1 + 2 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 5f4434c0a8f1..b52410deeb4c 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -34,6 +34,55 @@ struct intbuf { unsigned long attrs; }; +bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) +{ + struct venus_core *core = inst->core; + u32 session_type = inst->session_type; + u32 codec; + + switch (v4l2_pixfmt) { + case V4L2_PIX_FMT_H264: + codec = HFI_VIDEO_CODEC_H264; + break; + case V4L2_PIX_FMT_H263: + codec = HFI_VIDEO_CODEC_H263; + break; + case V4L2_PIX_FMT_MPEG1: + codec = HFI_VIDEO_CODEC_MPEG1; + break; + case V4L2_PIX_FMT_MPEG2: + codec = HFI_VIDEO_CODEC_MPEG2; + break; + case V4L2_PIX_FMT_MPEG4: + codec = HFI_VIDEO_CODEC_MPEG4; + break; + case V4L2_PIX_FMT_VC1_ANNEX_G: + case V4L2_PIX_FMT_VC1_ANNEX_L: + codec = HFI_VIDEO_CODEC_VC1; + break; + case V4L2_PIX_FMT_VP8: + codec = HFI_VIDEO_CODEC_VP8; + break; + case V4L2_PIX_FMT_VP9: + codec = HFI_VIDEO_CODEC_VP9; + break; + case V4L2_PIX_FMT_XVID: + codec = HFI_VIDEO_CODEC_DIVX; + break; + default: + return false; + } + + if (session_type == VIDC_SESSION_TYPE_ENC && core->enc_codecs & codec) + return true; + + if (session_type == VIDC_SESSION_TYPE_DEC && core->dec_codecs & codec) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(venus_helper_check_codec); + static int intbufs_set_buffer(struct venus_inst *inst, u32 type) { struct venus_core *core = inst->core; diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 6a061b417a93..971392be5df5 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -19,6 +19,7 @@ struct venus_inst; +bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt); struct vb2_v4l2_buffer *venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx); void venus_helper_buffers_done(struct venus_inst *inst, -- cgit v1.2.3 From 29f0133ec66c3e49a80fdf362be71482d45684f3 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:05 -0400 Subject: media: venus: use helper function to check supported codecs Use the helper function in decoder and encoder find_format to runtime check supported codecs. Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/vdec.c | 24 +++++++++++++++++------- drivers/media/platform/qcom/venus/venc.c | 28 +++++++++++++++++++--------- 2 files changed, 36 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 32a1feb2fe6a..da611a5eb670 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -102,7 +102,8 @@ static const struct venus_format vdec_formats[] = { }, }; -static const struct venus_format *find_format(u32 pixfmt, u32 type) +static const struct venus_format * +find_format(struct venus_inst *inst, u32 pixfmt, u32 type) { const struct venus_format *fmt = vdec_formats; unsigned int size = ARRAY_SIZE(vdec_formats); @@ -116,11 +117,15 @@ static const struct venus_format *find_format(u32 pixfmt, u32 type) if (i == size || fmt[i].type != type) return NULL; + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + !venus_helper_check_codec(inst, fmt[i].pixfmt)) + return NULL; + return &fmt[i]; } static const struct venus_format * -find_format_by_index(unsigned int index, u32 type) +find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) { const struct venus_format *fmt = vdec_formats; unsigned int size = ARRAY_SIZE(vdec_formats); @@ -140,6 +145,10 @@ find_format_by_index(unsigned int index, u32 type) if (i == size) return NULL; + if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + !venus_helper_check_codec(inst, fmt[i].pixfmt)) + return NULL; + return &fmt[i]; } @@ -154,7 +163,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); - fmt = find_format(pixmp->pixelformat, f->type); + fmt = find_format(inst, pixmp->pixelformat, f->type); if (!fmt) { if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) pixmp->pixelformat = V4L2_PIX_FMT_NV12; @@ -162,7 +171,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) pixmp->pixelformat = V4L2_PIX_FMT_H264; else return NULL; - fmt = find_format(pixmp->pixelformat, f->type); + fmt = find_format(inst, pixmp->pixelformat, f->type); pixmp->width = 1280; pixmp->height = 720; } @@ -364,11 +373,12 @@ vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) { + struct venus_inst *inst = to_inst(file); const struct venus_format *fmt; memset(f->reserved, 0, sizeof(f->reserved)); - fmt = find_format_by_index(f->index, f->type); + fmt = find_format_by_index(inst, f->index, f->type); if (!fmt) return -EINVAL; @@ -417,10 +427,10 @@ static int vdec_enum_framesizes(struct file *file, void *fh, struct venus_inst *inst = to_inst(file); const struct venus_format *fmt; - fmt = find_format(fsize->pixel_format, + fmt = find_format(inst, fsize->pixel_format, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (!fmt) { - fmt = find_format(fsize->pixel_format, + fmt = find_format(inst, fsize->pixel_format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!fmt) return -EINVAL; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 7eb346869d28..dc66fe664cd6 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -91,7 +91,8 @@ static const struct venus_format venc_formats[] = { }, }; -static const struct venus_format *find_format(u32 pixfmt, u32 type) +static const struct venus_format * +find_format(struct venus_inst *inst, u32 pixfmt, u32 type) { const struct venus_format *fmt = venc_formats; unsigned int size = ARRAY_SIZE(venc_formats); @@ -105,11 +106,15 @@ static const struct venus_format *find_format(u32 pixfmt, u32 type) if (i == size || fmt[i].type != type) return NULL; + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + !venus_helper_check_codec(inst, fmt[i].pixfmt)) + return NULL; + return &fmt[i]; } static const struct venus_format * -find_format_by_index(unsigned int index, u32 type) +find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) { const struct venus_format *fmt = venc_formats; unsigned int size = ARRAY_SIZE(venc_formats); @@ -129,6 +134,10 @@ find_format_by_index(unsigned int index, u32 type) if (i == size) return NULL; + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + !venus_helper_check_codec(inst, fmt[i].pixfmt)) + return NULL; + return &fmt[i]; } @@ -246,9 +255,10 @@ venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) { + struct venus_inst *inst = to_inst(file); const struct venus_format *fmt; - fmt = find_format_by_index(f->index, f->type); + fmt = find_format_by_index(inst, f->index, f->type); memset(f->reserved, 0, sizeof(f->reserved)); @@ -271,7 +281,7 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); - fmt = find_format(pixmp->pixelformat, f->type); + fmt = find_format(inst, pixmp->pixelformat, f->type); if (!fmt) { if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) pixmp->pixelformat = V4L2_PIX_FMT_H264; @@ -279,7 +289,7 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) pixmp->pixelformat = V4L2_PIX_FMT_NV12; else return NULL; - fmt = find_format(pixmp->pixelformat, f->type); + fmt = find_format(inst, pixmp->pixelformat, f->type); pixmp->width = 1280; pixmp->height = 720; } @@ -524,10 +534,10 @@ static int venc_enum_framesizes(struct file *file, void *fh, fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fmt = find_format(fsize->pixel_format, + fmt = find_format(inst, fsize->pixel_format, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (!fmt) { - fmt = find_format(fsize->pixel_format, + fmt = find_format(inst, fsize->pixel_format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!fmt) return -EINVAL; @@ -554,10 +564,10 @@ static int venc_enum_frameintervals(struct file *file, void *fh, fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; - fmt = find_format(fival->pixel_format, + fmt = find_format(inst, fival->pixel_format, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (!fmt) { - fmt = find_format(fival->pixel_format, + fmt = find_format(inst, fival->pixel_format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!fmt) return -EINVAL; -- cgit v1.2.3 From b1540ceaed8d62270490d4efd35adcc5ba2d595e Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:06 -0400 Subject: media: venus: venc: drop VP9 codec support No one of the supported Venus version has implemented VP9 codec for enconding, so drop it from the list of codecs. Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/venc.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index dc66fe664cd6..20a3daa82492 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -84,10 +84,6 @@ static const struct venus_format venc_formats[] = { .pixfmt = V4L2_PIX_FMT_VP8, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, - }, { - .pixfmt = V4L2_PIX_FMT_VP9, - .num_planes = 1, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, }, }; -- cgit v1.2.3 From c2bc8b06ca48e72c6a9bf0de65f9a636f714af7a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 15 Aug 2017 05:06:59 -0400 Subject: media: dw9714: Add Devicetree support Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/dw9714.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index 6a607d7f82de..bcf64ef8ad29 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -264,6 +264,12 @@ static const struct i2c_device_id dw9714_id_table[] = { MODULE_DEVICE_TABLE(i2c, dw9714_id_table); +static const struct of_device_id dw9714_of_table[] = { + { .compatible = "dongwoon,dw9714" }, + { { 0 } } +}; +MODULE_DEVICE_TABLE(of, dw9714_of_table); + static const struct dev_pm_ops dw9714_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume) SET_RUNTIME_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume, NULL) @@ -274,6 +280,7 @@ static struct i2c_driver dw9714_i2c_driver = { .name = DW9714_NAME, .pm = &dw9714_pm_ops, .acpi_match_table = ACPI_PTR(dw9714_acpi_match), + .of_match_table = dw9714_of_table, }, .probe = dw9714_probe, .remove = dw9714_remove, -- cgit v1.2.3 From f758eb2363ecf91adf17dbd1864691819dd3c060 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 15 Aug 2017 05:08:52 -0400 Subject: media: dw9714: Remove ACPI match tables, convert to use probe_new The ACPI match table is empty. Remove it. Also convert the drive to use probe_new callback in struct i2c_driver. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/dw9714.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index bcf64ef8ad29..95af4fc99cd0 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -11,7 +11,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -147,8 +146,7 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm) return hdl->error; } -static int dw9714_probe(struct i2c_client *client, - const struct i2c_device_id *devid) +static int dw9714_probe(struct i2c_client *client) { struct dw9714_device *dw9714_dev; int rval; @@ -250,18 +248,10 @@ static int __maybe_unused dw9714_vcm_resume(struct device *dev) return 0; } -#ifdef CONFIG_ACPI -static const struct acpi_device_id dw9714_acpi_match[] = { - {}, -}; -MODULE_DEVICE_TABLE(acpi, dw9714_acpi_match); -#endif - static const struct i2c_device_id dw9714_id_table[] = { - {DW9714_NAME, 0}, - {} + { DW9714_NAME, 0 }, + { { 0 } } }; - MODULE_DEVICE_TABLE(i2c, dw9714_id_table); static const struct of_device_id dw9714_of_table[] = { @@ -279,10 +269,9 @@ static struct i2c_driver dw9714_i2c_driver = { .driver = { .name = DW9714_NAME, .pm = &dw9714_pm_ops, - .acpi_match_table = ACPI_PTR(dw9714_acpi_match), .of_match_table = dw9714_of_table, }, - .probe = dw9714_probe, + .probe_new = dw9714_probe, .remove = dw9714_remove, .id_table = dw9714_id_table, }; -- cgit v1.2.3 From b24f021579c5384ea9ba22decec84e757d5fbd09 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 14 Aug 2017 06:15:21 -0400 Subject: media: v4l: fwnode: Fix lane-polarities property parsing fwnode_property_read_u32_array() only returns the number of array elements if the array argument is NULL. The assumption that it always did so lead to lane-polarities properties never being read. Fixes: 4ee236219f6d ("media: v4l2-fwnode: suppress a warning at OF parsing logic") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 5cd2687310fe..3f8eed008700 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -65,19 +65,23 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, } rval = fwnode_property_read_u32_array(fwnode, - "lane-polarities", array, - 1 + bus->num_data_lanes); + "lane-polarities", NULL, + 0); if (rval > 0) { - if (rval != 1 + bus->num_data_lanes /* clock + data */) { + if (rval != 1 + bus->num_data_lanes /* clock+data */) { pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", 1 + bus->num_data_lanes, rval); return -EINVAL; } + fwnode_property_read_u32_array(fwnode, + "lane-polarities", array, + 1 + bus->num_data_lanes); for (i = 0; i < 1 + bus->num_data_lanes; i++) bus->lane_polarities[i] = array[i]; } + } if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { -- cgit v1.2.3 From 1526c704b3c32640b5e6cdc1662b0698603e9d4f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 14 Aug 2017 06:22:14 -0400 Subject: media: v4l: fwnode: The clock lane is the first lane in lane_polarities The clock lane is the first lane in the lane_polarities array. Reflect this consistently by putting the number of data lanes after the number of clock lanes. Fixes: 4ee236219f6d ("media: v4l2-fwnode: suppress a warning at OF parsing logic") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 2 +- include/media/v4l2-fwnode.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 3f8eed008700..df7169b5ed8c 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -48,7 +48,7 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); if (rval > 0) { - u32 array[MAX_DATA_LANES + 1]; + u32 array[1 + MAX_DATA_LANES]; bus->num_data_lanes = min_t(int, MAX_DATA_LANES, rval); diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index cb34dcb0bb65..08e743fb7944 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -42,7 +42,7 @@ struct v4l2_fwnode_bus_mipi_csi2 { unsigned char data_lanes[MAX_DATA_LANES]; unsigned char clock_lane; unsigned short num_data_lanes; - bool lane_polarities[MAX_DATA_LANES + 1]; + bool lane_polarities[1 + MAX_DATA_LANES]; }; /** -- cgit v1.2.3 From ad3cdf3e1f37299fc1422f7828243635249a3dde Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 14 Aug 2017 06:43:07 -0400 Subject: media: v4l: fwnode: Use a less clash-prone name for MAX_DATA_LANES macro Avoid using a generic name such as MAX_DATA_LANES in a header file widely included in drivers. Instead, call it V4L2_FWNODE_CSI2_MAX_DATA_LANES. Fixes: 4ee236219f6d ("media: v4l2-fwnode: suppress a warning at OF parsing logic") Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fwnode.c | 5 +++-- include/media/v4l2-fwnode.h | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index df7169b5ed8c..40b2fbfe8865 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -48,9 +48,10 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); if (rval > 0) { - u32 array[1 + MAX_DATA_LANES]; + u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES]; - bus->num_data_lanes = min_t(int, MAX_DATA_LANES, rval); + bus->num_data_lanes = + min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval); fwnode_property_read_u32_array(fwnode, "data-lanes", array, bus->num_data_lanes); diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 08e743fb7944..7adec9851d9e 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -26,7 +26,7 @@ struct fwnode_handle; -#define MAX_DATA_LANES 4 +#define V4L2_FWNODE_CSI2_MAX_DATA_LANES 4 /** * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure @@ -39,10 +39,10 @@ struct fwnode_handle; */ struct v4l2_fwnode_bus_mipi_csi2 { unsigned int flags; - unsigned char data_lanes[MAX_DATA_LANES]; + unsigned char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES]; unsigned char clock_lane; unsigned short num_data_lanes; - bool lane_polarities[1 + MAX_DATA_LANES]; + bool lane_polarities[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES]; }; /** -- cgit v1.2.3 From 134e15e6815921cb6db4fa6a0453df3441989fad Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 22 Aug 2017 10:41:08 -0400 Subject: media: stm32-dcmi: catch dma submission error Test cookie return by dmaengine_submit() and return error if any. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index c2168b5c7810..7ffb2d3e99be 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -295,6 +295,10 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, /* Push current DMA transaction in the pending queue */ dcmi->dma_cookie = dmaengine_submit(desc); + if (dma_submit_error(dcmi->dma_cookie)) { + dev_err(dcmi->dev, "%s: DMA submission failed\n", __func__); + return -ENXIO; + } dma_async_issue_pending(dcmi->dma_chan); -- cgit v1.2.3 From 7b7805e58c0095017e3dce939f1af080fc90db79 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 22 Aug 2017 10:41:09 -0400 Subject: media: stm32-dcmi: revisit control register handling Simplify bits handling of DCMI_CR register. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 7ffb2d3e99be..1fe2d0f0f5de 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -490,7 +490,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); struct dcmi_buf *buf, *node; - u32 val; + u32 val = 0; int ret; ret = clk_enable(dcmi->mclk); @@ -510,22 +510,16 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) spin_lock_irq(&dcmi->irqlock); - val = reg_read(dcmi->regs, DCMI_CR); - - val &= ~(CR_PCKPOL | CR_HSPOL | CR_VSPOL | - CR_EDM_0 | CR_EDM_1 | CR_FCRC_0 | - CR_FCRC_1 | CR_JPEG | CR_ESS); - /* Set bus width */ switch (dcmi->bus.bus_width) { case 14: - val &= CR_EDM_0 + CR_EDM_1; + val |= CR_EDM_0 | CR_EDM_1; break; case 12: - val &= CR_EDM_1; + val |= CR_EDM_1; break; case 10: - val &= CR_EDM_0; + val |= CR_EDM_0; break; default: /* Set bus width to 8 bits by default */ -- cgit v1.2.3 From 38e423ee00b6138f8fafba60f2b6f4f3ebfeb1fa Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 22 Aug 2017 10:41:10 -0400 Subject: media: stm32-dcmi: cleanup variable/fields namings Uniformize "pixfmt" variables to "pix". Change "current_fmt" & "dcmi_fmt" variables to variables with "sd_" prefix to explicitly refer to subdev format. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 103 ++++++++++++++++-------------- 1 file changed, 54 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 1fe2d0f0f5de..7713c10e4769 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -132,9 +132,9 @@ struct stm32_dcmi { struct dcmi_graph_entity entity; struct v4l2_format fmt; - const struct dcmi_format **user_formats; - unsigned int num_user_formats; - const struct dcmi_format *current_fmt; + const struct dcmi_format **sd_formats; + unsigned int num_of_sd_formats; + const struct dcmi_format *sd_format; /* Protect this data structure */ struct mutex lock; @@ -684,12 +684,12 @@ static int dcmi_g_fmt_vid_cap(struct file *file, void *priv, static const struct dcmi_format *find_format_by_fourcc(struct stm32_dcmi *dcmi, unsigned int fourcc) { - unsigned int num_formats = dcmi->num_user_formats; + unsigned int num_formats = dcmi->num_of_sd_formats; const struct dcmi_format *fmt; unsigned int i; for (i = 0; i < num_formats; i++) { - fmt = dcmi->user_formats[i]; + fmt = dcmi->sd_formats[i]; if (fmt->fourcc == fourcc) return fmt; } @@ -698,40 +698,42 @@ static const struct dcmi_format *find_format_by_fourcc(struct stm32_dcmi *dcmi, } static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, - const struct dcmi_format **current_fmt) + const struct dcmi_format **sd_format) { - const struct dcmi_format *dcmi_fmt; - struct v4l2_pix_format *pixfmt = &f->fmt.pix; + const struct dcmi_format *sd_fmt; + struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; int ret; - dcmi_fmt = find_format_by_fourcc(dcmi, pixfmt->pixelformat); - if (!dcmi_fmt) { - dcmi_fmt = dcmi->user_formats[dcmi->num_user_formats - 1]; - pixfmt->pixelformat = dcmi_fmt->fourcc; + sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); + if (!sd_fmt) { + sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; + pix->pixelformat = sd_fmt->fourcc; } /* Limit to hardware capabilities */ - pixfmt->width = clamp(pixfmt->width, MIN_WIDTH, MAX_WIDTH); - pixfmt->height = clamp(pixfmt->height, MIN_HEIGHT, MAX_HEIGHT); + pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); + pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT); - v4l2_fill_mbus_format(&format.format, pixfmt, dcmi_fmt->mbus_code); + v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - v4l2_fill_pix_format(pixfmt, &format.format); + /* Update pix regarding to what sensor can do */ + v4l2_fill_pix_format(pix, &format.format); - pixfmt->field = V4L2_FIELD_NONE; - pixfmt->bytesperline = pixfmt->width * dcmi_fmt->bpp; - pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; - if (current_fmt) - *current_fmt = dcmi_fmt; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = pix->width * sd_fmt->bpp; + pix->sizeimage = pix->bytesperline * pix->height; + + if (sd_format) + *sd_format = sd_fmt; return 0; } @@ -741,22 +743,25 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f) struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; - const struct dcmi_format *current_fmt; + const struct dcmi_format *sd_format; + struct v4l2_mbus_framefmt *mf = &format.format; + struct v4l2_pix_format *pix = &f->fmt.pix; int ret; - ret = dcmi_try_fmt(dcmi, f, ¤t_fmt); + ret = dcmi_try_fmt(dcmi, f, &sd_format); if (ret) return ret; - v4l2_fill_mbus_format(&format.format, &f->fmt.pix, - current_fmt->mbus_code); + /* pix to mbus format */ + v4l2_fill_mbus_format(mf, pix, + sd_format->mbus_code); ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, NULL, &format); if (ret < 0) return ret; dcmi->fmt = *f; - dcmi->current_fmt = current_fmt; + dcmi->sd_format = sd_format; return 0; } @@ -785,10 +790,10 @@ static int dcmi_enum_fmt_vid_cap(struct file *file, void *priv, { struct stm32_dcmi *dcmi = video_drvdata(file); - if (f->index >= dcmi->num_user_formats) + if (f->index >= dcmi->num_of_sd_formats) return -EINVAL; - f->pixelformat = dcmi->user_formats[f->index]->fourcc; + f->pixelformat = dcmi->sd_formats[f->index]->fourcc; return 0; } @@ -830,18 +835,18 @@ static int dcmi_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { struct stm32_dcmi *dcmi = video_drvdata(file); - const struct dcmi_format *dcmi_fmt; + const struct dcmi_format *sd_fmt; struct v4l2_subdev_frame_size_enum fse = { .index = fsize->index, .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; int ret; - dcmi_fmt = find_format_by_fourcc(dcmi, fsize->pixel_format); - if (!dcmi_fmt) + sd_fmt = find_format_by_fourcc(dcmi, fsize->pixel_format); + if (!sd_fmt) return -EINVAL; - fse.code = dcmi_fmt->mbus_code; + fse.code = sd_fmt->mbus_code; ret = v4l2_subdev_call(dcmi->entity.subdev, pad, enum_frame_size, NULL, &fse); @@ -859,7 +864,7 @@ static int dcmi_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) { struct stm32_dcmi *dcmi = video_drvdata(file); - const struct dcmi_format *dcmi_fmt; + const struct dcmi_format *sd_fmt; struct v4l2_subdev_frame_interval_enum fie = { .index = fival->index, .width = fival->width, @@ -868,11 +873,11 @@ static int dcmi_enum_frameintervals(struct file *file, void *fh, }; int ret; - dcmi_fmt = find_format_by_fourcc(dcmi, fival->pixel_format); - if (!dcmi_fmt) + sd_fmt = find_format_by_fourcc(dcmi, fival->pixel_format); + if (!sd_fmt) return -EINVAL; - fie.code = dcmi_fmt->mbus_code; + fie.code = sd_fmt->mbus_code; ret = v4l2_subdev_call(dcmi->entity.subdev, pad, enum_frame_interval, NULL, &fie); @@ -994,7 +999,7 @@ static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) .width = CIF_WIDTH, .height = CIF_HEIGHT, .field = V4L2_FIELD_NONE, - .pixelformat = dcmi->user_formats[0]->fourcc, + .pixelformat = dcmi->sd_formats[0]->fourcc, }, }; int ret; @@ -1002,7 +1007,7 @@ static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) ret = dcmi_try_fmt(dcmi, &f, NULL); if (ret) return ret; - dcmi->current_fmt = dcmi->user_formats[0]; + dcmi->sd_format = dcmi->sd_formats[0]; dcmi->fmt = f; return 0; } @@ -1025,7 +1030,7 @@ static const struct dcmi_format dcmi_formats[] = { static int dcmi_formats_init(struct stm32_dcmi *dcmi) { - const struct dcmi_format *dcmi_fmts[ARRAY_SIZE(dcmi_formats)]; + const struct dcmi_format *sd_fmts[ARRAY_SIZE(dcmi_formats)]; unsigned int num_fmts = 0, i, j; struct v4l2_subdev *subdev = dcmi->entity.subdev; struct v4l2_subdev_mbus_code_enum mbus_code = { @@ -1040,13 +1045,13 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) /* Code supported, have we got this fourcc yet? */ for (j = 0; j < num_fmts; j++) - if (dcmi_fmts[j]->fourcc == + if (sd_fmts[j]->fourcc == dcmi_formats[i].fourcc) /* Already available */ break; if (j == num_fmts) /* New */ - dcmi_fmts[num_fmts++] = dcmi_formats + i; + sd_fmts[num_fmts++] = dcmi_formats + i; } mbus_code.index++; } @@ -1054,18 +1059,18 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) if (!num_fmts) return -ENXIO; - dcmi->num_user_formats = num_fmts; - dcmi->user_formats = devm_kcalloc(dcmi->dev, - num_fmts, sizeof(struct dcmi_format *), - GFP_KERNEL); - if (!dcmi->user_formats) { - dev_err(dcmi->dev, "could not allocate memory\n"); + dcmi->num_of_sd_formats = num_fmts; + dcmi->sd_formats = devm_kcalloc(dcmi->dev, + num_fmts, sizeof(struct dcmi_format *), + GFP_KERNEL); + if (!dcmi->sd_formats) { + dev_err(dcmi->dev, "Could not allocate memory\n"); return -ENOMEM; } - memcpy(dcmi->user_formats, dcmi_fmts, + memcpy(dcmi->sd_formats, sd_fmts, num_fmts * sizeof(struct dcmi_format *)); - dcmi->current_fmt = dcmi->user_formats[0]; + dcmi->sd_format = dcmi->sd_formats[0]; return 0; } -- cgit v1.2.3 From d533d5010ec373ea06ae4f253d7d69deb3fe0cfd Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 22 Aug 2017 10:41:11 -0400 Subject: media: stm32-dcmi: g_/s_selection crop support Implements g_/s_selection crop support by using DCMI crop hardware feature. User can first get the maximum supported resolution of the sensor by calling g_selection(V4L2_SEL_TGT_CROP_BOUNDS). Then user call to s_selection(V4L2_SEL_TGT_CROP) will reset sensor to its maximum resolution and crop request is saved for later usage in s_fmt(). Next call to s_fmt() will check if sensor can do frame size request with crop request. If sensor supports only discrete frame sizes, the frame size which is larger than user request is selected in order to be able to match the crop request. Then s_fmt() resolution user request is adjusted to match crop request resolution. Signed-off-by: Hugues Fruchet Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 374 +++++++++++++++++++++++++++++- 1 file changed, 370 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 7713c10e4769..35ba6f211b79 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define DRV_NAME "stm32-dcmi" @@ -107,6 +108,11 @@ struct dcmi_format { u8 bpp; }; +struct dcmi_framesize { + u32 width; + u32 height; +}; + struct dcmi_buf { struct vb2_v4l2_buffer vb; bool prepared; @@ -131,10 +137,16 @@ struct stm32_dcmi { struct v4l2_async_notifier notifier; struct dcmi_graph_entity entity; struct v4l2_format fmt; + struct v4l2_rect crop; + bool do_crop; const struct dcmi_format **sd_formats; unsigned int num_of_sd_formats; const struct dcmi_format *sd_format; + struct dcmi_framesize *sd_framesizes; + unsigned int num_of_sd_framesizes; + struct dcmi_framesize sd_framesize; + struct v4l2_rect sd_bounds; /* Protect this data structure */ struct mutex lock; @@ -325,6 +337,28 @@ static int dcmi_start_capture(struct stm32_dcmi *dcmi) return 0; } +static void dcmi_set_crop(struct stm32_dcmi *dcmi) +{ + u32 size, start; + + /* Crop resolution */ + size = ((dcmi->crop.height - 1) << 16) | + ((dcmi->crop.width << 1) - 1); + reg_write(dcmi->regs, DCMI_CWSIZE, size); + + /* Crop start point */ + start = ((dcmi->crop.top) << 16) | + ((dcmi->crop.left << 1)); + reg_write(dcmi->regs, DCMI_CWSTRT, start); + + dev_dbg(dcmi->dev, "Cropping to %ux%u@%u:%u\n", + dcmi->crop.width, dcmi->crop.height, + dcmi->crop.left, dcmi->crop.top); + + /* Enable crop */ + reg_set(dcmi->regs, DCMI_CR, CR_CROP); +} + static irqreturn_t dcmi_irq_thread(int irq, void *arg) { struct stm32_dcmi *dcmi = arg; @@ -540,6 +574,10 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) reg_write(dcmi->regs, DCMI_CR, val); + /* Set crop */ + if (dcmi->do_crop) + dcmi_set_crop(dcmi); + /* Enable dcmi */ reg_set(dcmi->regs, DCMI_CR, CR_ENABLE); @@ -697,10 +735,37 @@ static const struct dcmi_format *find_format_by_fourcc(struct stm32_dcmi *dcmi, return NULL; } +static void __find_outer_frame_size(struct stm32_dcmi *dcmi, + struct v4l2_pix_format *pix, + struct dcmi_framesize *framesize) +{ + struct dcmi_framesize *match = NULL; + unsigned int i; + unsigned int min_err = UINT_MAX; + + for (i = 0; i < dcmi->num_of_sd_framesizes; i++) { + struct dcmi_framesize *fsize = &dcmi->sd_framesizes[i]; + int w_err = (fsize->width - pix->width); + int h_err = (fsize->height - pix->height); + int err = w_err + h_err; + + if ((w_err >= 0) && (h_err >= 0) && (err < min_err)) { + min_err = err; + match = fsize; + } + } + if (!match) + match = &dcmi->sd_framesizes[0]; + + *framesize = *match; +} + static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, - const struct dcmi_format **sd_format) + const struct dcmi_format **sd_format, + struct dcmi_framesize *sd_framesize) { const struct dcmi_format *sd_fmt; + struct dcmi_framesize sd_fsize; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_format format = { @@ -718,6 +783,17 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT); + if (dcmi->do_crop && dcmi->num_of_sd_framesizes) { + struct dcmi_framesize outer_sd_fsize; + /* + * If crop is requested and sensor have discrete frame sizes, + * select the frame size that is just larger than request + */ + __find_outer_frame_size(dcmi, pix, &outer_sd_fsize); + pix->width = outer_sd_fsize.width; + pix->height = outer_sd_fsize.height; + } + v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, &pad_cfg, &format); @@ -727,6 +803,31 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, /* Update pix regarding to what sensor can do */ v4l2_fill_pix_format(pix, &format.format); + /* Save resolution that sensor can actually do */ + sd_fsize.width = pix->width; + sd_fsize.height = pix->height; + + if (dcmi->do_crop) { + struct v4l2_rect c = dcmi->crop; + struct v4l2_rect max_rect; + + /* + * Adjust crop by making the intersection between + * format resolution request and crop request + */ + max_rect.top = 0; + max_rect.left = 0; + max_rect.width = pix->width; + max_rect.height = pix->height; + v4l2_rect_map_inside(&c, &max_rect); + c.top = clamp_t(s32, c.top, 0, pix->height - c.height); + c.left = clamp_t(s32, c.left, 0, pix->width - c.width); + dcmi->crop = c; + + /* Adjust format resolution request to crop */ + pix->width = dcmi->crop.width; + pix->height = dcmi->crop.height; + } pix->field = V4L2_FIELD_NONE; pix->bytesperline = pix->width * sd_fmt->bpp; @@ -734,6 +835,8 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, if (sd_format) *sd_format = sd_fmt; + if (sd_framesize) + *sd_framesize = sd_fsize; return 0; } @@ -744,24 +847,41 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f) .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; const struct dcmi_format *sd_format; + struct dcmi_framesize sd_framesize; struct v4l2_mbus_framefmt *mf = &format.format; struct v4l2_pix_format *pix = &f->fmt.pix; int ret; - ret = dcmi_try_fmt(dcmi, f, &sd_format); + /* + * Try format, fmt.width/height could have been changed + * to match sensor capability or crop request + * sd_format & sd_framesize will contain what subdev + * can do for this request. + */ + ret = dcmi_try_fmt(dcmi, f, &sd_format, &sd_framesize); if (ret) return ret; /* pix to mbus format */ v4l2_fill_mbus_format(mf, pix, sd_format->mbus_code); + mf->width = sd_framesize.width; + mf->height = sd_framesize.height; + ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, NULL, &format); if (ret < 0) return ret; + dev_dbg(dcmi->dev, "Sensor format set to 0x%x %ux%u\n", + mf->code, mf->width, mf->height); + dev_dbg(dcmi->dev, "Buffer format set to %4.4s %ux%u\n", + (char *)&pix->pixelformat, + pix->width, pix->height); + dcmi->fmt = *f; dcmi->sd_format = sd_format; + dcmi->sd_framesize = sd_framesize; return 0; } @@ -782,7 +902,7 @@ static int dcmi_try_fmt_vid_cap(struct file *file, void *priv, { struct stm32_dcmi *dcmi = video_drvdata(file); - return dcmi_try_fmt(dcmi, f, NULL); + return dcmi_try_fmt(dcmi, f, NULL, NULL); } static int dcmi_enum_fmt_vid_cap(struct file *file, void *priv, @@ -797,6 +917,193 @@ static int dcmi_enum_fmt_vid_cap(struct file *file, void *priv, return 0; } +static int dcmi_get_sensor_format(struct stm32_dcmi *dcmi, + struct v4l2_pix_format *pix) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + int ret; + + ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_fmt, NULL, &fmt); + if (ret) + return ret; + + v4l2_fill_pix_format(pix, &fmt.format); + + return 0; +} + +static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi, + struct v4l2_pix_format *pix) +{ + const struct dcmi_format *sd_fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_TRY, + }; + struct v4l2_subdev_pad_config pad_cfg; + int ret; + + sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); + if (!sd_fmt) { + sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; + pix->pixelformat = sd_fmt->fourcc; + } + + v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); + ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, + &pad_cfg, &format); + if (ret < 0) + return ret; + + return 0; +} + +static int dcmi_get_sensor_bounds(struct stm32_dcmi *dcmi, + struct v4l2_rect *r) +{ + struct v4l2_subdev_selection bounds = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP_BOUNDS, + }; + unsigned int max_width, max_height, max_pixsize; + struct v4l2_pix_format pix; + unsigned int i; + int ret; + + /* + * Get sensor bounds first + */ + ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_selection, + NULL, &bounds); + if (!ret) + *r = bounds.r; + if (ret != -ENOIOCTLCMD) + return ret; + + /* + * If selection is not implemented, + * fallback by enumerating sensor frame sizes + * and take the largest one + */ + max_width = 0; + max_height = 0; + max_pixsize = 0; + for (i = 0; i < dcmi->num_of_sd_framesizes; i++) { + struct dcmi_framesize *fsize = &dcmi->sd_framesizes[i]; + unsigned int pixsize = fsize->width * fsize->height; + + if (pixsize > max_pixsize) { + max_pixsize = pixsize; + max_width = fsize->width; + max_height = fsize->height; + } + } + if (max_pixsize > 0) { + r->top = 0; + r->left = 0; + r->width = max_width; + r->height = max_height; + return 0; + } + + /* + * If frame sizes enumeration is not implemented, + * fallback by getting current sensor frame size + */ + ret = dcmi_get_sensor_format(dcmi, &pix); + if (ret) + return ret; + + r->top = 0; + r->left = 0; + r->width = pix.width; + r->height = pix.height; + + return 0; +} + +static int dcmi_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct stm32_dcmi *dcmi = video_drvdata(file); + + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + s->r = dcmi->sd_bounds; + return 0; + case V4L2_SEL_TGT_CROP: + if (dcmi->do_crop) { + s->r = dcmi->crop; + } else { + s->r.top = 0; + s->r.left = 0; + s->r.width = dcmi->fmt.fmt.pix.width; + s->r.height = dcmi->fmt.fmt.pix.height; + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static int dcmi_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct stm32_dcmi *dcmi = video_drvdata(file); + struct v4l2_rect r = s->r; + struct v4l2_rect max_rect; + struct v4l2_pix_format pix; + + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + s->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + /* Reset sensor resolution to max resolution */ + pix.pixelformat = dcmi->fmt.fmt.pix.pixelformat; + pix.width = dcmi->sd_bounds.width; + pix.height = dcmi->sd_bounds.height; + dcmi_set_sensor_format(dcmi, &pix); + + /* + * Make the intersection between + * sensor resolution + * and crop request + */ + max_rect.top = 0; + max_rect.left = 0; + max_rect.width = pix.width; + max_rect.height = pix.height; + v4l2_rect_map_inside(&r, &max_rect); + r.top = clamp_t(s32, r.top, 0, pix.height - r.height); + r.left = clamp_t(s32, r.left, 0, pix.width - r.width); + + if (!((r.top == dcmi->sd_bounds.top) && + (r.left == dcmi->sd_bounds.left) && + (r.width == dcmi->sd_bounds.width) && + (r.height == dcmi->sd_bounds.height))) { + /* Crop if request is different than sensor resolution */ + dcmi->do_crop = true; + dcmi->crop = r; + dev_dbg(dcmi->dev, "s_selection: crop %ux%u@(%u,%u) from %ux%u\n", + r.width, r.height, r.left, r.top, + pix.width, pix.height); + } else { + /* Disable crop */ + dcmi->do_crop = false; + dev_dbg(dcmi->dev, "s_selection: crop is disabled\n"); + } + + s->r = r; + return 0; +} + static int dcmi_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -955,6 +1262,8 @@ static const struct v4l2_ioctl_ops dcmi_ioctl_ops = { .vidioc_g_fmt_vid_cap = dcmi_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = dcmi_s_fmt_vid_cap, .vidioc_enum_fmt_vid_cap = dcmi_enum_fmt_vid_cap, + .vidioc_g_selection = dcmi_g_selection, + .vidioc_s_selection = dcmi_s_selection, .vidioc_enum_input = dcmi_enum_input, .vidioc_g_input = dcmi_g_input, @@ -1004,7 +1313,7 @@ static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) }; int ret; - ret = dcmi_try_fmt(dcmi, &f, NULL); + ret = dcmi_try_fmt(dcmi, &f, NULL, NULL); if (ret) return ret; dcmi->sd_format = dcmi->sd_formats[0]; @@ -1075,6 +1384,51 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) return 0; } +static int dcmi_framesizes_init(struct stm32_dcmi *dcmi) +{ + unsigned int num_fsize = 0; + struct v4l2_subdev *subdev = dcmi->entity.subdev; + struct v4l2_subdev_frame_size_enum fse = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .code = dcmi->sd_format->mbus_code, + }; + unsigned int ret; + unsigned int i; + + /* Allocate discrete framesizes array */ + while (!v4l2_subdev_call(subdev, pad, enum_frame_size, + NULL, &fse)) + fse.index++; + + num_fsize = fse.index; + if (!num_fsize) + return 0; + + dcmi->num_of_sd_framesizes = num_fsize; + dcmi->sd_framesizes = devm_kcalloc(dcmi->dev, num_fsize, + sizeof(struct dcmi_framesize), + GFP_KERNEL); + if (!dcmi->sd_framesizes) { + dev_err(dcmi->dev, "Could not allocate memory\n"); + return -ENOMEM; + } + + /* Fill array with sensor supported framesizes */ + dev_dbg(dcmi->dev, "Sensor supports %u frame sizes:\n", num_fsize); + for (i = 0; i < dcmi->num_of_sd_framesizes; i++) { + fse.index = i; + ret = v4l2_subdev_call(subdev, pad, enum_frame_size, + NULL, &fse); + if (ret) + return ret; + dcmi->sd_framesizes[fse.index].width = fse.max_width; + dcmi->sd_framesizes[fse.index].height = fse.max_height; + dev_dbg(dcmi->dev, "%ux%u\n", fse.max_width, fse.max_height); + } + + return 0; +} + static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) { struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); @@ -1087,6 +1441,18 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) return ret; } + ret = dcmi_framesizes_init(dcmi); + if (ret) { + dev_err(dcmi->dev, "Could not initialize framesizes\n"); + return ret; + } + + ret = dcmi_get_sensor_bounds(dcmi, &dcmi->sd_bounds); + if (ret) { + dev_err(dcmi->dev, "Could not get sensor bounds\n"); + return ret; + } + ret = dcmi_set_default_fmt(dcmi); if (ret) { dev_err(dcmi->dev, "Could not set default format\n"); -- cgit v1.2.3 From 5b6f9abe5a49df81737fbbfba890ee5b093f8168 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Mon, 21 Aug 2017 07:34:10 -0400 Subject: media: vb2: add bidirectional flag in vb2_queue This change is intended to give to the v4l2 drivers a choice to change the default behavior of the v4l2-core DMA mapping direction from DMA_TO/FROM_DEVICE (depending on the buffer type CAPTURE or OUTPUT) to DMA_BIDIRECTIONAL during queue_init time. Initially the issue with DMA mapping direction has been found in Venus encoder driver where the hardware (firmware side) adds few lines padding on bottom of the image buffer, and the consequence is triggering of IOMMU protection faults. This will help supporting venus encoder (and probably other drivers in the future) which wants to map output type of buffers as read/write. Signed-off-by: Stanimir Varbanov Acked-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 17 ++++++++--------- drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 ++- drivers/media/v4l2-core/videobuf2-dma-sg.c | 6 ++++-- drivers/media/v4l2-core/videobuf2-vmalloc.c | 6 ++++-- include/media/videobuf2-core.h | 13 +++++++++++++ 5 files changed, 31 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 0924594989b4..cb115ba6a1d2 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -194,8 +194,6 @@ static void __enqueue_in_driver(struct vb2_buffer *vb); static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) { struct vb2_queue *q = vb->vb2_queue; - enum dma_data_direction dma_dir = - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; void *mem_priv; int plane; int ret = -ENOMEM; @@ -209,7 +207,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) mem_priv = call_ptr_memop(vb, alloc, q->alloc_devs[plane] ? : q->dev, - q->dma_attrs, size, dma_dir, q->gfp_flags); + q->dma_attrs, size, q->dma_dir, q->gfp_flags); if (IS_ERR_OR_NULL(mem_priv)) { if (mem_priv) ret = PTR_ERR(mem_priv); @@ -978,8 +976,6 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) void *mem_priv; unsigned int plane; int ret = 0; - enum dma_data_direction dma_dir = - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); @@ -1030,7 +1026,7 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_devs[plane] ? : q->dev, planes[plane].m.userptr, - planes[plane].length, dma_dir); + planes[plane].length, q->dma_dir); if (IS_ERR(mem_priv)) { dprintk(1, "failed acquiring userspace memory for plane %d\n", plane); @@ -1096,8 +1092,6 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) void *mem_priv; unsigned int plane; int ret = 0; - enum dma_data_direction dma_dir = - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; bool reacquired = vb->planes[0].mem_priv == NULL; memset(planes, 0, sizeof(planes[0]) * vb->num_planes); @@ -1156,7 +1150,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) /* Acquire each plane's memory */ mem_priv = call_ptr_memop(vb, attach_dmabuf, q->alloc_devs[plane] ? : q->dev, - dbuf, planes[plane].length, dma_dir); + dbuf, planes[plane].length, q->dma_dir); if (IS_ERR(mem_priv)) { dprintk(1, "failed to attach dmabuf\n"); ret = PTR_ERR(mem_priv); @@ -2003,6 +1997,11 @@ int vb2_core_queue_init(struct vb2_queue *q) if (q->buf_struct_size == 0) q->buf_struct_size = sizeof(struct vb2_buffer); + if (q->bidirectional) + q->dma_dir = DMA_BIDIRECTIONAL; + else + q->dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + return 0; } EXPORT_SYMBOL_GPL(vb2_core_queue_init); diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 5b90a66b9e78..9f389f36566d 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -508,7 +508,8 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, buf->dma_dir = dma_dir; offset = vaddr & ~PAGE_MASK; - vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || + dma_dir == DMA_BIDIRECTIONAL); if (IS_ERR(vec)) { ret = PTR_ERR(vec); goto fail_buf; diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 54f33938d45b..6808231a6bdc 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -239,7 +239,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, buf->offset = vaddr & ~PAGE_MASK; buf->size = size; buf->dma_sgt = &buf->sg_table; - vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE); + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || + dma_dir == DMA_BIDIRECTIONAL); if (IS_ERR(vec)) goto userptr_fail_pfnvec; buf->vec = vec; @@ -292,7 +293,8 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(buf->dma_sgt); while (--i >= 0) { - if (buf->dma_dir == DMA_FROM_DEVICE) + if (buf->dma_dir == DMA_FROM_DEVICE || + buf->dma_dir == DMA_BIDIRECTIONAL) set_page_dirty_lock(buf->pages[i]); } vb2_destroy_framevec(buf->vec); diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 6bc130fe84f6..3a7c80cd1a17 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -87,7 +87,8 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, buf->dma_dir = dma_dir; offset = vaddr & ~PAGE_MASK; buf->size = size; - vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || + dma_dir == DMA_BIDIRECTIONAL); if (IS_ERR(vec)) { ret = PTR_ERR(vec); goto fail_pfnvec_create; @@ -137,7 +138,8 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) pages = frame_vector_pages(buf->vec); if (vaddr) vm_unmap_ram((void *)vaddr, n_pages); - if (buf->dma_dir == DMA_FROM_DEVICE) + if (buf->dma_dir == DMA_FROM_DEVICE || + buf->dma_dir == DMA_BIDIRECTIONAL) for (i = 0; i < n_pages; i++) set_page_dirty_lock(pages[i]); } else { diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index cb97c224be73..ef9b64398c8c 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -427,6 +427,16 @@ struct vb2_buf_ops { * @dev: device to use for the default allocation context if the driver * doesn't fill in the @alloc_devs array. * @dma_attrs: DMA attributes to use for the DMA. + * @bidirectional: when this flag is set the DMA direction for the buffers of + * this queue will be overridden with DMA_BIDIRECTIONAL direction. + * This is useful in cases where the hardware (firmware) writes to + * a buffer which is mapped as read (DMA_TO_DEVICE), or reads from + * buffer which is mapped for write (DMA_FROM_DEVICE) in order + * to satisfy some internal hardware restrictions or adds a padding + * needed by the processing algorithm. In case the DMA mapping is + * not bidirectional but the hardware (firmware) trying to access + * the buffer (in the opposite direction) this could lead to an + * IOMMU protection faults. * @fileio_read_once: report EOF after reading the first buffer * @fileio_write_immediately: queue buffer after each write() call * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver @@ -465,6 +475,7 @@ struct vb2_buf_ops { * Private elements (won't appear at the uAPI book): * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped * @memory: current memory type used + * @dma_dir: DMA mapping direction. * @bufs: videobuf buffer structures * @num_buffers: number of allocated/used buffers * @queued_list: list of buffers currently queued from userspace @@ -495,6 +506,7 @@ struct vb2_queue { unsigned int io_modes; struct device *dev; unsigned long dma_attrs; + unsigned bidirectional:1; unsigned fileio_read_once:1; unsigned fileio_write_immediately:1; unsigned allow_zero_bytesused:1; @@ -516,6 +528,7 @@ struct vb2_queue { /* private: internal use only */ struct mutex mmap_lock; unsigned int memory; + enum dma_data_direction dma_dir; struct vb2_buffer *bufs[VB2_MAX_FRAME]; unsigned int num_buffers; -- cgit v1.2.3 From 07d3717a12ce4063c7f35839d902e608bbf3ea2c Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Fri, 18 Aug 2017 10:16:01 -0400 Subject: media: venus: venc: set correct resolution on compressed stream This change the alignment restriction for output type of buffers only, also set corect input resolution and fill bidirectional vb2 queue flag in order to map output type buffers read/write. The last is needed by encoder firmware to add padding at the bottom of output (input buffers). Signed-off-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/venc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 20a3daa82492..6f123a387cf9 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -295,7 +295,7 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) pixmp->height = clamp(pixmp->height, inst->cap_height.min, inst->cap_height.max); - if (inst->core->res->hfi_version == HFI_VERSION_1XX) + if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) pixmp->height = ALIGN(pixmp->height, 32); pixmp->width = ALIGN(pixmp->width, 2); @@ -753,8 +753,8 @@ static int venc_init_session(struct venus_inst *inst) if (ret) return ret; - ret = venus_helper_set_input_resolution(inst, inst->out_width, - inst->out_height); + ret = venus_helper_set_input_resolution(inst, inst->width, + inst->height); if (ret) goto deinit; @@ -1016,6 +1016,8 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->allow_zero_bytesused = 1; src_vq->min_buffers_needed = 1; src_vq->dev = inst->core->dev; + if (inst->core->res->hfi_version == HFI_VERSION_1XX) + src_vq->bidirectional = 1; ret = vb2_queue_init(src_vq); if (ret) return ret; -- cgit v1.2.3 From 4d947447cf54a877ac81c4667706892c4b57a1d2 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Mon, 21 Aug 2017 09:33:32 -0400 Subject: media: bt8xx: Make i2c_algo_bit_data const Make this const as it is only used in a copy operation. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-i2c.c b/drivers/media/pci/bt8xx/bttv-i2c.c index 274fd036b306..eccd1e3d717a 100644 --- a/drivers/media/pci/bt8xx/bttv-i2c.c +++ b/drivers/media/pci/bt8xx/bttv-i2c.c @@ -97,7 +97,7 @@ static int bttv_bit_getsda(void *data) return state; } -static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { +static const struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { .setsda = bttv_bit_setsda, .setscl = bttv_bit_setscl, .getsda = bttv_bit_getsda, -- cgit v1.2.3 From 597c147ba950a3b0c4ecb0d1877668b66425c262 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Mon, 21 Aug 2017 09:35:50 -0400 Subject: media: cx18: Make i2c_algo_bit_data const Make this const as it is only used in a copy operation. Signed-off-by: Bhumika Goyal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c index af56d56eae08..7f588eeac60f 100644 --- a/drivers/media/pci/cx18/cx18-i2c.c +++ b/drivers/media/pci/cx18/cx18-i2c.c @@ -216,7 +216,7 @@ static const struct i2c_adapter cx18_i2c_adap_template = { #define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */ #define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */ -static struct i2c_algo_bit_data cx18_i2c_algo_template = { +static const struct i2c_algo_bit_data cx18_i2c_algo_template = { .setsda = cx18_setsda, .setscl = cx18_setscl, .getsda = cx18_getsda, -- cgit v1.2.3 From 11c2078bbfc30ac3923b1435612cd91e35820176 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 22 Aug 2017 08:56:33 -0400 Subject: media: saa7146: constify videobuf_queue_ops structures videobuf_queue_ops are not supposed to change at runtime. All functions working with videobuf_queue_ops provided by work with const videobuf_queue_ops. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146/saa7146_vbi.c | 2 +- drivers/media/common/saa7146/saa7146_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c index 3553ac4cba5c..d79e4d7ecd9f 100644 --- a/drivers/media/common/saa7146/saa7146_vbi.c +++ b/drivers/media/common/saa7146/saa7146_vbi.c @@ -308,7 +308,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) saa7146_dma_free(dev,q,buf); } -static struct videobuf_queue_ops vbi_qops = { +static const struct videobuf_queue_ops vbi_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c index b3b29d4f36ed..37b4654dc21c 100644 --- a/drivers/media/common/saa7146/saa7146_video.c +++ b/drivers/media/common/saa7146/saa7146_video.c @@ -1187,7 +1187,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) release_all_pagetables(dev, buf); } -static struct videobuf_queue_ops video_qops = { +static const struct videobuf_queue_ops video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From 960c15dd171cf9f7172ecb785673b8265c567a53 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 22 Aug 2017 08:56:34 -0400 Subject: media: pci: constify videobuf_queue_ops structures videobuf_queue_ops are not supposed to change at runtime. All functions working with videobuf_queue_ops provided by work with const videobuf_queue_ops. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bttv-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 40110be4e986..227086a2e99c 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -1702,7 +1702,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) bttv_dma_free(q,fh->btv,buf); } -static struct videobuf_queue_ops bttv_video_qops = { +static const struct videobuf_queue_ops bttv_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From bd9f8f750e238f8a6160fb053ae97016f6da1098 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Tue, 22 Aug 2017 08:56:35 -0400 Subject: media: platform: constify videobuf_queue_ops structures videobuf_queue_ops are not supposed to change at runtime. All functions working with videobuf_queue_ops provided by work with const videobuf_queue_ops. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpfe_capture.c | 2 +- drivers/media/platform/fsl-viu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index b1bf4a7e8eb7..6792da16d9c7 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1288,7 +1288,7 @@ static void vpfe_videobuf_release(struct videobuf_queue *vq, vb->state = VIDEOBUF_NEEDS_INIT; } -static struct videobuf_queue_ops vpfe_videobuf_qops = { +static const struct videobuf_queue_ops vpfe_videobuf_qops = { .buf_setup = vpfe_videobuf_setup, .buf_prepare = vpfe_videobuf_prepare, .buf_queue = vpfe_videobuf_queue, diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index f7b88e58d00e..2e06dd564442 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -549,7 +549,7 @@ static void buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -static struct videobuf_queue_ops viu_video_qops = { +static const struct videobuf_queue_ops viu_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, -- cgit v1.2.3 From 801e3659bf2c87c31b7024087d61e89e172b5651 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 22 Aug 2017 10:21:20 -0400 Subject: media: em28xx: calculate left volume level correctly The calculation of the left volume looks suspect, the value of 0x1f - ((val << 8) & 0x1f) is always 0x1f. The debug prior to the assignment of value[1] prints the left volume setting using the calculation 0x1f - (val >> 8) & 0x1f which looks correct to me. Fix the left volume by using the correct expression as used in the debug. Detected by CoverityScan, CID#146140 ("Wrong operator used") Fixes: 850d24a5a861 ("[media] em28xx-alsa: add mixer support for AC97 volume controls") Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 261620a57420..4628d73f46f2 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -564,7 +564,7 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol, val, (int)kcontrol->private_value); value->value.integer.value[0] = 0x1f - (val & 0x1f); - value->value.integer.value[1] = 0x1f - ((val << 8) & 0x1f); + value->value.integer.value[1] = 0x1f - ((val >> 8) & 0x1f); return 0; } -- cgit v1.2.3 From 0de0ef6c3f2dd7e9965270683445917e10384ab0 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 18 Aug 2017 12:07:19 -0400 Subject: media: venus: fix copy/paste error in return_buf_error Call function v4l2_m2m_dst_buf_remove_by_buf() instead of v4l2_m2m_src_buf_remove_by_buf() Addresses-Coverity-ID: 1415317 Signed-off-by: Gustavo A. R. Silva Acked-by: Stanimir Varbanov Signed-off-by: Hans Verkuil Cc: # for v4.13 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index b52410deeb4c..68933d208063 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -292,7 +292,7 @@ static void return_buf_error(struct venus_inst *inst, if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); else - v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf); + v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf); v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); } -- cgit v1.2.3 From d1b3437ed780cd97b4b1300db96a4d8faae6fea1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Aug 2017 09:29:58 -0400 Subject: media: v4l: Add packed Bayer raw12 pixel formats These formats are compressed 12-bit raw bayer formats with four different pixel orders. They are similar to 10-bit variants. The formats added by this patch are V4L2_PIX_FMT_SBGGR12P V4L2_PIX_FMT_SGBRG12P V4L2_PIX_FMT_SGRBG12P V4L2_PIX_FMT_SRGGB12P Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-rgb.rst | 1 + Documentation/media/uapi/v4l/pixfmt-srggb12p.rst | 103 +++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 12 ++- include/uapi/linux/videodev2.h | 5 ++ 4 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 Documentation/media/uapi/v4l/pixfmt-srggb12p.rst (limited to 'drivers') diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index b0f35136021e..4cc27195dc79 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -17,4 +17,5 @@ RGB Formats pixfmt-srggb10alaw8 pixfmt-srggb10dpcm8 pixfmt-srggb12 + pixfmt-srggb12p pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst new file mode 100644 index 000000000000..c0541e5acd01 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst @@ -0,0 +1,103 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB12P: +.. _v4l2-pix-fmt-sbggr12p: +.. _v4l2-pix-fmt-sgbrg12p: +.. _v4l2-pix-fmt-sgrbg12p: + +******************************************************************************************************************************* +V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGBRG12P ('pGAA'), V4L2_PIX_FMT_SBGGR12P ('pBAA'), +******************************************************************************************************************************* + + +12-bit packed Bayer formats + + +Description +=========== + +These four pixel formats are packed raw sRGB / Bayer formats with 12 +bits per colour. Every two consecutive samples are packed into three +bytes. Each of the first two bytes contain the 8 high order bits of +the pixels, and the third byte contains the four least significants +bits of each pixel, in the same order. + +Each n-pixel row contains n/2 green samples and n/2 blue or red +samples, with alternating green-red and green-blue rows. They are +conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. +Below is an example of a small V4L2_PIX_FMT_SBGGR12P image: + +**Byte Order.** +Each cell is one byte. + + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 2 1 1 1 1 1 1 + + + - .. row 1 + + - start + 0: + + - B\ :sub:`00high` + + - G\ :sub:`01high` + + - G\ :sub:`01low`\ (bits 7--4) B\ :sub:`00low`\ (bits 3--0) + + - B\ :sub:`02high` + + - G\ :sub:`03high` + + - G\ :sub:`03low`\ (bits 7--4) B\ :sub:`02low`\ (bits 3--0) + + - .. row 2 + + - start + 6: + + - G\ :sub:`10high` + + - R\ :sub:`11high` + + - R\ :sub:`11low`\ (bits 7--4) G\ :sub:`10low`\ (bits 3--0) + + - G\ :sub:`12high` + + - R\ :sub:`13high` + + - R\ :sub:`13low`\ (bits 3--2) G\ :sub:`12low`\ (bits 3--0) + + - .. row 3 + + - start + 12: + + - B\ :sub:`20high` + + - G\ :sub:`21high` + + - G\ :sub:`21low`\ (bits 7--4) B\ :sub:`20low`\ (bits 3--0) + + - B\ :sub:`22high` + + - G\ :sub:`23high` + + - G\ :sub:`23low`\ (bits 7--4) B\ :sub:`22low`\ (bits 3--0) + + - .. row 4 + + - start + 18: + + - G\ :sub:`30high` + + - R\ :sub:`31high` + + - R\ :sub:`31low`\ (bits 7--4) G\ :sub:`30low`\ (bits 3--0) + + - G\ :sub:`32high` + + - R\ :sub:`33high` + + - R\ :sub:`33low`\ (bits 3--2) G\ :sub:`32low`\ (bits 3--0) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index cab63bb49c97..b60a6b0841d1 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1195,10 +1195,6 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; - case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; - case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; - case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; - case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; @@ -1211,6 +1207,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; + case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 45cf7359822c..185d6a0acc06 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -603,6 +603,11 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ + /* 12bit raw bayer packed, 6 bytes for every 4 pixels */ +#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C') +#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') +#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') +#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16 GRGR.. BGBG.. */ -- cgit v1.2.3 From c94d21ffa8147073b3604e919bb61f29132235a5 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:02 -0400 Subject: media: camss: Add CSIPHY files These files control the CSIPHY modules which are responsible for the physical layer of the CSI2 receivers. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-csiphy.c | 823 +++++++++++++++++++++ .../media/platform/qcom/camss-8x16/camss-csiphy.h | 77 ++ 2 files changed, 900 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-csiphy.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-csiphy.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c new file mode 100644 index 000000000000..ed03775c9b3a --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c @@ -0,0 +1,823 @@ +/* + * camss-csiphy.c + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camss-csiphy.h" +#include "camss.h" + +#define MSM_CSIPHY_NAME "msm_csiphy" + +#define CAMSS_CSI_PHY_LNn_CFG2(n) (0x004 + 0x40 * (n)) +#define CAMSS_CSI_PHY_LNn_CFG3(n) (0x008 + 0x40 * (n)) +#define CAMSS_CSI_PHY_GLBL_RESET 0x140 +#define CAMSS_CSI_PHY_GLBL_PWR_CFG 0x144 +#define CAMSS_CSI_PHY_GLBL_IRQ_CMD 0x164 +#define CAMSS_CSI_PHY_HW_VERSION 0x188 +#define CAMSS_CSI_PHY_INTERRUPT_STATUSn(n) (0x18c + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_MASKn(n) (0x1ac + 0x4 * (n)) +#define CAMSS_CSI_PHY_INTERRUPT_CLEARn(n) (0x1cc + 0x4 * (n)) +#define CAMSS_CSI_PHY_GLBL_T_INIT_CFG0 0x1ec +#define CAMSS_CSI_PHY_T_WAKEUP_CFG0 0x1f4 + +static const struct { + u32 code; + u8 bpp; +} csiphy_formats[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + 12, + } +}; + +/* + * csiphy_get_bpp - map media bus format to bits per pixel + * @code: media bus format code + * + * Return number of bits per pixel + */ +static u8 csiphy_get_bpp(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(csiphy_formats); i++) + if (code == csiphy_formats[i].code) + return csiphy_formats[i].bpp; + + WARN(1, "Unknown format\n"); + + return csiphy_formats[0].bpp; +} + +/* + * csiphy_isr - CSIPHY module interrupt handler + * @irq: Interrupt line + * @dev: CSIPHY device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t csiphy_isr(int irq, void *dev) +{ + struct csiphy_device *csiphy = dev; + u8 i; + + for (i = 0; i < 8; i++) { + u8 val = readl_relaxed(csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_STATUSn(i)); + writel_relaxed(val, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); + writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_IRQ_CMD); + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_IRQ_CMD); + writel_relaxed(0x0, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); + } + + return IRQ_HANDLED; +} + +/* + * csiphy_reset - Perform software reset on CSIPHY module + * @csiphy: CSIPHY device + */ +static void csiphy_reset(struct csiphy_device *csiphy) +{ + writel_relaxed(0x1, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); + usleep_range(5000, 8000); + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); +} + +/* + * csiphy_set_power - Power on/off CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @on: Requested power state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_power(struct v4l2_subdev *sd, int on) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct device *dev = to_device_index(csiphy, csiphy->id); + + if (on) { + u8 hw_version; + int ret; + + ret = camss_enable_clocks(csiphy->nclocks, csiphy->clock, dev); + if (ret < 0) + return ret; + + enable_irq(csiphy->irq); + + csiphy_reset(csiphy); + + hw_version = readl_relaxed(csiphy->base + + CAMSS_CSI_PHY_HW_VERSION); + dev_dbg(dev, "CSIPHY HW Version = 0x%02x\n", hw_version); + } else { + disable_irq(csiphy->irq); + + camss_disable_clocks(csiphy->nclocks, csiphy->clock); + } + + return 0; +} + +/* + * csiphy_get_lane_mask - Calculate CSI2 lane mask configuration parameter + * @lane_cfg - CSI2 lane configuration + * + * Return lane mask + */ +static u8 csiphy_get_lane_mask(struct csiphy_lanes_cfg *lane_cfg) +{ + u8 lane_mask; + int i; + + lane_mask = 1 << lane_cfg->clk.pos; + + for (i = 0; i < lane_cfg->num_data; i++) + lane_mask |= 1 << lane_cfg->data[i].pos; + + return lane_mask; +} + +/* + * csiphy_settle_cnt_calc - Calculate settle count value + * @csiphy: CSIPHY device + * + * Helper function to calculate settle count value. This is + * based on the CSI2 T_hs_settle parameter which in turn + * is calculated based on the CSI2 transmitter pixel clock + * frequency. + * + * Return settle count value or 0 if the CSI2 pixel clock + * frequency is not available + */ +static u8 csiphy_settle_cnt_calc(struct csiphy_device *csiphy) +{ + u8 bpp = csiphy_get_bpp( + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); + u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; + u32 pixel_clock; /* Hz */ + u32 mipi_clock; /* Hz */ + u32 ui; /* ps */ + u32 timer_period; /* ps */ + u32 t_hs_prepare_max; /* ps */ + u32 t_hs_prepare_zero_min; /* ps */ + u32 t_hs_settle; /* ps */ + u8 settle_cnt; + int ret; + + ret = camss_get_pixel_clock(&csiphy->subdev.entity, &pixel_clock); + if (ret) { + dev_err(to_device_index(csiphy, csiphy->id), + "Cannot get CSI2 transmitter's pixel clock\n"); + return 0; + } + if (!pixel_clock) { + dev_err(to_device_index(csiphy, csiphy->id), + "Got pixel clock == 0, cannot continue\n"); + return 0; + } + + mipi_clock = pixel_clock * bpp / (2 * num_lanes); + ui = div_u64(1000000000000, mipi_clock); + ui /= 2; + t_hs_prepare_max = 85000 + 6 * ui; + t_hs_prepare_zero_min = 145000 + 10 * ui; + t_hs_settle = (t_hs_prepare_max + t_hs_prepare_zero_min) / 2; + + timer_period = div_u64(1000000000000, csiphy->timer_clk_rate); + settle_cnt = t_hs_settle / timer_period; + + return settle_cnt; +} + +/* + * csiphy_stream_on - Enable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to enable streaming on CSIPHY module. + * Main configuration of CSIPHY module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_stream_on(struct csiphy_device *csiphy) +{ + struct csiphy_config *cfg = &csiphy->cfg; + u8 lane_mask = csiphy_get_lane_mask(&cfg->csi2->lane_cfg); + u8 settle_cnt; + u8 val; + int i = 0; + + settle_cnt = csiphy_settle_cnt_calc(csiphy); + if (!settle_cnt) + return -EINVAL; + + val = readl_relaxed(csiphy->base_clk_mux); + if (cfg->combo_mode && (lane_mask & 0x18) == 0x18) { + val &= ~0xf0; + val |= cfg->csid_id << 4; + } else { + val &= ~0xf; + val |= cfg->csid_id; + } + writel_relaxed(val, csiphy->base_clk_mux); + + writel_relaxed(0x1, csiphy->base + + CAMSS_CSI_PHY_GLBL_T_INIT_CFG0); + writel_relaxed(0x1, csiphy->base + + CAMSS_CSI_PHY_T_WAKEUP_CFG0); + + val = 0x1; + val |= lane_mask << 1; + writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_PWR_CFG); + + val = cfg->combo_mode << 4; + writel_relaxed(val, csiphy->base + CAMSS_CSI_PHY_GLBL_RESET); + + while (lane_mask) { + if (lane_mask & 0x1) { + writel_relaxed(0x10, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(i)); + writel_relaxed(settle_cnt, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG3(i)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_MASKn(i)); + writel_relaxed(0x3f, csiphy->base + + CAMSS_CSI_PHY_INTERRUPT_CLEARn(i)); + } + + lane_mask >>= 1; + i++; + } + + return 0; +} + +/* + * csiphy_stream_off - Disable streaming on CSIPHY module + * @csiphy: CSIPHY device + * + * Helper function to disable streaming on CSIPHY module + */ +static void csiphy_stream_off(struct csiphy_device *csiphy) +{ + u8 lane_mask = csiphy_get_lane_mask(&csiphy->cfg.csi2->lane_cfg); + int i = 0; + + while (lane_mask) { + if (lane_mask & 0x1) + writel_relaxed(0x0, csiphy->base + + CAMSS_CSI_PHY_LNn_CFG2(i)); + + lane_mask >>= 1; + i++; + } + + writel_relaxed(0x0, csiphy->base + CAMSS_CSI_PHY_GLBL_PWR_CFG); +} + + +/* + * csiphy_set_stream - Enable/disable streaming on CSIPHY module + * @sd: CSIPHY V4L2 subdevice + * @enable: Requested streaming state + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + int ret = 0; + + if (enable) + ret = csiphy_stream_on(csiphy); + else + csiphy_stream_off(csiphy); + + return ret; +} + +/* + * __csiphy_get_format - Get pointer to format structure + * @csiphy: CSIPHY device + * @cfg: V4L2 subdev pad configuration + * @pad: pad from which format is requested + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE format structure + */ +static struct v4l2_mbus_framefmt * +__csiphy_get_format(struct csiphy_device *csiphy, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&csiphy->subdev, cfg, pad); + + return &csiphy->fmt[pad]; +} + +/* + * csiphy_try_format - Handle try format by pad subdev method + * @csiphy: CSIPHY device + * @cfg: V4L2 subdev pad configuration + * @pad: pad on which format is requested + * @fmt: pointer to v4l2 format structure + * @which: wanted subdev format + */ +static void csiphy_try_format(struct csiphy_device *csiphy, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + struct v4l2_mbus_framefmt *fmt, + enum v4l2_subdev_format_whence which) +{ + unsigned int i; + + switch (pad) { + case MSM_CSIPHY_PAD_SINK: + /* Set format on sink pad */ + + for (i = 0; i < ARRAY_SIZE(csiphy_formats); i++) + if (fmt->code == csiphy_formats[i].code) + break; + + /* If not found, use UYVY as default */ + if (i >= ARRAY_SIZE(csiphy_formats)) + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + + fmt->width = clamp_t(u32, fmt->width, 1, 8191); + fmt->height = clamp_t(u32, fmt->height, 1, 8191); + + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + + break; + + case MSM_CSIPHY_PAD_SRC: + /* Set and return a format same as sink pad */ + + *fmt = *__csiphy_get_format(csiphy, cfg, MSM_CSID_PAD_SINK, + which); + + break; + } +} + +/* + * csiphy_enum_mbus_code - Handle pixel format enumeration + * @sd: CSIPHY V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @code: pointer to v4l2_subdev_mbus_code_enum structure + * return -EINVAL or zero on success + */ +static int csiphy_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + if (code->pad == MSM_CSIPHY_PAD_SINK) { + if (code->index >= ARRAY_SIZE(csiphy_formats)) + return -EINVAL; + + code->code = csiphy_formats[code->index].code; + } else { + if (code->index > 0) + return -EINVAL; + + format = __csiphy_get_format(csiphy, cfg, MSM_CSIPHY_PAD_SINK, + code->which); + + code->code = format->code; + } + + return 0; +} + +/* + * csiphy_enum_frame_size - Handle frame size enumeration + * @sd: CSIPHY V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fse: pointer to v4l2_subdev_frame_size_enum structure + * return -EINVAL or zero on success + */ +static int csiphy_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt format; + + if (fse->index != 0) + return -EINVAL; + + format.code = fse->code; + format.width = 1; + format.height = 1; + csiphy_try_format(csiphy, cfg, fse->pad, &format, fse->which); + fse->min_width = format.width; + fse->min_height = format.height; + + if (format.code != fse->code) + return -EINVAL; + + format.code = fse->code; + format.width = -1; + format.height = -1; + csiphy_try_format(csiphy, cfg, fse->pad, &format, fse->which); + fse->max_width = format.width; + fse->max_height = format.height; + + return 0; +} + +/* + * csiphy_get_format - Handle get format by pads subdev method + * @sd: CSIPHY V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int csiphy_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __csiphy_get_format(csiphy, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + fmt->format = *format; + + return 0; +} + +/* + * csiphy_set_format - Handle set format by pads subdev method + * @sd: CSIPHY V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int csiphy_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __csiphy_get_format(csiphy, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + csiphy_try_format(csiphy, cfg, fmt->pad, &fmt->format, fmt->which); + *format = fmt->format; + + /* Propagate the format from sink to source */ + if (fmt->pad == MSM_CSIPHY_PAD_SINK) { + format = __csiphy_get_format(csiphy, cfg, MSM_CSIPHY_PAD_SRC, + fmt->which); + + *format = fmt->format; + csiphy_try_format(csiphy, cfg, MSM_CSIPHY_PAD_SRC, format, + fmt->which); + } + + return 0; +} + +/* + * csiphy_init_formats - Initialize formats on all pads + * @sd: CSIPHY V4L2 subdevice + * @fh: V4L2 subdev file handle + * + * Initialize all pad formats with default values. + * + * Return 0 on success or a negative error code otherwise + */ +static int csiphy_init_formats(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh) +{ + struct v4l2_subdev_format format = { + .pad = MSM_CSIPHY_PAD_SINK, + .which = fh ? V4L2_SUBDEV_FORMAT_TRY : + V4L2_SUBDEV_FORMAT_ACTIVE, + .format = { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .width = 1920, + .height = 1080 + } + }; + + return csiphy_set_format(sd, fh ? fh->pad : NULL, &format); +} + +/* + * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources + * @csiphy: CSIPHY device + * @res: CSIPHY module resources table + * @id: CSIPHY module id + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csiphy_subdev_init(struct csiphy_device *csiphy, + const struct resources *res, u8 id) +{ + struct device *dev = to_device_index(csiphy, id); + struct platform_device *pdev = to_platform_device(dev); + struct resource *r; + int i; + int ret; + + csiphy->id = id; + csiphy->cfg.combo_mode = 0; + + /* Memory */ + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); + csiphy->base = devm_ioremap_resource(dev, r); + if (IS_ERR(csiphy->base)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(csiphy->base); + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]); + csiphy->base_clk_mux = devm_ioremap_resource(dev, r); + if (IS_ERR(csiphy->base_clk_mux)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(csiphy->base_clk_mux); + } + + /* Interrupt */ + + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, + res->interrupt[0]); + if (!r) { + dev_err(dev, "missing IRQ\n"); + return -EINVAL; + } + + csiphy->irq = r->start; + snprintf(csiphy->irq_name, sizeof(csiphy->irq_name), "%s_%s%d", + dev_name(dev), MSM_CSIPHY_NAME, csiphy->id); + ret = devm_request_irq(dev, csiphy->irq, csiphy_isr, + IRQF_TRIGGER_RISING, csiphy->irq_name, csiphy); + if (ret < 0) { + dev_err(dev, "request_irq failed: %d\n", ret); + return ret; + } + + disable_irq(csiphy->irq); + + /* Clocks */ + + csiphy->nclocks = 0; + while (res->clock[csiphy->nclocks]) + csiphy->nclocks++; + + csiphy->clock = devm_kzalloc(dev, csiphy->nclocks * + sizeof(*csiphy->clock), GFP_KERNEL); + if (!csiphy->clock) + return -ENOMEM; + + for (i = 0; i < csiphy->nclocks; i++) { + csiphy->clock[i] = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(csiphy->clock[i])) + return PTR_ERR(csiphy->clock[i]); + + if (res->clock_rate[i]) { + long clk_rate = clk_round_rate(csiphy->clock[i], + res->clock_rate[i]); + if (clk_rate < 0) { + dev_err(to_device_index(csiphy, csiphy->id), + "clk round rate failed: %ld\n", + clk_rate); + return -EINVAL; + } + ret = clk_set_rate(csiphy->clock[i], clk_rate); + if (ret < 0) { + dev_err(to_device_index(csiphy, csiphy->id), + "clk set rate failed: %d\n", ret); + return ret; + } + + if (!strcmp(res->clock[i], "csiphy0_timer") || + !strcmp(res->clock[i], "csiphy1_timer")) + csiphy->timer_clk_rate = clk_rate; + } + } + + return 0; +} + +/* + * csiphy_link_setup - Setup CSIPHY connections + * @entity: Pointer to media entity structure + * @local: Pointer to local pad + * @remote: Pointer to remote pad + * @flags: Link flags + * + * Rreturn 0 on success + */ +static int csiphy_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + if ((local->flags & MEDIA_PAD_FL_SOURCE) && + (flags & MEDIA_LNK_FL_ENABLED)) { + struct v4l2_subdev *sd; + struct csiphy_device *csiphy; + struct csid_device *csid; + + if (media_entity_remote_pad(local)) + return -EBUSY; + + sd = media_entity_to_v4l2_subdev(entity); + csiphy = v4l2_get_subdevdata(sd); + + sd = media_entity_to_v4l2_subdev(remote->entity); + csid = v4l2_get_subdevdata(sd); + + csiphy->cfg.csid_id = csid->id; + } + + return 0; +} + +static const struct v4l2_subdev_core_ops csiphy_core_ops = { + .s_power = csiphy_set_power, +}; + +static const struct v4l2_subdev_video_ops csiphy_video_ops = { + .s_stream = csiphy_set_stream, +}; + +static const struct v4l2_subdev_pad_ops csiphy_pad_ops = { + .enum_mbus_code = csiphy_enum_mbus_code, + .enum_frame_size = csiphy_enum_frame_size, + .get_fmt = csiphy_get_format, + .set_fmt = csiphy_set_format, +}; + +static const struct v4l2_subdev_ops csiphy_v4l2_ops = { + .core = &csiphy_core_ops, + .video = &csiphy_video_ops, + .pad = &csiphy_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops csiphy_v4l2_internal_ops = { + .open = csiphy_init_formats, +}; + +static const struct media_entity_operations csiphy_media_ops = { + .link_setup = csiphy_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +/* + * msm_csiphy_register_entity - Register subdev node for CSIPHY module + * @csiphy: CSIPHY device + * @v4l2_dev: V4L2 device + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csiphy_register_entity(struct csiphy_device *csiphy, + struct v4l2_device *v4l2_dev) +{ + struct v4l2_subdev *sd = &csiphy->subdev; + struct media_pad *pads = csiphy->pads; + struct device *dev = to_device_index(csiphy, csiphy->id); + int ret; + + v4l2_subdev_init(sd, &csiphy_v4l2_ops); + sd->internal_ops = &csiphy_v4l2_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", + MSM_CSIPHY_NAME, csiphy->id); + v4l2_set_subdevdata(sd, csiphy); + + ret = csiphy_init_formats(sd, NULL); + if (ret < 0) { + dev_err(dev, "Failed to init format: %d\n", ret); + return ret; + } + + pads[MSM_CSIPHY_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + pads[MSM_CSIPHY_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; + + sd->entity.function = MEDIA_ENT_F_IO_V4L; + sd->entity.ops = &csiphy_media_ops; + ret = media_entity_pads_init(&sd->entity, MSM_CSIPHY_PADS_NUM, pads); + if (ret < 0) { + dev_err(dev, "Failed to init media entity: %d\n", ret); + return ret; + } + + ret = v4l2_device_register_subdev(v4l2_dev, sd); + if (ret < 0) { + dev_err(dev, "Failed to register subdev: %d\n", ret); + media_entity_cleanup(&sd->entity); + } + + return ret; +} + +/* + * msm_csiphy_unregister_entity - Unregister CSIPHY module subdev node + * @csiphy: CSIPHY device + */ +void msm_csiphy_unregister_entity(struct csiphy_device *csiphy) +{ + v4l2_device_unregister_subdev(&csiphy->subdev); + media_entity_cleanup(&csiphy->subdev.entity); +} diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h new file mode 100644 index 000000000000..e886e6d88fd2 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h @@ -0,0 +1,77 @@ +/* + * camss-csiphy.h + * + * Qualcomm MSM Camera Subsystem - CSIPHY Module + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2016-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_CSIPHY_H +#define QC_MSM_CAMSS_CSIPHY_H + +#include +#include +#include +#include +#include + +#define MSM_CSIPHY_PAD_SINK 0 +#define MSM_CSIPHY_PAD_SRC 1 +#define MSM_CSIPHY_PADS_NUM 2 + +struct csiphy_lane { + u8 pos; + u8 pol; +}; + +struct csiphy_lanes_cfg { + int num_data; + struct csiphy_lane *data; + struct csiphy_lane clk; +}; + +struct csiphy_csi2_cfg { + struct csiphy_lanes_cfg lane_cfg; +}; + +struct csiphy_config { + u8 combo_mode; + u8 csid_id; + struct csiphy_csi2_cfg *csi2; +}; + +struct csiphy_device { + u8 id; + struct v4l2_subdev subdev; + struct media_pad pads[MSM_CSIPHY_PADS_NUM]; + void __iomem *base; + void __iomem *base_clk_mux; + u32 irq; + char irq_name[30]; + struct clk **clock; + int nclocks; + u32 timer_clk_rate; + struct csiphy_config cfg; + struct v4l2_mbus_framefmt fmt[MSM_CSIPHY_PADS_NUM]; +}; + +struct resources; + +int msm_csiphy_subdev_init(struct csiphy_device *csiphy, + const struct resources *res, u8 id); + +int msm_csiphy_register_entity(struct csiphy_device *csiphy, + struct v4l2_device *v4l2_dev); + +void msm_csiphy_unregister_entity(struct csiphy_device *csiphy); + +#endif /* QC_MSM_CAMSS_CSIPHY_H */ -- cgit v1.2.3 From 0c277ec68561f75cdbe75aa9a03cba286cec2797 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:03 -0400 Subject: media: camss: Add CSID files These files control the CSID modules which handle the protocol and application layer of the CSI2 receivers. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-csid.c | 1003 ++++++++++++++++++++ .../media/platform/qcom/camss-8x16/camss-csid.h | 82 ++ 2 files changed, 1085 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-csid.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-csid.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss-8x16/camss-csid.c new file mode 100644 index 000000000000..5c09e83e4a2b --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c @@ -0,0 +1,1003 @@ +/* + * camss-csid.c + * + * Qualcomm MSM Camera Subsystem - CSID Module + * + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camss-csid.h" +#include "camss.h" + +#define MSM_CSID_NAME "msm_csid" + +#define CAMSS_CSID_HW_VERSION 0x0 +#define CAMSS_CSID_CORE_CTRL_0 0x004 +#define CAMSS_CSID_CORE_CTRL_1 0x008 +#define CAMSS_CSID_RST_CMD 0x00c +#define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n)) +#define CAMSS_CSID_CID_n_CFG(n) (0x020 + 0x4 * (n)) +#define CAMSS_CSID_IRQ_CLEAR_CMD 0x060 +#define CAMSS_CSID_IRQ_MASK 0x064 +#define CAMSS_CSID_IRQ_STATUS 0x068 +#define CAMSS_CSID_TG_CTRL 0x0a0 +#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436 +#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437 +#define CAMSS_CSID_TG_VC_CFG 0x0a4 +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f +#define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0ac + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b0 + 0xc * (n)) +#define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0b4 + 0xc * (n)) + +#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12 +#define DATA_TYPE_YUV422_8BIT 0x1e +#define DATA_TYPE_RAW_6BIT 0x28 +#define DATA_TYPE_RAW_8BIT 0x2a +#define DATA_TYPE_RAW_10BIT 0x2b +#define DATA_TYPE_RAW_12BIT 0x2c + +#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0 +#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1 +#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2 +#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3 + +#define CSID_RESET_TIMEOUT_MS 500 + +struct csid_fmts { + u32 code; + u8 data_type; + u8 decode_format; + u8 bpp; +}; + +static const struct csid_fmts csid_input_fmts[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + DATA_TYPE_YUV422_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 16, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + DATA_TYPE_RAW_8BIT, + DECODE_FORMAT_UNCOMPRESSED_8_BIT, + 8, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + DATA_TYPE_RAW_10BIT, + DECODE_FORMAT_UNCOMPRESSED_10_BIT, + 10, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + DATA_TYPE_RAW_12BIT, + DECODE_FORMAT_UNCOMPRESSED_12_BIT, + 12, + } +}; + +static const struct csid_fmts *csid_get_fmt_entry(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(csid_input_fmts); i++) + if (code == csid_input_fmts[i].code) + return &csid_input_fmts[i]; + + WARN(1, "Unknown format\n"); + + return &csid_input_fmts[0]; +} + +/* + * csid_isr - CSID module interrupt handler + * @irq: Interrupt line + * @dev: CSID device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t csid_isr(int irq, void *dev) +{ + struct csid_device *csid = dev; + u32 value; + + value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS); + writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD); + + if ((value >> 11) & 0x1) + complete(&csid->reset_complete); + + return IRQ_HANDLED; +} + +/* + * csid_reset - Trigger reset on CSID module and wait to complete + * @csid: CSID device + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_reset(struct csid_device *csid) +{ + unsigned long time; + + reinit_completion(&csid->reset_complete); + + writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD); + + time = wait_for_completion_timeout(&csid->reset_complete, + msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(to_device_index(csid, csid->id), + "CSID reset timeout\n"); + return -EIO; + } + + return 0; +} + +/* + * csid_set_power - Power on/off CSID module + * @sd: CSID V4L2 subdevice + * @on: Requested power state + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_set_power(struct v4l2_subdev *sd, int on) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct device *dev = to_device_index(csid, csid->id); + int ret; + + if (on) { + u32 hw_version; + + ret = regulator_enable(csid->vdda); + if (ret < 0) + return ret; + + ret = camss_enable_clocks(csid->nclocks, csid->clock, dev); + if (ret < 0) { + regulator_disable(csid->vdda); + return ret; + } + + enable_irq(csid->irq); + + ret = csid_reset(csid); + if (ret < 0) { + disable_irq(csid->irq); + camss_disable_clocks(csid->nclocks, csid->clock); + regulator_disable(csid->vdda); + return ret; + } + + hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION); + dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version); + } else { + disable_irq(csid->irq); + camss_disable_clocks(csid->nclocks, csid->clock); + ret = regulator_disable(csid->vdda); + } + + return ret; +} + +/* + * csid_set_stream - Enable/disable streaming on CSID module + * @sd: CSID V4L2 subdevice + * @enable: Requested streaming state + * + * Main configuration of CSID module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct csid_testgen_config *tg = &csid->testgen; + u32 val; + + if (enable) { + u8 vc = 0; /* Virtual Channel 0 */ + u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */ + u8 dt, dt_shift, df; + int ret; + + ret = v4l2_ctrl_handler_setup(&csid->ctrls); + if (ret < 0) { + dev_err(to_device_index(csid, csid->id), + "could not sync v4l2 controls: %d\n", ret); + return ret; + } + + if (!tg->enabled && + !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK])) + return -ENOLINK; + + dt = csid_get_fmt_entry(csid->fmt[MSM_CSID_PAD_SRC].code)-> + data_type; + + if (tg->enabled) { + /* Config Test Generator */ + struct v4l2_mbus_framefmt *f = + &csid->fmt[MSM_CSID_PAD_SRC]; + u8 bpp = csid_get_fmt_entry(f->code)->bpp; + u32 num_bytes_per_line = f->width * bpp / 8; + u32 num_lines = f->height; + + /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */ + /* 1:0 VC */ + val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) | + ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13); + writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG); + + /* 28:16 bytes per lines, 12:0 num of lines */ + val = ((num_bytes_per_line & 0x1fff) << 16) | + (num_lines & 0x1fff); + writel_relaxed(val, csid->base + + CAMSS_CSID_TG_DT_n_CGG_0(0)); + + /* 5:0 data type */ + val = dt; + writel_relaxed(val, csid->base + + CAMSS_CSID_TG_DT_n_CGG_1(0)); + + /* 2:0 output test pattern */ + val = tg->payload_mode; + writel_relaxed(val, csid->base + + CAMSS_CSID_TG_DT_n_CGG_2(0)); + } else { + struct csid_phy_config *phy = &csid->phy; + + val = phy->lane_cnt - 1; + val |= phy->lane_assign << 4; + + writel_relaxed(val, + csid->base + CAMSS_CSID_CORE_CTRL_0); + + val = phy->csiphy_id << 17; + val |= 0x9; + + writel_relaxed(val, + csid->base + CAMSS_CSID_CORE_CTRL_1); + } + + /* Config LUT */ + + dt_shift = (cid % 4) * 8; + df = csid_get_fmt_entry(csid->fmt[MSM_CSID_PAD_SINK].code)-> + decode_format; + + val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + val &= ~(0xff << dt_shift); + val |= dt << dt_shift; + writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc)); + + val = (df << 4) | 0x3; + writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid)); + + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_ENABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } else { + if (tg->enabled) { + val = CAMSS_CSID_TG_CTRL_DISABLE; + writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL); + } + } + + return 0; +} + +/* + * __csid_get_format - Get pointer to format structure + * @csid: CSID device + * @cfg: V4L2 subdev pad configuration + * @pad: pad from which format is requested + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE format structure + */ +static struct v4l2_mbus_framefmt * +__csid_get_format(struct csid_device *csid, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&csid->subdev, cfg, pad); + + return &csid->fmt[pad]; +} + +/* + * csid_try_format - Handle try format by pad subdev method + * @csid: CSID device + * @cfg: V4L2 subdev pad configuration + * @pad: pad on which format is requested + * @fmt: pointer to v4l2 format structure + * @which: wanted subdev format + */ +static void csid_try_format(struct csid_device *csid, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + struct v4l2_mbus_framefmt *fmt, + enum v4l2_subdev_format_whence which) +{ + unsigned int i; + + switch (pad) { + case MSM_CSID_PAD_SINK: + /* Set format on sink pad */ + + for (i = 0; i < ARRAY_SIZE(csid_input_fmts); i++) + if (fmt->code == csid_input_fmts[i].code) + break; + + /* If not found, use UYVY as default */ + if (i >= ARRAY_SIZE(csid_input_fmts)) + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + + fmt->width = clamp_t(u32, fmt->width, 1, 8191); + fmt->height = clamp_t(u32, fmt->height, 1, 8191); + + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + + break; + + case MSM_CSID_PAD_SRC: + if (csid->testgen_mode->cur.val == 0) { + /* Test generator is disabled, keep pad formats */ + /* in sync - set and return a format same as sink pad */ + struct v4l2_mbus_framefmt format; + + format = *__csid_get_format(csid, cfg, + MSM_CSID_PAD_SINK, which); + *fmt = format; + } else { + /* Test generator is enabled, set format on source*/ + /* pad to allow test generator usage */ + + for (i = 0; i < ARRAY_SIZE(csid_input_fmts); i++) + if (csid_input_fmts[i].code == fmt->code) + break; + + /* If not found, use UYVY as default */ + if (i >= ARRAY_SIZE(csid_input_fmts)) + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + + fmt->width = clamp_t(u32, fmt->width, 1, 8191); + fmt->height = clamp_t(u32, fmt->height, 1, 8191); + + fmt->field = V4L2_FIELD_NONE; + } + break; + } + + fmt->colorspace = V4L2_COLORSPACE_SRGB; +} + +/* + * csid_enum_mbus_code - Handle pixel format enumeration + * @sd: CSID V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @code: pointer to v4l2_subdev_mbus_code_enum structure + * return -EINVAL or zero on success + */ +static int csid_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + if (code->pad == MSM_CSID_PAD_SINK) { + if (code->index >= ARRAY_SIZE(csid_input_fmts)) + return -EINVAL; + + code->code = csid_input_fmts[code->index].code; + } else { + if (csid->testgen_mode->cur.val == 0) { + if (code->index > 0) + return -EINVAL; + + format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SINK, + code->which); + + code->code = format->code; + } else { + if (code->index >= ARRAY_SIZE(csid_input_fmts)) + return -EINVAL; + + code->code = csid_input_fmts[code->index].code; + } + } + + return 0; +} + +/* + * csid_enum_frame_size - Handle frame size enumeration + * @sd: CSID V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fse: pointer to v4l2_subdev_frame_size_enum structure + * return -EINVAL or zero on success + */ +static int csid_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt format; + + if (fse->index != 0) + return -EINVAL; + + format.code = fse->code; + format.width = 1; + format.height = 1; + csid_try_format(csid, cfg, fse->pad, &format, fse->which); + fse->min_width = format.width; + fse->min_height = format.height; + + if (format.code != fse->code) + return -EINVAL; + + format.code = fse->code; + format.width = -1; + format.height = -1; + csid_try_format(csid, cfg, fse->pad, &format, fse->which); + fse->max_width = format.width; + fse->max_height = format.height; + + return 0; +} + +/* + * csid_get_format - Handle get format by pads subdev method + * @sd: CSID V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int csid_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __csid_get_format(csid, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + fmt->format = *format; + + return 0; +} + +/* + * csid_set_format - Handle set format by pads subdev method + * @sd: CSID V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int csid_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct csid_device *csid = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __csid_get_format(csid, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + csid_try_format(csid, cfg, fmt->pad, &fmt->format, fmt->which); + *format = fmt->format; + + /* Propagate the format from sink to source */ + if (fmt->pad == MSM_CSID_PAD_SINK) { + format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SRC, + fmt->which); + + *format = fmt->format; + csid_try_format(csid, cfg, MSM_CSID_PAD_SRC, format, + fmt->which); + } + + return 0; +} + +/* + * csid_init_formats - Initialize formats on all pads + * @sd: CSID V4L2 subdevice + * @fh: V4L2 subdev file handle + * + * Initialize all pad formats with default values. + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_subdev_format format = { + .pad = MSM_CSID_PAD_SINK, + .which = fh ? V4L2_SUBDEV_FORMAT_TRY : + V4L2_SUBDEV_FORMAT_ACTIVE, + .format = { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .width = 1920, + .height = 1080 + } + }; + + return csid_set_format(sd, fh ? fh->pad : NULL, &format); +} + +static const char * const csid_test_pattern_menu[] = { + "Disabled", + "Incrementing", + "Alternating 0x55/0xAA", + "All Zeros 0x00", + "All Ones 0xFF", + "Pseudo-random Data", +}; + +/* + * csid_set_test_pattern - Set test generator's pattern mode + * @csid: CSID device + * @value: desired test pattern mode + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_set_test_pattern(struct csid_device *csid, s32 value) +{ + struct csid_testgen_config *tg = &csid->testgen; + + /* If CSID is linked to CSIPHY, do not allow to enable test generator */ + if (value && media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK])) + return -EBUSY; + + tg->enabled = !!value; + + switch (value) { + case 1: + tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING; + break; + case 2: + tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA; + break; + case 3: + tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES; + break; + case 4: + tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES; + break; + case 5: + tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM; + break; + } + + return 0; +} + +/* + * csid_s_ctrl - Handle set control subdev method + * @ctrl: pointer to v4l2 control structure + * + * Return 0 on success or a negative error code otherwise + */ +static int csid_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct csid_device *csid = container_of(ctrl->handler, + struct csid_device, ctrls); + int ret = -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_TEST_PATTERN: + ret = csid_set_test_pattern(csid, ctrl->val); + break; + } + + return ret; +} + +static const struct v4l2_ctrl_ops csid_ctrl_ops = { + .s_ctrl = csid_s_ctrl, +}; + +/* + * msm_csid_subdev_init - Initialize CSID device structure and resources + * @csid: CSID device + * @res: CSID module resources table + * @id: CSID module id + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csid_subdev_init(struct csid_device *csid, + const struct resources *res, u8 id) +{ + struct device *dev = to_device_index(csid, id); + struct platform_device *pdev = to_platform_device(dev); + struct resource *r; + int i; + int ret; + + csid->id = id; + + /* Memory */ + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); + csid->base = devm_ioremap_resource(dev, r); + if (IS_ERR(csid->base)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(csid->base); + } + + /* Interrupt */ + + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, + res->interrupt[0]); + if (!r) { + dev_err(dev, "missing IRQ\n"); + return -EINVAL; + } + + csid->irq = r->start; + snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d", + dev_name(dev), MSM_CSID_NAME, csid->id); + ret = devm_request_irq(dev, csid->irq, csid_isr, + IRQF_TRIGGER_RISING, csid->irq_name, csid); + if (ret < 0) { + dev_err(dev, "request_irq failed: %d\n", ret); + return ret; + } + + disable_irq(csid->irq); + + /* Clocks */ + + csid->nclocks = 0; + while (res->clock[csid->nclocks]) + csid->nclocks++; + + csid->clock = devm_kzalloc(dev, csid->nclocks * sizeof(*csid->clock), + GFP_KERNEL); + if (!csid->clock) + return -ENOMEM; + + for (i = 0; i < csid->nclocks; i++) { + csid->clock[i] = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(csid->clock[i])) + return PTR_ERR(csid->clock[i]); + + if (res->clock_rate[i]) { + long clk_rate = clk_round_rate(csid->clock[i], + res->clock_rate[i]); + if (clk_rate < 0) { + dev_err(to_device_index(csid, csid->id), + "clk round rate failed: %ld\n", + clk_rate); + return -EINVAL; + } + ret = clk_set_rate(csid->clock[i], clk_rate); + if (ret < 0) { + dev_err(to_device_index(csid, csid->id), + "clk set rate failed: %d\n", ret); + return ret; + } + } + } + + /* Regulator */ + + csid->vdda = devm_regulator_get(dev, res->regulator[0]); + if (IS_ERR(csid->vdda)) { + dev_err(dev, "could not get regulator\n"); + return PTR_ERR(csid->vdda); + } + + init_completion(&csid->reset_complete); + + return 0; +} + +/* + * msm_csid_get_csid_id - Get CSID HW module id + * @entity: Pointer to CSID media entity structure + * @id: Return CSID HW module id here + */ +void msm_csid_get_csid_id(struct media_entity *entity, u8 *id) +{ + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct csid_device *csid = v4l2_get_subdevdata(sd); + + *id = csid->id; +} + +/* + * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter + * @lane_cfg - CSI2 lane configuration + * + * Return lane assign + */ +static u32 csid_get_lane_assign(struct csiphy_lanes_cfg *lane_cfg) +{ + u32 lane_assign = 0; + int i; + + for (i = 0; i < lane_cfg->num_data; i++) + lane_assign |= lane_cfg->data[i].pos << (i * 4); + + return lane_assign; +} + +/* + * csid_link_setup - Setup CSID connections + * @entity: Pointer to media entity structure + * @local: Pointer to local pad + * @remote: Pointer to remote pad + * @flags: Link flags + * + * Return 0 on success + */ +static int csid_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + if (flags & MEDIA_LNK_FL_ENABLED) + if (media_entity_remote_pad(local)) + return -EBUSY; + + if ((local->flags & MEDIA_PAD_FL_SINK) && + (flags & MEDIA_LNK_FL_ENABLED)) { + struct v4l2_subdev *sd; + struct csid_device *csid; + struct csiphy_device *csiphy; + struct csiphy_lanes_cfg *lane_cfg; + struct v4l2_subdev_format format = { 0 }; + + sd = media_entity_to_v4l2_subdev(entity); + csid = v4l2_get_subdevdata(sd); + + /* If test generator is enabled */ + /* do not allow a link from CSIPHY to CSID */ + if (csid->testgen_mode->cur.val != 0) + return -EBUSY; + + sd = media_entity_to_v4l2_subdev(remote->entity); + csiphy = v4l2_get_subdevdata(sd); + + /* If a sensor is not linked to CSIPHY */ + /* do no allow a link from CSIPHY to CSID */ + if (!csiphy->cfg.csi2) + return -EPERM; + + csid->phy.csiphy_id = csiphy->id; + + lane_cfg = &csiphy->cfg.csi2->lane_cfg; + csid->phy.lane_cnt = lane_cfg->num_data; + csid->phy.lane_assign = csid_get_lane_assign(lane_cfg); + + /* Reset format on source pad to sink pad format */ + format.pad = MSM_CSID_PAD_SRC; + format.which = V4L2_SUBDEV_FORMAT_ACTIVE; + csid_set_format(&csid->subdev, NULL, &format); + } + + return 0; +} + +static const struct v4l2_subdev_core_ops csid_core_ops = { + .s_power = csid_set_power, +}; + +static const struct v4l2_subdev_video_ops csid_video_ops = { + .s_stream = csid_set_stream, +}; + +static const struct v4l2_subdev_pad_ops csid_pad_ops = { + .enum_mbus_code = csid_enum_mbus_code, + .enum_frame_size = csid_enum_frame_size, + .get_fmt = csid_get_format, + .set_fmt = csid_set_format, +}; + +static const struct v4l2_subdev_ops csid_v4l2_ops = { + .core = &csid_core_ops, + .video = &csid_video_ops, + .pad = &csid_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops csid_v4l2_internal_ops = { + .open = csid_init_formats, +}; + +static const struct media_entity_operations csid_media_ops = { + .link_setup = csid_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +/* + * msm_csid_register_entity - Register subdev node for CSID module + * @csid: CSID device + * @v4l2_dev: V4L2 device + * + * Return 0 on success or a negative error code otherwise + */ +int msm_csid_register_entity(struct csid_device *csid, + struct v4l2_device *v4l2_dev) +{ + struct v4l2_subdev *sd = &csid->subdev; + struct media_pad *pads = csid->pads; + struct device *dev = to_device_index(csid, csid->id); + int ret; + + v4l2_subdev_init(sd, &csid_v4l2_ops); + sd->internal_ops = &csid_v4l2_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", + MSM_CSID_NAME, csid->id); + v4l2_set_subdevdata(sd, csid); + + ret = v4l2_ctrl_handler_init(&csid->ctrls, 1); + if (ret < 0) { + dev_err(dev, "Failed to init ctrl handler: %d\n", ret); + return ret; + } + + csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls, + &csid_ctrl_ops, V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0, + csid_test_pattern_menu); + + if (csid->ctrls.error) { + dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error); + ret = csid->ctrls.error; + goto free_ctrl; + } + + csid->subdev.ctrl_handler = &csid->ctrls; + + ret = csid_init_formats(sd, NULL); + if (ret < 0) { + dev_err(dev, "Failed to init format: %d\n", ret); + goto free_ctrl; + } + + pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; + + sd->entity.function = MEDIA_ENT_F_IO_V4L; + sd->entity.ops = &csid_media_ops; + ret = media_entity_pads_init(&sd->entity, MSM_CSID_PADS_NUM, pads); + if (ret < 0) { + dev_err(dev, "Failed to init media entity: %d\n", ret); + goto free_ctrl; + } + + ret = v4l2_device_register_subdev(v4l2_dev, sd); + if (ret < 0) { + dev_err(dev, "Failed to register subdev: %d\n", ret); + goto media_cleanup; + } + + return 0; + +media_cleanup: + media_entity_cleanup(&sd->entity); +free_ctrl: + v4l2_ctrl_handler_free(&csid->ctrls); + + return ret; +} + +/* + * msm_csid_unregister_entity - Unregister CSID module subdev node + * @csid: CSID device + */ +void msm_csid_unregister_entity(struct csid_device *csid) +{ + v4l2_device_unregister_subdev(&csid->subdev); + media_entity_cleanup(&csid->subdev.entity); + v4l2_ctrl_handler_free(&csid->ctrls); +} diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.h b/drivers/media/platform/qcom/camss-8x16/camss-csid.h new file mode 100644 index 000000000000..3186c11ac07d --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.h @@ -0,0 +1,82 @@ +/* + * camss-csid.h + * + * Qualcomm MSM Camera Subsystem - CSID Module + * + * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_CSID_H +#define QC_MSM_CAMSS_CSID_H + +#include +#include +#include +#include +#include +#include + +#define MSM_CSID_PAD_SINK 0 +#define MSM_CSID_PAD_SRC 1 +#define MSM_CSID_PADS_NUM 2 + +enum csid_payload_mode { + CSID_PAYLOAD_MODE_INCREMENTING = 0, + CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 1, + CSID_PAYLOAD_MODE_ALL_ZEROES = 2, + CSID_PAYLOAD_MODE_ALL_ONES = 3, + CSID_PAYLOAD_MODE_RANDOM = 4, + CSID_PAYLOAD_MODE_USER_SPECIFIED = 5, +}; + +struct csid_testgen_config { + u8 enabled; + enum csid_payload_mode payload_mode; +}; + +struct csid_phy_config { + u8 csiphy_id; + u8 lane_cnt; + u32 lane_assign; +}; + +struct csid_device { + u8 id; + struct v4l2_subdev subdev; + struct media_pad pads[MSM_CSID_PADS_NUM]; + void __iomem *base; + u32 irq; + char irq_name[30]; + struct clk **clock; + int nclocks; + struct regulator *vdda; + struct completion reset_complete; + struct csid_testgen_config testgen; + struct csid_phy_config phy; + struct v4l2_mbus_framefmt fmt[MSM_CSID_PADS_NUM]; + struct v4l2_ctrl_handler ctrls; + struct v4l2_ctrl *testgen_mode; +}; + +struct resources; + +int msm_csid_subdev_init(struct csid_device *csid, + const struct resources *res, u8 id); + +int msm_csid_register_entity(struct csid_device *csid, + struct v4l2_device *v4l2_dev); + +void msm_csid_unregister_entity(struct csid_device *csid); + +void msm_csid_get_csid_id(struct media_entity *entity, u8 *id); + +#endif /* QC_MSM_CAMSS_CSID_H */ -- cgit v1.2.3 From a3a2e82d28b232f1e4d704ddc5cfab7fdc85eab5 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:04 -0400 Subject: media: camss: Add ISPIF files These files control the ISPIF module which handles the routing of the data streams from the CSIDs to the inputs of the VFE. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-ispif.c | 1164 ++++++++++++++++++++ .../media/platform/qcom/camss-8x16/camss-ispif.h | 85 ++ 2 files changed, 1249 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-ispif.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-ispif.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c new file mode 100644 index 000000000000..b0478117585e --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -0,0 +1,1164 @@ +/* + * camss-ispif.c + * + * Qualcomm MSM Camera Subsystem - ISPIF Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camss-ispif.h" +#include "camss.h" + +#define MSM_ISPIF_NAME "msm_ispif" + +#define ispif_line_array(ptr_line) \ + ((const struct ispif_line (*)[]) &(ptr_line[-(ptr_line->id)])) + +#define to_ispif(ptr_line) \ + container_of(ispif_line_array(ptr_line), struct ispif_device, ptr_line) + +#define ISPIF_RST_CMD_0 0x008 +#define ISPIF_RST_CMD_0_STROBED_RST_EN (1 << 0) +#define ISPIF_RST_CMD_0_MISC_LOGIC_RST (1 << 1) +#define ISPIF_RST_CMD_0_SW_REG_RST (1 << 2) +#define ISPIF_RST_CMD_0_PIX_INTF_0_CSID_RST (1 << 3) +#define ISPIF_RST_CMD_0_PIX_INTF_0_VFE_RST (1 << 4) +#define ISPIF_RST_CMD_0_PIX_INTF_1_CSID_RST (1 << 5) +#define ISPIF_RST_CMD_0_PIX_INTF_1_VFE_RST (1 << 6) +#define ISPIF_RST_CMD_0_RDI_INTF_0_CSID_RST (1 << 7) +#define ISPIF_RST_CMD_0_RDI_INTF_0_VFE_RST (1 << 8) +#define ISPIF_RST_CMD_0_RDI_INTF_1_CSID_RST (1 << 9) +#define ISPIF_RST_CMD_0_RDI_INTF_1_VFE_RST (1 << 10) +#define ISPIF_RST_CMD_0_RDI_INTF_2_CSID_RST (1 << 11) +#define ISPIF_RST_CMD_0_RDI_INTF_2_VFE_RST (1 << 12) +#define ISPIF_RST_CMD_0_PIX_OUTPUT_0_MISR_RST (1 << 16) +#define ISPIF_RST_CMD_0_RDI_OUTPUT_0_MISR_RST (1 << 17) +#define ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST (1 << 18) +#define ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST (1 << 19) +#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x01c +#define ISPIF_VFE_m_CTRL_0(m) (0x200 + 0x200 * (m)) +#define ISPIF_VFE_m_CTRL_0_PIX0_LINE_BUF_EN (1 << 6) +#define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE 0x00001249 +#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK 0x00001fff +#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE 0x02492000 +#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK 0x03ffe000 +#define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20c + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE 0x00001249 +#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK 0x00001fff +#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE 0x02492000 +#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK 0x03ffe000 +#define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE 0x00001249 +#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK 0x00001fff +#define ISPIF_VFE_m_IRQ_STATUS_0(m) (0x21c + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW (1 << 12) +#define ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW (1 << 25) +#define ISPIF_VFE_m_IRQ_STATUS_1(m) (0x220 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW (1 << 12) +#define ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW (1 << 25) +#define ISPIF_VFE_m_IRQ_STATUS_2(m) (0x224 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW (1 << 12) +#define ISPIF_VFE_m_IRQ_CLEAR_0(m) (0x230 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_CLEAR_1(m) (0x234 + 0x200 * (m)) +#define ISPIF_VFE_m_IRQ_CLEAR_2(m) (0x238 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_INPUT_SEL(m) (0x244 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_CMD_0(m) (0x248 + 0x200 * (m)) +#define ISPIF_VFE_m_INTF_CMD_1(m) (0x24c + 0x200 * (m)) +#define ISPIF_VFE_m_PIX_INTF_n_CID_MASK(m, n) \ + (0x254 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_CID_MASK(m, n) \ + (0x264 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_PIX_INTF_n_STATUS(m, n) \ + (0x2c0 + 0x200 * (m) + 0x4 * (n)) +#define ISPIF_VFE_m_RDI_INTF_n_STATUS(m, n) \ + (0x2d0 + 0x200 * (m) + 0x4 * (n)) + +#define CSI_PIX_CLK_MUX_SEL 0x000 +#define CSI_RDI_CLK_MUX_SEL 0x008 + +#define ISPIF_TIMEOUT_SLEEP_US 1000 +#define ISPIF_TIMEOUT_ALL_US 1000000 +#define ISPIF_RESET_TIMEOUT_MS 500 + +enum ispif_intf_cmd { + CMD_DISABLE_FRAME_BOUNDARY = 0x0, + CMD_ENABLE_FRAME_BOUNDARY = 0x1, + CMD_DISABLE_IMMEDIATELY = 0x2, + CMD_ALL_DISABLE_IMMEDIATELY = 0xaaaaaaaa, + CMD_ALL_NO_CHANGE = 0xffffffff, +}; + +static const u32 ispif_formats[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, +}; + +/* + * ispif_isr - ISPIF module interrupt handler + * @irq: Interrupt line + * @dev: ISPIF device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t ispif_isr(int irq, void *dev) +{ + struct ispif_device *ispif = dev; + u32 value0, value1, value2; + + value0 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(0)); + value1 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(0)); + value2 = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(0)); + + writel_relaxed(value0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(0)); + writel_relaxed(value1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(0)); + writel_relaxed(value2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(0)); + + writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); + + if ((value0 >> 27) & 0x1) + complete(&ispif->reset_complete); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix0 overflow\n"); + + if (unlikely(value0 & ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi0 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 pix1 overflow\n"); + + if (unlikely(value1 & ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi1 overflow\n"); + + if (unlikely(value2 & ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW)) + dev_err_ratelimited(to_device(ispif), "VFE0 rdi2 overflow\n"); + + return IRQ_HANDLED; +} + +/* + * ispif_reset - Trigger reset on ISPIF module and wait to complete + * @ispif: ISPIF device + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_reset(struct ispif_device *ispif) +{ + unsigned long time; + u32 val; + int ret; + + ret = camss_enable_clocks(ispif->nclocks_for_reset, + ispif->clock_for_reset, + to_device(ispif)); + if (ret < 0) + return ret; + + reinit_completion(&ispif->reset_complete); + + val = ISPIF_RST_CMD_0_STROBED_RST_EN | + ISPIF_RST_CMD_0_MISC_LOGIC_RST | + ISPIF_RST_CMD_0_SW_REG_RST | + ISPIF_RST_CMD_0_PIX_INTF_0_CSID_RST | + ISPIF_RST_CMD_0_PIX_INTF_0_VFE_RST | + ISPIF_RST_CMD_0_PIX_INTF_1_CSID_RST | + ISPIF_RST_CMD_0_PIX_INTF_1_VFE_RST | + ISPIF_RST_CMD_0_RDI_INTF_0_CSID_RST | + ISPIF_RST_CMD_0_RDI_INTF_0_VFE_RST | + ISPIF_RST_CMD_0_RDI_INTF_1_CSID_RST | + ISPIF_RST_CMD_0_RDI_INTF_1_VFE_RST | + ISPIF_RST_CMD_0_RDI_INTF_2_CSID_RST | + ISPIF_RST_CMD_0_RDI_INTF_2_VFE_RST | + ISPIF_RST_CMD_0_PIX_OUTPUT_0_MISR_RST | + ISPIF_RST_CMD_0_RDI_OUTPUT_0_MISR_RST | + ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST | + ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST; + + writel_relaxed(val, ispif->base + ISPIF_RST_CMD_0); + + time = wait_for_completion_timeout(&ispif->reset_complete, + msecs_to_jiffies(ISPIF_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(to_device(ispif), "ISPIF reset timeout\n"); + return -EIO; + } + + camss_disable_clocks(ispif->nclocks_for_reset, ispif->clock_for_reset); + + return 0; +} + +/* + * ispif_set_power - Power on/off ISPIF module + * @sd: ISPIF V4L2 subdevice + * @on: Requested power state + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_set_power(struct v4l2_subdev *sd, int on) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct ispif_device *ispif = to_ispif(line); + struct device *dev = to_device(ispif); + int ret = 0; + + mutex_lock(&ispif->power_lock); + + if (on) { + if (ispif->power_count) { + /* Power is already on */ + ispif->power_count++; + goto exit; + } + + ret = camss_enable_clocks(ispif->nclocks, ispif->clock, dev); + if (ret < 0) + goto exit; + + ret = ispif_reset(ispif); + if (ret < 0) { + camss_disable_clocks(ispif->nclocks, ispif->clock); + goto exit; + } + + ispif->intf_cmd[line->vfe_id].cmd_0 = CMD_ALL_NO_CHANGE; + ispif->intf_cmd[line->vfe_id].cmd_1 = CMD_ALL_NO_CHANGE; + + ispif->power_count++; + } else { + if (ispif->power_count == 0) { + dev_err(dev, "ispif power off on power_count == 0\n"); + goto exit; + } else if (ispif->power_count == 1) { + camss_disable_clocks(ispif->nclocks, ispif->clock); + } + + ispif->power_count--; + } + +exit: + mutex_unlock(&ispif->power_lock); + + return ret; +} + +/* + * ispif_select_clk_mux - Select clock for PIX/RDI interface + * @ispif: ISPIF device + * @intf: VFE interface + * @csid: CSID HW module id + * @vfe: VFE HW module id + * @enable: enable or disable the selected clock + */ +static void ispif_select_clk_mux(struct ispif_device *ispif, + enum ispif_intf intf, u8 csid, + u8 vfe, u8 enable) +{ + u32 val; + + switch (intf) { + case PIX0: + val = readl_relaxed(ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL); + val &= ~(0xf << (vfe * 8)); + if (enable) + val |= (csid << (vfe * 8)); + writel_relaxed(val, ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL); + break; + + case RDI0: + val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + val &= ~(0xf << (vfe * 12)); + if (enable) + val |= (csid << (vfe * 12)); + writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + break; + + case PIX1: + val = readl_relaxed(ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL); + val &= ~(0xf << (4 + (vfe * 8))); + if (enable) + val |= (csid << (4 + (vfe * 8))); + writel_relaxed(val, ispif->base_clk_mux + CSI_PIX_CLK_MUX_SEL); + break; + + case RDI1: + val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + val &= ~(0xf << (4 + (vfe * 12))); + if (enable) + val |= (csid << (4 + (vfe * 12))); + writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + break; + + case RDI2: + val = readl_relaxed(ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + val &= ~(0xf << (8 + (vfe * 12))); + if (enable) + val |= (csid << (8 + (vfe * 12))); + writel_relaxed(val, ispif->base_clk_mux + CSI_RDI_CLK_MUX_SEL); + break; + } + + mb(); +} + +/* + * ispif_validate_intf_status - Validate current status of PIX/RDI interface + * @ispif: ISPIF device + * @intf: VFE interface + * @vfe: VFE HW module id + * + * Return 0 when interface is idle or -EBUSY otherwise + */ +static int ispif_validate_intf_status(struct ispif_device *ispif, + enum ispif_intf intf, u8 vfe) +{ + int ret = 0; + u32 val = 0; + + switch (intf) { + case PIX0: + val = readl_relaxed(ispif->base + + ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 0)); + break; + case RDI0: + val = readl_relaxed(ispif->base + + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 0)); + break; + case PIX1: + val = readl_relaxed(ispif->base + + ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 1)); + break; + case RDI1: + val = readl_relaxed(ispif->base + + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 1)); + break; + case RDI2: + val = readl_relaxed(ispif->base + + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 2)); + break; + } + + if ((val & 0xf) != 0xf) { + dev_err(to_device(ispif), "%s: ispif is busy: 0x%x\n", + __func__, val); + ret = -EBUSY; + } + + return ret; +} + +/* + * ispif_wait_for_stop - Wait for PIX/RDI interface to stop + * @ispif: ISPIF device + * @intf: VFE interface + * @vfe: VFE HW module id + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_wait_for_stop(struct ispif_device *ispif, + enum ispif_intf intf, u8 vfe) +{ + u32 addr = 0; + u32 stop_flag = 0; + int ret; + + switch (intf) { + case PIX0: + addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 0); + break; + case RDI0: + addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 0); + break; + case PIX1: + addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe, 1); + break; + case RDI1: + addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 1); + break; + case RDI2: + addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe, 2); + break; + } + + ret = readl_poll_timeout(ispif->base + addr, + stop_flag, + (stop_flag & 0xf) == 0xf, + ISPIF_TIMEOUT_SLEEP_US, + ISPIF_TIMEOUT_ALL_US); + if (ret < 0) + dev_err(to_device(ispif), "%s: ispif stop timeout\n", + __func__); + + return ret; +} + +/* + * ispif_select_csid - Select CSID HW module for input from + * @ispif: ISPIF device + * @intf: VFE interface + * @csid: CSID HW module id + * @vfe: VFE HW module id + * @enable: enable or disable the selected input + */ +static void ispif_select_csid(struct ispif_device *ispif, enum ispif_intf intf, + u8 csid, u8 vfe, u8 enable) +{ + u32 val; + + val = readl_relaxed(ispif->base + ISPIF_VFE_m_INTF_INPUT_SEL(vfe)); + switch (intf) { + case PIX0: + val &= ~(BIT(1) | BIT(0)); + if (enable) + val |= csid; + break; + case RDI0: + val &= ~(BIT(5) | BIT(4)); + if (enable) + val |= (csid << 4); + break; + case PIX1: + val &= ~(BIT(9) | BIT(8)); + if (enable) + val |= (csid << 8); + break; + case RDI1: + val &= ~(BIT(13) | BIT(12)); + if (enable) + val |= (csid << 12); + break; + case RDI2: + val &= ~(BIT(21) | BIT(20)); + if (enable) + val |= (csid << 20); + break; + } + + writel(val, ispif->base + ISPIF_VFE_m_INTF_INPUT_SEL(vfe)); +} + +/* + * ispif_select_cid - Enable/disable desired CID + * @ispif: ISPIF device + * @intf: VFE interface + * @cid: desired CID to enable/disable + * @vfe: VFE HW module id + * @enable: enable or disable the desired CID + */ +static void ispif_select_cid(struct ispif_device *ispif, enum ispif_intf intf, + u8 cid, u8 vfe, u8 enable) +{ + u32 cid_mask = 1 << cid; + u32 addr = 0; + u32 val; + + switch (intf) { + case PIX0: + addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe, 0); + break; + case RDI0: + addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 0); + break; + case PIX1: + addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe, 1); + break; + case RDI1: + addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 1); + break; + case RDI2: + addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe, 2); + break; + } + + val = readl_relaxed(ispif->base + addr); + if (enable) + val |= cid_mask; + else + val &= ~cid_mask; + + writel(val, ispif->base + addr); +} + +/* + * ispif_config_irq - Enable/disable interrupts for PIX/RDI interface + * @ispif: ISPIF device + * @intf: VFE interface + * @vfe: VFE HW module id + * @enable: enable or disable + */ +static void ispif_config_irq(struct ispif_device *ispif, enum ispif_intf intf, + u8 vfe, u8 enable) +{ + u32 val; + + switch (intf) { + case PIX0: + val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe)); + val &= ~ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK; + if (enable) + val |= ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE; + writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe)); + writel_relaxed(ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE, + ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(vfe)); + break; + case RDI0: + val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe)); + val &= ~ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK; + if (enable) + val |= ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE; + writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe)); + writel_relaxed(ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE, + ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(vfe)); + break; + case PIX1: + val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe)); + val &= ~ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK; + if (enable) + val |= ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE; + writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe)); + writel_relaxed(ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE, + ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(vfe)); + break; + case RDI1: + val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe)); + val &= ~ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK; + if (enable) + val |= ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE; + writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe)); + writel_relaxed(ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE, + ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(vfe)); + break; + case RDI2: + val = readl_relaxed(ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe)); + val &= ~ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK; + if (enable) + val |= ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE; + writel_relaxed(val, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe)); + writel_relaxed(ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE, + ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(vfe)); + break; + } + + writel(0x1, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD); +} + +/* + * ispif_set_intf_cmd - Set command to enable/disable interface + * @ispif: ISPIF device + * @cmd: interface command + * @intf: VFE interface + * @vfe: VFE HW module id + * @vc: virtual channel + */ +static void ispif_set_intf_cmd(struct ispif_device *ispif, u8 cmd, + enum ispif_intf intf, u8 vfe, u8 vc) +{ + u32 *val; + + if (intf == RDI2) { + val = &ispif->intf_cmd[vfe].cmd_1; + *val &= ~(0x3 << (vc * 2 + 8)); + *val |= (cmd << (vc * 2 + 8)); + wmb(); + writel_relaxed(*val, ispif->base + ISPIF_VFE_m_INTF_CMD_1(vfe)); + wmb(); + } else { + val = &ispif->intf_cmd[vfe].cmd_0; + *val &= ~(0x3 << (vc * 2 + intf * 8)); + *val |= (cmd << (vc * 2 + intf * 8)); + wmb(); + writel_relaxed(*val, ispif->base + ISPIF_VFE_m_INTF_CMD_0(vfe)); + wmb(); + } +} + +/* + * ispif_set_stream - Enable/disable streaming on ISPIF module + * @sd: ISPIF V4L2 subdevice + * @enable: Requested streaming state + * + * Main configuration of ISPIF module is also done here. + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct ispif_device *ispif = to_ispif(line); + enum ispif_intf intf = line->interface; + u8 csid = line->csid_id; + u8 vfe = line->vfe_id; + u8 vc = 0; /* Virtual Channel 0 */ + u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */ + int ret; + + if (enable) { + if (!media_entity_remote_pad(&line->pads[MSM_ISPIF_PAD_SINK])) + return -ENOLINK; + + /* Config */ + + mutex_lock(&ispif->config_lock); + ispif_select_clk_mux(ispif, intf, csid, vfe, 1); + + ret = ispif_validate_intf_status(ispif, intf, vfe); + if (ret < 0) { + mutex_unlock(&ispif->config_lock); + return ret; + } + + ispif_select_csid(ispif, intf, csid, vfe, 1); + ispif_select_cid(ispif, intf, cid, vfe, 1); + ispif_config_irq(ispif, intf, vfe, 1); + ispif_set_intf_cmd(ispif, CMD_ENABLE_FRAME_BOUNDARY, + intf, vfe, vc); + } else { + mutex_lock(&ispif->config_lock); + ispif_set_intf_cmd(ispif, CMD_DISABLE_FRAME_BOUNDARY, + intf, vfe, vc); + mutex_unlock(&ispif->config_lock); + + ret = ispif_wait_for_stop(ispif, intf, vfe); + if (ret < 0) + return ret; + + mutex_lock(&ispif->config_lock); + ispif_config_irq(ispif, intf, vfe, 0); + ispif_select_cid(ispif, intf, cid, vfe, 0); + ispif_select_csid(ispif, intf, csid, vfe, 0); + ispif_select_clk_mux(ispif, intf, csid, vfe, 0); + } + + mutex_unlock(&ispif->config_lock); + + return 0; +} + +/* + * __ispif_get_format - Get pointer to format structure + * @ispif: ISPIF line + * @cfg: V4L2 subdev pad configuration + * @pad: pad from which format is requested + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE format structure + */ +static struct v4l2_mbus_framefmt * +__ispif_get_format(struct ispif_line *line, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&line->subdev, cfg, pad); + + return &line->fmt[pad]; +} + +/* + * ispif_try_format - Handle try format by pad subdev method + * @ispif: ISPIF line + * @cfg: V4L2 subdev pad configuration + * @pad: pad on which format is requested + * @fmt: pointer to v4l2 format structure + * @which: wanted subdev format + */ +static void ispif_try_format(struct ispif_line *line, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + struct v4l2_mbus_framefmt *fmt, + enum v4l2_subdev_format_whence which) +{ + unsigned int i; + + switch (pad) { + case MSM_ISPIF_PAD_SINK: + /* Set format on sink pad */ + + for (i = 0; i < ARRAY_SIZE(ispif_formats); i++) + if (fmt->code == ispif_formats[i]) + break; + + /* If not found, use UYVY as default */ + if (i >= ARRAY_SIZE(ispif_formats)) + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + + fmt->width = clamp_t(u32, fmt->width, 1, 8191); + fmt->height = clamp_t(u32, fmt->height, 1, 8191); + + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + + break; + + case MSM_ISPIF_PAD_SRC: + /* Set and return a format same as sink pad */ + + *fmt = *__ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK, + which); + + break; + } + + fmt->colorspace = V4L2_COLORSPACE_SRGB; +} + +/* + * ispif_enum_mbus_code - Handle pixel format enumeration + * @sd: ISPIF V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @code: pointer to v4l2_subdev_mbus_code_enum structure + * return -EINVAL or zero on success + */ +static int ispif_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + if (code->pad == MSM_ISPIF_PAD_SINK) { + if (code->index >= ARRAY_SIZE(ispif_formats)) + return -EINVAL; + + code->code = ispif_formats[code->index]; + } else { + if (code->index > 0) + return -EINVAL; + + format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK, + code->which); + + code->code = format->code; + } + + return 0; +} + +/* + * ispif_enum_frame_size - Handle frame size enumeration + * @sd: ISPIF V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fse: pointer to v4l2_subdev_frame_size_enum structure + * return -EINVAL or zero on success + */ +static int ispif_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt format; + + if (fse->index != 0) + return -EINVAL; + + format.code = fse->code; + format.width = 1; + format.height = 1; + ispif_try_format(line, cfg, fse->pad, &format, fse->which); + fse->min_width = format.width; + fse->min_height = format.height; + + if (format.code != fse->code) + return -EINVAL; + + format.code = fse->code; + format.width = -1; + format.height = -1; + ispif_try_format(line, cfg, fse->pad, &format, fse->which); + fse->max_width = format.width; + fse->max_height = format.height; + + return 0; +} + +/* + * ispif_get_format - Handle get format by pads subdev method + * @sd: ISPIF V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int ispif_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __ispif_get_format(line, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + fmt->format = *format; + + return 0; +} + +/* + * ispif_set_format - Handle set format by pads subdev method + * @sd: ISPIF V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int ispif_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct ispif_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __ispif_get_format(line, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + ispif_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); + *format = fmt->format; + + /* Propagate the format from sink to source */ + if (fmt->pad == MSM_ISPIF_PAD_SINK) { + format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SRC, + fmt->which); + + *format = fmt->format; + ispif_try_format(line, cfg, MSM_ISPIF_PAD_SRC, format, + fmt->which); + } + + return 0; +} + +/* + * ispif_init_formats - Initialize formats on all pads + * @sd: ISPIF V4L2 subdevice + * @fh: V4L2 subdev file handle + * + * Initialize all pad formats with default values. + * + * Return 0 on success or a negative error code otherwise + */ +static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_subdev_format format = { + .pad = MSM_ISPIF_PAD_SINK, + .which = fh ? V4L2_SUBDEV_FORMAT_TRY : + V4L2_SUBDEV_FORMAT_ACTIVE, + .format = { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .width = 1920, + .height = 1080 + } + }; + + return ispif_set_format(sd, fh ? fh->pad : NULL, &format); +} + +/* + * msm_ispif_subdev_init - Initialize ISPIF device structure and resources + * @ispif: ISPIF device + * @res: ISPIF module resources table + * + * Return 0 on success or a negative error code otherwise + */ +int msm_ispif_subdev_init(struct ispif_device *ispif, + const struct resources_ispif *res) +{ + struct device *dev = to_device(ispif); + struct platform_device *pdev = to_platform_device(dev); + struct resource *r; + int i; + int ret; + + /* Memory */ + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); + ispif->base = devm_ioremap_resource(dev, r); + if (IS_ERR(ispif->base)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(ispif->base); + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]); + ispif->base_clk_mux = devm_ioremap_resource(dev, r); + if (IS_ERR(ispif->base_clk_mux)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(ispif->base_clk_mux); + } + + /* Interrupt */ + + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res->interrupt); + + if (!r) { + dev_err(dev, "missing IRQ\n"); + return -EINVAL; + } + + ispif->irq = r->start; + snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", + dev_name(dev), MSM_ISPIF_NAME); + ret = devm_request_irq(dev, ispif->irq, ispif_isr, + IRQF_TRIGGER_RISING, ispif->irq_name, ispif); + if (ret < 0) { + dev_err(dev, "request_irq failed: %d\n", ret); + return ret; + } + + /* Clocks */ + + ispif->nclocks = 0; + while (res->clock[ispif->nclocks]) + ispif->nclocks++; + + ispif->clock = devm_kzalloc(dev, ispif->nclocks * sizeof(*ispif->clock), + GFP_KERNEL); + if (!ispif->clock) + return -ENOMEM; + + for (i = 0; i < ispif->nclocks; i++) { + ispif->clock[i] = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(ispif->clock[i])) + return PTR_ERR(ispif->clock[i]); + } + + ispif->nclocks_for_reset = 0; + while (res->clock_for_reset[ispif->nclocks_for_reset]) + ispif->nclocks_for_reset++; + + ispif->clock_for_reset = devm_kzalloc(dev, ispif->nclocks_for_reset * + sizeof(*ispif->clock_for_reset), GFP_KERNEL); + if (!ispif->clock_for_reset) + return -ENOMEM; + + for (i = 0; i < ispif->nclocks_for_reset; i++) { + ispif->clock_for_reset[i] = devm_clk_get(dev, + res->clock_for_reset[i]); + if (IS_ERR(ispif->clock_for_reset[i])) + return PTR_ERR(ispif->clock_for_reset[i]); + } + + for (i = 0; i < ARRAY_SIZE(ispif->line); i++) + ispif->line[i].id = i; + + mutex_init(&ispif->power_lock); + ispif->power_count = 0; + + mutex_init(&ispif->config_lock); + + init_completion(&ispif->reset_complete); + + return 0; +} + +/* + * ispif_get_intf - Get ISPIF interface to use by VFE line id + * @line_id: VFE line id that the ISPIF line is connected to + * + * Return ISPIF interface to use + */ +static enum ispif_intf ispif_get_intf(enum vfe_line_id line_id) +{ + switch (line_id) { + case (VFE_LINE_RDI0): + return RDI0; + case (VFE_LINE_RDI1): + return RDI1; + case (VFE_LINE_RDI2): + return RDI2; + default: + return RDI0; + } +} + +/* + * ispif_link_setup - Setup ISPIF connections + * @entity: Pointer to media entity structure + * @local: Pointer to local pad + * @remote: Pointer to remote pad + * @flags: Link flags + * + * Return 0 on success + */ +static int ispif_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + if (flags & MEDIA_LNK_FL_ENABLED) { + if (media_entity_remote_pad(local)) + return -EBUSY; + + if (local->flags & MEDIA_PAD_FL_SINK) { + struct v4l2_subdev *sd; + struct ispif_line *line; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + + msm_csid_get_csid_id(remote->entity, &line->csid_id); + } else { /* MEDIA_PAD_FL_SOURCE */ + struct v4l2_subdev *sd; + struct ispif_line *line; + enum vfe_line_id id; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + + msm_vfe_get_vfe_id(remote->entity, &line->vfe_id); + msm_vfe_get_vfe_line_id(remote->entity, &id); + line->interface = ispif_get_intf(id); + } + } + + return 0; +} + +static const struct v4l2_subdev_core_ops ispif_core_ops = { + .s_power = ispif_set_power, +}; + +static const struct v4l2_subdev_video_ops ispif_video_ops = { + .s_stream = ispif_set_stream, +}; + +static const struct v4l2_subdev_pad_ops ispif_pad_ops = { + .enum_mbus_code = ispif_enum_mbus_code, + .enum_frame_size = ispif_enum_frame_size, + .get_fmt = ispif_get_format, + .set_fmt = ispif_set_format, +}; + +static const struct v4l2_subdev_ops ispif_v4l2_ops = { + .core = &ispif_core_ops, + .video = &ispif_video_ops, + .pad = &ispif_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops ispif_v4l2_internal_ops = { + .open = ispif_init_formats, +}; + +static const struct media_entity_operations ispif_media_ops = { + .link_setup = ispif_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +/* + * msm_ispif_register_entities - Register subdev node for ISPIF module + * @ispif: ISPIF device + * @v4l2_dev: V4L2 device + * + * Return 0 on success or a negative error code otherwise + */ +int msm_ispif_register_entities(struct ispif_device *ispif, + struct v4l2_device *v4l2_dev) +{ + struct device *dev = to_device(ispif); + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(ispif->line); i++) { + struct v4l2_subdev *sd = &ispif->line[i].subdev; + struct media_pad *pads = ispif->line[i].pads; + + v4l2_subdev_init(sd, &ispif_v4l2_ops); + sd->internal_ops = &ispif_v4l2_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", + MSM_ISPIF_NAME, i); + v4l2_set_subdevdata(sd, &ispif->line[i]); + + ret = ispif_init_formats(sd, NULL); + if (ret < 0) { + dev_err(dev, "Failed to init format: %d\n", ret); + goto error; + } + + pads[MSM_ISPIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + pads[MSM_ISPIF_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; + + sd->entity.function = MEDIA_ENT_F_IO_V4L; + sd->entity.ops = &ispif_media_ops; + ret = media_entity_pads_init(&sd->entity, MSM_ISPIF_PADS_NUM, + pads); + if (ret < 0) { + dev_err(dev, "Failed to init media entity: %d\n", ret); + goto error; + } + + ret = v4l2_device_register_subdev(v4l2_dev, sd); + if (ret < 0) { + dev_err(dev, "Failed to register subdev: %d\n", ret); + media_entity_cleanup(&sd->entity); + goto error; + } + } + + return 0; + +error: + for (i--; i >= 0; i--) { + struct v4l2_subdev *sd = &ispif->line[i].subdev; + + v4l2_device_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + } + + return ret; +} + +/* + * msm_ispif_unregister_entities - Unregister ISPIF module subdev node + * @ispif: ISPIF device + */ +void msm_ispif_unregister_entities(struct ispif_device *ispif) +{ + int i; + + mutex_destroy(&ispif->power_lock); + mutex_destroy(&ispif->config_lock); + + for (i = 0; i < ARRAY_SIZE(ispif->line); i++) { + struct v4l2_subdev *sd = &ispif->line[i].subdev; + + v4l2_device_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + } +} diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h new file mode 100644 index 000000000000..6a1c9bd65477 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h @@ -0,0 +1,85 @@ +/* + * camss-ispif.h + * + * Qualcomm MSM Camera Subsystem - ISPIF Module + * + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_ISPIF_H +#define QC_MSM_CAMSS_ISPIF_H + +#include +#include +#include +#include + +/* Number of ISPIF lines - same as number of CSID hardware modules */ +#define MSM_ISPIF_LINE_NUM 2 + +#define MSM_ISPIF_PAD_SINK 0 +#define MSM_ISPIF_PAD_SRC 1 +#define MSM_ISPIF_PADS_NUM 2 + +#define MSM_ISPIF_VFE_NUM 1 + +enum ispif_intf { + PIX0, + RDI0, + PIX1, + RDI1, + RDI2 +}; + +struct ispif_intf_cmd_reg { + u32 cmd_0; + u32 cmd_1; +}; + +struct ispif_line { + u8 id; + u8 csid_id; + u8 vfe_id; + enum ispif_intf interface; + struct v4l2_subdev subdev; + struct media_pad pads[MSM_ISPIF_PADS_NUM]; + struct v4l2_mbus_framefmt fmt[MSM_ISPIF_PADS_NUM]; +}; + +struct ispif_device { + void __iomem *base; + void __iomem *base_clk_mux; + u32 irq; + char irq_name[30]; + struct clk **clock; + int nclocks; + struct clk **clock_for_reset; + int nclocks_for_reset; + struct completion reset_complete; + int power_count; + struct mutex power_lock; + struct ispif_intf_cmd_reg intf_cmd[MSM_ISPIF_VFE_NUM]; + struct mutex config_lock; + struct ispif_line line[MSM_ISPIF_LINE_NUM]; +}; + +struct resources_ispif; + +int msm_ispif_subdev_init(struct ispif_device *ispif, + const struct resources_ispif *res); + +int msm_ispif_register_entities(struct ispif_device *ispif, + struct v4l2_device *v4l2_dev); + +void msm_ispif_unregister_entities(struct ispif_device *ispif); + +#endif /* QC_MSM_CAMSS_ISPIF_H */ -- cgit v1.2.3 From 4c98a5f57f90f2c80db85187aac40d9805c2b554 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:05 -0400 Subject: media: camss: Add VFE files These files control the VFE module. The VFE has different input interfaces. The PIX input interface feeds the input data to an image processing pipeline. Three RDI input interfaces bypass the image processing pipeline. The VFE also contains the AXI bus interface which writes the output data to memory. RDI interfaces are supported in this version. PIX interface is not supported. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 1906 ++++++++++++++++++++ drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 114 ++ 2 files changed, 2020 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-vfe.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-vfe.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c new file mode 100644 index 000000000000..fe6b8abd49d9 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -0,0 +1,1906 @@ +/* + * camss-vfe.c + * + * Qualcomm MSM Camera Subsystem - VFE Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camss-vfe.h" +#include "camss.h" + +#define MSM_VFE_NAME "msm_vfe" + +#define vfe_line_array(ptr_line) \ + ((const struct vfe_line (*)[]) &(ptr_line[-(ptr_line->id)])) + +#define to_vfe(ptr_line) \ + container_of(vfe_line_array(ptr_line), struct vfe_device, ptr_line) + +#define VFE_0_HW_VERSION 0x000 + +#define VFE_0_GLOBAL_RESET_CMD 0x00c +#define VFE_0_GLOBAL_RESET_CMD_CORE (1 << 0) +#define VFE_0_GLOBAL_RESET_CMD_CAMIF (1 << 1) +#define VFE_0_GLOBAL_RESET_CMD_BUS (1 << 2) +#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG (1 << 3) +#define VFE_0_GLOBAL_RESET_CMD_REGISTER (1 << 4) +#define VFE_0_GLOBAL_RESET_CMD_TIMER (1 << 5) +#define VFE_0_GLOBAL_RESET_CMD_PM (1 << 6) +#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR (1 << 7) +#define VFE_0_GLOBAL_RESET_CMD_TESTGEN (1 << 8) + +#define VFE_0_IRQ_CMD 0x024 +#define VFE_0_IRQ_CMD_GLOBAL_CLEAR (1 << 0) + +#define VFE_0_IRQ_MASK_0 0x028 +#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5)) +#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_MASK_0_RESET_ACK (1 << 31) +#define VFE_0_IRQ_MASK_1 0x02c +#define VFE_0_IRQ_MASK_1_VIOLATION (1 << 7) +#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK (1 << 8) +#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) (1 << ((n) + 9)) + +#define VFE_0_IRQ_CLEAR_0 0x030 +#define VFE_0_IRQ_CLEAR_1 0x034 + +#define VFE_0_IRQ_STATUS_0 0x038 +#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5)) +#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_STATUS_0_RESET_ACK (1 << 31) +#define VFE_0_IRQ_STATUS_1 0x03c +#define VFE_0_IRQ_STATUS_1_VIOLATION (1 << 7) +#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK (1 << 8) + +#define VFE_0_VIOLATION_STATUS 0x48 + +#define VFE_0_BUS_CMD 0x4c +#define VFE_0_BUS_CMD_Mx_RLD_CMD(x) (1 << (x)) + +#define VFE_0_BUS_CFG 0x050 + +#define VFE_0_BUS_XBAR_CFG_x(x) (0x58 + 0x4 * ((x) / 2)) +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 5 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 6 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 7 + +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x06c + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT 1 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x070 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x074 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x078 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1F << 2) + +#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x07c + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \ + (0x088 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \ + (0x08c + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff + +#define VFE_0_BUS_PING_PONG_STATUS 0x268 + +#define VFE_0_BUS_BDG_CMD 0x2c0 +#define VFE_0_BUS_BDG_CMD_HALT_REQ 1 + +#define VFE_0_BUS_BDG_QOS_CFG_0 0x2c4 +#define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 +#define VFE_0_BUS_BDG_QOS_CFG_1 0x2c8 +#define VFE_0_BUS_BDG_QOS_CFG_2 0x2cc +#define VFE_0_BUS_BDG_QOS_CFG_3 0x2d0 +#define VFE_0_BUS_BDG_QOS_CFG_4 0x2d4 +#define VFE_0_BUS_BDG_QOS_CFG_5 0x2d8 +#define VFE_0_BUS_BDG_QOS_CFG_6 0x2dc +#define VFE_0_BUS_BDG_QOS_CFG_7 0x2e0 +#define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0001aaa5 + +#define VFE_0_RDI_CFG_x(x) (0x2e8 + (0x4 * (x))) +#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 +#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28) +#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4 +#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4) +#define VFE_0_RDI_CFG_x_RDI_EN_BIT (1 << 2) +#define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3 +#define VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(r) (1 << (16 + (r))) + +#define VFE_0_REG_UPDATE 0x378 +#define VFE_0_REG_UPDATE_RDIn(n) (1 << (1 + (n))) + +#define VFE_0_CGC_OVERRIDE_1 0x974 +#define VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(x) (1 << (x)) + +/* VFE reset timeout */ +#define VFE_RESET_TIMEOUT_MS 50 +/* VFE halt timeout */ +#define VFE_HALT_TIMEOUT_MS 100 +/* Max number of frame drop updates per frame */ +#define VFE_FRAME_DROP_UPDATES 5 +/* Frame drop value. NOTE: VAL + UPDATES should not exceed 31 */ +#define VFE_FRAME_DROP_VAL 20 + +static const u32 vfe_formats[] = { + MEDIA_BUS_FMT_UYVY8_2X8, + MEDIA_BUS_FMT_VYUY8_2X8, + MEDIA_BUS_FMT_YUYV8_2X8, + MEDIA_BUS_FMT_YVYU8_2X8, + MEDIA_BUS_FMT_SBGGR8_1X8, + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, + MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10, + MEDIA_BUS_FMT_SBGGR12_1X12, + MEDIA_BUS_FMT_SGBRG12_1X12, + MEDIA_BUS_FMT_SGRBG12_1X12, + MEDIA_BUS_FMT_SRGGB12_1X12, +}; + +static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits & ~clr_bits, vfe->base + reg); +} + +static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits) +{ + u32 bits = readl_relaxed(vfe->base + reg); + + writel_relaxed(bits | set_bits, vfe->base + reg); +} + +static void vfe_global_reset(struct vfe_device *vfe) +{ + u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_TESTGEN | + VFE_0_GLOBAL_RESET_CMD_BUS_MISR | + VFE_0_GLOBAL_RESET_CMD_PM | + VFE_0_GLOBAL_RESET_CMD_TIMER | + VFE_0_GLOBAL_RESET_CMD_REGISTER | + VFE_0_GLOBAL_RESET_CMD_BUS_BDG | + VFE_0_GLOBAL_RESET_CMD_BUS | + VFE_0_GLOBAL_RESET_CMD_CAMIF | + VFE_0_GLOBAL_RESET_CMD_CORE; + + writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); +} + +static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) +{ + if (enable) + vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT); + else + vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT); +} + +static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) +{ + if (enable) + vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT); + else + vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm), + 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT); +} + +static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per) +{ + u32 reg; + + reg = readl_relaxed(vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); + + reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK); + + reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT) + & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK; + + writel_relaxed(reg, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); +} + +static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm, + u32 pattern) +{ + writel_relaxed(pattern, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm)); +} + +static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, u16 offset, + u16 depth) +{ + u32 reg; + + reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) | + depth; + writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm)); +} + +static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm) +{ + wmb(); + writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); + wmb(); +} + +static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr) +{ + writel_relaxed(addr, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm)); +} + +static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr) +{ + writel_relaxed(addr, + vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm)); +} + +static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm) +{ + u32 reg; + + reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS); + + return (reg >> wm) & 0x1; +} + +static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable) +{ + if (enable) + writel_relaxed(0x10000009, vfe->base + VFE_0_BUS_CFG); + else + writel_relaxed(0, vfe->base + VFE_0_BUS_CFG); +} + +static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm, + enum vfe_line_id id) +{ + u32 reg; + + reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS; + reg |= VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id); + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg); + + reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; + reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) & + VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK; + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg); + + switch (id) { + case VFE_LINE_RDI0: + default: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI1: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI2: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + } + + if (wm % 2 == 1) + reg <<= 16; + + vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); + + writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF, + vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); +} + +static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm, + enum vfe_line_id id) +{ + u32 reg; + + reg = VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(id); + vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(0), reg); + + reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; + vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg); + + switch (id) { + case VFE_LINE_RDI0: + default: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI1: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + case VFE_LINE_RDI2: + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + break; + } + + if (wm % 2 == 1) + reg <<= 16; + + vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); +} + +static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) +{ + vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), + VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK); + + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), + cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT); +} + +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + vfe->reg_update |= VFE_0_REG_UPDATE_RDIn(line_id); + wmb(); + writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); + wmb(); +} + +static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, + enum vfe_line_id line_id, u8 enable) +{ + u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) | + VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(line_id); + u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm); + + if (enable) { + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); + } else { + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); + } +} + +static void vfe_enable_irq_common(struct vfe_device *vfe) +{ + u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK; + u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION | + VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK; + + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); +} + +/* + * vfe_reset - Trigger reset on VFE module and wait to complete + * @vfe: VFE device + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_reset(struct vfe_device *vfe) +{ + unsigned long time; + + reinit_completion(&vfe->reset_complete); + + vfe_global_reset(vfe); + + time = wait_for_completion_timeout(&vfe->reset_complete, + msecs_to_jiffies(VFE_RESET_TIMEOUT_MS)); + if (!time) { + dev_err(to_device(vfe), "VFE reset timeout\n"); + return -EIO; + } + + return 0; +} + +/* + * vfe_halt - Trigger halt on VFE module and wait to complete + * @vfe: VFE device + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_halt(struct vfe_device *vfe) +{ + unsigned long time; + + reinit_completion(&vfe->halt_complete); + + writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ, + vfe->base + VFE_0_BUS_BDG_CMD); + + time = wait_for_completion_timeout(&vfe->halt_complete, + msecs_to_jiffies(VFE_HALT_TIMEOUT_MS)); + if (!time) { + dev_err(to_device(vfe), "VFE halt timeout\n"); + return -EIO; + } + + return 0; +} + +static void vfe_init_outputs(struct vfe_device *vfe) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + struct vfe_output *output = &vfe->line[i].output; + + output->state = VFE_OUTPUT_OFF; + output->buf[0] = NULL; + output->buf[1] = NULL; + INIT_LIST_HEAD(&output->pending_bufs); + } +} + +static void vfe_reset_output_maps(struct vfe_device *vfe) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) + vfe->wm_output_map[i] = VFE_LINE_NONE; +} + +static void vfe_set_qos(struct vfe_device *vfe) +{ + u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; + u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; + + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); + writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); + writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); +} + +static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) +{ + u32 val = VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(wm); + + if (enable) + vfe_reg_set(vfe, VFE_0_CGC_OVERRIDE_1, val); + else + vfe_reg_clr(vfe, VFE_0_CGC_OVERRIDE_1, val); + + wmb(); +} + +static void vfe_output_init_addrs(struct vfe_device *vfe, + struct vfe_output *output, u8 sync) +{ + u32 ping_addr = 0; + u32 pong_addr = 0; + + output->active_buf = 0; + + if (output->buf[0]) + ping_addr = output->buf[0]->addr; + + if (output->buf[1]) + pong_addr = output->buf[1]->addr; + else + pong_addr = ping_addr; + + vfe_wm_set_ping_addr(vfe, output->wm_idx, ping_addr); + vfe_wm_set_pong_addr(vfe, output->wm_idx, pong_addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx); +} + +static void vfe_output_update_ping_addr(struct vfe_device *vfe, + struct vfe_output *output, u8 sync) +{ + u32 addr = 0; + + if (output->buf[0]) + addr = output->buf[0]->addr; + + vfe_wm_set_ping_addr(vfe, output->wm_idx, addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx); +} + +static void vfe_output_update_pong_addr(struct vfe_device *vfe, + struct vfe_output *output, u8 sync) +{ + u32 addr = 0; + + if (output->buf[1]) + addr = output->buf[1]->addr; + + vfe_wm_set_pong_addr(vfe, output->wm_idx, addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx); + +} + +static int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + int ret = -EBUSY; + int i; + + for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) { + if (vfe->wm_output_map[i] == VFE_LINE_NONE) { + vfe->wm_output_map[i] = line_id; + ret = i; + break; + } + } + + return ret; +} + +static int vfe_release_wm(struct vfe_device *vfe, u8 wm) +{ + if (wm > ARRAY_SIZE(vfe->wm_output_map)) + return -EINVAL; + + vfe->wm_output_map[wm] = VFE_LINE_NONE; + + return 0; +} + +static void vfe_output_frame_drop(struct vfe_device *vfe, + struct vfe_output *output, + u32 drop_pattern) +{ + u8 drop_period; + + /* We need to toggle update period to be valid on next frame */ + output->drop_update_idx++; + output->drop_update_idx %= VFE_FRAME_DROP_UPDATES; + drop_period = VFE_FRAME_DROP_VAL + output->drop_update_idx; + + vfe_wm_set_framedrop_period(vfe, output->wm_idx, drop_period); + vfe_wm_set_framedrop_pattern(vfe, output->wm_idx, drop_pattern); + vfe_reg_update(vfe, container_of(output, struct vfe_line, output)->id); +} + +static struct camss_buffer *vfe_buf_get_pending(struct vfe_output *output) +{ + struct camss_buffer *buffer = NULL; + + if (!list_empty(&output->pending_bufs)) { + buffer = list_first_entry(&output->pending_bufs, + struct camss_buffer, + queue); + list_del(&buffer->queue); + } + + return buffer; +} + +/* + * vfe_buf_add_pending - Add output buffer to list of pending + * @output: VFE output + * @buffer: Video buffer + */ +static void vfe_buf_add_pending(struct vfe_output *output, + struct camss_buffer *buffer) +{ + INIT_LIST_HEAD(&buffer->queue); + list_add_tail(&buffer->queue, &output->pending_bufs); +} + +/* + * vfe_buf_flush_pending - Flush all pending buffers. + * @output: VFE output + * @state: vb2 buffer state + */ +static void vfe_buf_flush_pending(struct vfe_output *output, + enum vb2_buffer_state state) +{ + struct camss_buffer *buf; + struct camss_buffer *t; + + list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) { + vb2_buffer_done(&buf->vb.vb2_buf, state); + list_del(&buf->queue); + } +} + +static void vfe_buf_update_wm_on_next(struct vfe_device *vfe, + struct vfe_output *output) +{ + switch (output->state) { + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3); + break; + case VFE_OUTPUT_SINGLE: + default: + dev_err_ratelimited(to_device(vfe), + "Next buf in wrong state! %d\n", + output->state); + break; + } +} + +static void vfe_buf_update_wm_on_last(struct vfe_device *vfe, + struct vfe_output *output) +{ + switch (output->state) { + case VFE_OUTPUT_CONTINUOUS: + output->state = VFE_OUTPUT_SINGLE; + vfe_output_frame_drop(vfe, output, 1); + break; + case VFE_OUTPUT_SINGLE: + output->state = VFE_OUTPUT_STOPPING; + vfe_output_frame_drop(vfe, output, 0); + break; + default: + dev_err_ratelimited(to_device(vfe), + "Last buff in wrong state! %d\n", + output->state); + break; + } +} + +static void vfe_buf_update_wm_on_new(struct vfe_device *vfe, + struct vfe_output *output, + struct camss_buffer *new_buf) +{ + int inactive_idx; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + inactive_idx = !output->active_buf; + + if (!output->buf[inactive_idx]) { + output->buf[inactive_idx] = new_buf; + + if (inactive_idx) + vfe_output_update_pong_addr(vfe, output, 0); + else + vfe_output_update_ping_addr(vfe, output, 0); + + vfe_output_frame_drop(vfe, output, 3); + output->state = VFE_OUTPUT_CONTINUOUS; + } else { + vfe_buf_add_pending(output, new_buf); + dev_err_ratelimited(to_device(vfe), + "Inactive buffer is busy\n"); + } + break; + + case VFE_OUTPUT_IDLE: + if (!output->buf[0]) { + output->buf[0] = new_buf; + + vfe_output_init_addrs(vfe, output, 1); + + vfe_output_frame_drop(vfe, output, 1); + output->state = VFE_OUTPUT_SINGLE; + } else { + vfe_buf_add_pending(output, new_buf); + dev_err_ratelimited(to_device(vfe), + "Output idle with buffer set!\n"); + } + break; + + case VFE_OUTPUT_CONTINUOUS: + default: + vfe_buf_add_pending(output, new_buf); + break; + } +} + +static int vfe_get_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output; + unsigned long flags; + int wm_idx; + + spin_lock_irqsave(&vfe->output_lock, flags); + + output = &line->output; + if (output->state != VFE_OUTPUT_OFF) { + dev_err(to_device(vfe), "Output is running\n"); + goto error; + } + output->state = VFE_OUTPUT_RESERVED; + + output->active_buf = 0; + + /* We will use only one wm per output for now */ + wm_idx = vfe_reserve_wm(vfe, line->id); + if (wm_idx < 0) { + dev_err(to_device(vfe), "Can not reserve wm\n"); + goto error_get_wm; + } + output->drop_update_idx = 0; + output->wm_idx = wm_idx; + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; + +error_get_wm: + output->state = VFE_OUTPUT_OFF; +error: + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return -EINVAL; +} + +static int vfe_put_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + unsigned long flags; + int ret; + + spin_lock_irqsave(&vfe->output_lock, flags); + + ret = vfe_release_wm(vfe, output->wm_idx); + if (ret < 0) + goto out; + + output->state = VFE_OUTPUT_OFF; + +out: + spin_unlock_irqrestore(&vfe->output_lock, flags); + return ret; +} + +static int vfe_enable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + unsigned long flags; + u16 ub_size; + + switch (vfe->id) { + case 0: + ub_size = MSM_VFE_VFE0_UB_SIZE_RDI; + break; + case 1: + ub_size = MSM_VFE_VFE1_UB_SIZE_RDI; + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&vfe->output_lock, flags); + + vfe->reg_update &= ~VFE_0_REG_UPDATE_RDIn(line->id); + + if (output->state != VFE_OUTPUT_RESERVED) { + dev_err(to_device(vfe), "Output is not in reserved state %d\n", + output->state); + spin_unlock_irqrestore(&vfe->output_lock, flags); + return -EINVAL; + } + output->state = VFE_OUTPUT_IDLE; + + output->buf[0] = vfe_buf_get_pending(output); + output->buf[1] = vfe_buf_get_pending(output); + + if (!output->buf[0] && output->buf[1]) { + output->buf[0] = output->buf[1]; + output->buf[1] = NULL; + } + + if (output->buf[0]) + output->state = VFE_OUTPUT_SINGLE; + + if (output->buf[1]) + output->state = VFE_OUTPUT_CONTINUOUS; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + vfe_output_frame_drop(vfe, output, 1); + break; + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3); + break; + default: + vfe_output_frame_drop(vfe, output, 0); + break; + } + + output->sequence = 0; + + vfe_output_init_addrs(vfe, output, 0); + + vfe_set_cgc_override(vfe, output->wm_idx, 1); + + vfe_enable_irq_wm_line(vfe, output->wm_idx, line->id, 1); + + vfe_bus_connect_wm_to_rdi(vfe, output->wm_idx, line->id); + + vfe_set_rdi_cid(vfe, line->id, 0); + + vfe_wm_set_ub_cfg(vfe, output->wm_idx, + (ub_size + 1) * output->wm_idx, ub_size); + + vfe_wm_frame_based(vfe, output->wm_idx, 1); + vfe_wm_enable(vfe, output->wm_idx, 1); + + vfe_bus_reload_wm(vfe, output->wm_idx); + + vfe_reg_update(vfe, line->id); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +static int vfe_disable_output(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + struct vfe_output *output = &line->output; + unsigned long flags; + + spin_lock_irqsave(&vfe->output_lock, flags); + + vfe_wm_enable(vfe, output->wm_idx, 0); + vfe_bus_disconnect_wm_from_rdi(vfe, output->wm_idx, line->id); + vfe_reg_update(vfe, line->id); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +/* + * vfe_enable - Enable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_enable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + int ret; + + mutex_lock(&vfe->stream_lock); + + if (!vfe->stream_count) { + vfe_enable_irq_common(vfe); + + vfe_bus_enable_wr_if(vfe, 1); + + vfe_set_qos(vfe); + } + + vfe->stream_count++; + + mutex_unlock(&vfe->stream_lock); + + ret = vfe_get_output(line); + if (ret < 0) + goto error_get_output; + + ret = vfe_enable_output(line); + if (ret < 0) + goto error_enable_output; + + vfe->was_streaming = 1; + + return 0; + + +error_enable_output: + vfe_put_output(line); + +error_get_output: + mutex_lock(&vfe->stream_lock); + + if (vfe->stream_count == 1) + vfe_bus_enable_wr_if(vfe, 0); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + return ret; +} + +/* + * vfe_disable - Disable streaming on VFE line + * @line: VFE line + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_disable(struct vfe_line *line) +{ + struct vfe_device *vfe = to_vfe(line); + + mutex_lock(&vfe->stream_lock); + + if (vfe->stream_count == 1) + vfe_bus_enable_wr_if(vfe, 0); + + vfe->stream_count--; + + mutex_unlock(&vfe->stream_lock); + + vfe_disable_output(line); + + vfe_put_output(line); + + return 0; +} + +/* + * vfe_isr_reg_update - Process reg update interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + struct vfe_output *output; + unsigned long flags; + + spin_lock_irqsave(&vfe->output_lock, flags); + vfe->reg_update &= ~VFE_0_REG_UPDATE_RDIn(line_id); + + output = &vfe->line[line_id].output; + if (output->state == VFE_OUTPUT_STOPPING) { + /* Release last buffer when hw is idle */ + if (output->last_buffer) { + vb2_buffer_done(&output->last_buffer->vb.vb2_buf, + VB2_BUF_STATE_DONE); + output->last_buffer = NULL; + } + output->state = VFE_OUTPUT_IDLE; + + /* Buffers received in stopping state are queued in */ + /* dma pending queue, start next capture here */ + + output->buf[0] = vfe_buf_get_pending(output); + output->buf[1] = vfe_buf_get_pending(output); + + if (!output->buf[0] && output->buf[1]) { + output->buf[0] = output->buf[1]; + output->buf[1] = NULL; + } + + if (output->buf[0]) + output->state = VFE_OUTPUT_SINGLE; + + if (output->buf[1]) + output->state = VFE_OUTPUT_CONTINUOUS; + + switch (output->state) { + case VFE_OUTPUT_SINGLE: + vfe_output_frame_drop(vfe, output, 2); + break; + case VFE_OUTPUT_CONTINUOUS: + vfe_output_frame_drop(vfe, output, 3); + break; + default: + vfe_output_frame_drop(vfe, output, 0); + break; + } + + vfe_output_init_addrs(vfe, output, 1); + } + + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_isr_wm_done - Process write master done interrupt + * @vfe: VFE Device + * @wm: Write master id + */ +static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) +{ + struct camss_buffer *ready_buf; + struct vfe_output *output; + dma_addr_t new_addr; + unsigned long flags; + u32 active_index; + u64 ts = ktime_get_ns(); + + active_index = vfe_wm_get_ping_pong_status(vfe, wm); + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (vfe->wm_output_map[wm] == VFE_LINE_NONE) { + dev_err_ratelimited(to_device(vfe), + "Received wm done for unmapped index\n"); + goto out_unlock; + } + output = &vfe->line[vfe->wm_output_map[wm]].output; + + if (output->active_buf == active_index) { + dev_err_ratelimited(to_device(vfe), + "Active buffer mismatch!\n"); + goto out_unlock; + } + output->active_buf = active_index; + + ready_buf = output->buf[!active_index]; + if (!ready_buf) { + dev_err_ratelimited(to_device(vfe), + "Missing ready buf %d %d!\n", + !active_index, output->state); + goto out_unlock; + } + + ready_buf->vb.vb2_buf.timestamp = ts; + ready_buf->vb.sequence = output->sequence++; + + /* Get next buffer */ + output->buf[!active_index] = vfe_buf_get_pending(output); + if (!output->buf[!active_index]) { + /* No next buffer - set same address */ + new_addr = ready_buf->addr; + vfe_buf_update_wm_on_last(vfe, output); + } else { + new_addr = output->buf[!active_index]->addr; + vfe_buf_update_wm_on_next(vfe, output); + } + + if (active_index) + vfe_wm_set_ping_addr(vfe, wm, new_addr); + else + vfe_wm_set_pong_addr(vfe, wm, new_addr); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + if (output->state == VFE_OUTPUT_STOPPING) + output->last_buffer = ready_buf; + else + vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + + return; + +out_unlock: + spin_unlock_irqrestore(&vfe->output_lock, flags); +} + +/* + * vfe_isr - ISPIF module interrupt handler + * @irq: Interrupt line + * @dev: VFE device + * + * Return IRQ_HANDLED on success + */ +static irqreturn_t vfe_isr(int irq, void *dev) +{ + struct vfe_device *vfe = dev; + u32 value0, value1; + u32 violation; + int i; + + value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); + value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); + + writel_relaxed(value0, vfe->base + VFE_0_IRQ_CLEAR_0); + writel_relaxed(value1, vfe->base + VFE_0_IRQ_CLEAR_1); + + wmb(); + writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); + + if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) + complete(&vfe->reset_complete); + + if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION) { + violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); + dev_err_ratelimited(to_device(vfe), + "VFE: violation = 0x%08x\n", violation); + } + + if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) { + complete(&vfe->halt_complete); + writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); + } + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) + if (value0 & VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(i)) + vfe_isr_reg_update(vfe, i); + + for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) + if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i)) + vfe_isr_wm_done(vfe, i); + + return IRQ_HANDLED; +} + +/* + * vfe_get - Power up and reset VFE module + * @vfe: VFE Device + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_get(struct vfe_device *vfe) +{ + int ret; + + mutex_lock(&vfe->power_lock); + + if (vfe->power_count == 0) { + ret = camss_enable_clocks(vfe->nclocks, vfe->clock, + to_device(vfe)); + if (ret < 0) + goto error_clocks; + + ret = vfe_reset(vfe); + if (ret < 0) + goto error_reset; + + vfe_reset_output_maps(vfe); + + vfe_init_outputs(vfe); + } + vfe->power_count++; + + mutex_unlock(&vfe->power_lock); + + return 0; + +error_reset: + camss_disable_clocks(vfe->nclocks, vfe->clock); + +error_clocks: + mutex_unlock(&vfe->power_lock); + + return ret; +} + +/* + * vfe_put - Power down VFE module + * @vfe: VFE Device + */ +static void vfe_put(struct vfe_device *vfe) +{ + mutex_lock(&vfe->power_lock); + + if (vfe->power_count == 0) { + dev_err(to_device(vfe), "vfe power off on power_count == 0\n"); + goto exit; + } else if (vfe->power_count == 1) { + if (vfe->was_streaming) { + vfe->was_streaming = 0; + vfe_halt(vfe); + } + camss_disable_clocks(vfe->nclocks, vfe->clock); + } + + vfe->power_count--; + +exit: + mutex_unlock(&vfe->power_lock); +} + +/* + * vfe_video_pad_to_line - Get pointer to VFE line by media pad + * @pad: Media pad + * + * Return pointer to vfe line structure + */ +static struct vfe_line *vfe_video_pad_to_line(struct media_pad *pad) +{ + struct media_pad *vfe_pad; + struct v4l2_subdev *subdev; + + vfe_pad = media_entity_remote_pad(pad); + if (vfe_pad == NULL) + return NULL; + + subdev = media_entity_to_v4l2_subdev(vfe_pad->entity); + + return container_of(subdev, struct vfe_line, subdev); +} + +/* + * vfe_queue_buffer - Add empty buffer + * @vid: Video device structure + * @buf: Buffer to be enqueued + * + * Add an empty buffer - depending on the current number of buffers it will be + * put in pending buffer queue or directly given to the hardware to be filled. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_queue_buffer(struct camss_video *vid, + struct camss_buffer *buf) +{ + struct vfe_device *vfe = &vid->camss->vfe; + struct vfe_line *line; + struct vfe_output *output; + unsigned long flags; + + line = vfe_video_pad_to_line(&vid->pad); + if (!line) { + dev_err(to_device(vfe), "Can not queue buffer\n"); + return -1; + } + output = &line->output; + + spin_lock_irqsave(&vfe->output_lock, flags); + + vfe_buf_update_wm_on_new(vfe, output, buf); + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +/* + * vfe_flush_buffers - Return all vb2 buffers + * @vid: Video device structure + * @state: vb2 buffer state of the returned buffers + * + * Return all buffers to vb2. This includes queued pending buffers (still + * unused) and any buffers given to the hardware but again still not used. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_flush_buffers(struct camss_video *vid, + enum vb2_buffer_state state) +{ + struct vfe_device *vfe = &vid->camss->vfe; + struct vfe_line *line; + struct vfe_output *output; + unsigned long flags; + + line = vfe_video_pad_to_line(&vid->pad); + if (!line) { + dev_err(to_device(vfe), "Can not flush buffers\n"); + return -1; + } + output = &line->output; + + spin_lock_irqsave(&vfe->output_lock, flags); + + vfe_buf_flush_pending(output, state); + + if (output->buf[0]) + vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state); + + if (output->buf[1]) + vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state); + + if (output->last_buffer) { + vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state); + output->last_buffer = NULL; + } + + spin_unlock_irqrestore(&vfe->output_lock, flags); + + return 0; +} + +/* + * vfe_set_power - Power on/off VFE module + * @sd: VFE V4L2 subdevice + * @on: Requested power state + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_set_power(struct v4l2_subdev *sd, int on) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct vfe_device *vfe = to_vfe(line); + int ret; + + if (on) { + u32 hw_version; + + ret = vfe_get(vfe); + if (ret < 0) + return ret; + + hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION); + dev_dbg(to_device(vfe), + "VFE HW Version = 0x%08x\n", hw_version); + } else { + vfe_put(vfe); + } + + return 0; +} + +/* + * vfe_set_stream - Enable/disable streaming on VFE module + * @sd: VFE V4L2 subdevice + * @enable: Requested streaming state + * + * Main configuration of VFE module is triggered here. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct vfe_device *vfe = to_vfe(line); + int ret; + + if (enable) { + ret = vfe_enable(line); + if (ret < 0) + dev_err(to_device(vfe), + "Failed to enable vfe outputs\n"); + } else { + ret = vfe_disable(line); + if (ret < 0) + dev_err(to_device(vfe), + "Failed to disable vfe outputs\n"); + } + + return ret; +} + +/* + * __vfe_get_format - Get pointer to format structure + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @pad: pad from which format is requested + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE format structure + */ +static struct v4l2_mbus_framefmt * +__vfe_get_format(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&line->subdev, cfg, pad); + + return &line->fmt[pad]; +} + + +/* + * vfe_try_format - Handle try format by pad subdev method + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @pad: pad on which format is requested + * @fmt: pointer to v4l2 format structure + * @which: wanted subdev format + */ +static void vfe_try_format(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + unsigned int pad, + struct v4l2_mbus_framefmt *fmt, + enum v4l2_subdev_format_whence which) +{ + unsigned int i; + + switch (pad) { + case MSM_VFE_PAD_SINK: + /* Set format on sink pad */ + + for (i = 0; i < ARRAY_SIZE(vfe_formats); i++) + if (fmt->code == vfe_formats[i]) + break; + + /* If not found, use UYVY as default */ + if (i >= ARRAY_SIZE(vfe_formats)) + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + + fmt->width = clamp_t(u32, fmt->width, 1, 8191); + fmt->height = clamp_t(u32, fmt->height, 1, 8191); + + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + + break; + + case MSM_VFE_PAD_SRC: + /* Set and return a format same as sink pad */ + + *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, + which); + + break; + } + + fmt->colorspace = V4L2_COLORSPACE_SRGB; +} + +/* + * vfe_enum_mbus_code - Handle pixel format enumeration + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @code: pointer to v4l2_subdev_mbus_code_enum structure + * + * return -EINVAL or zero on success + */ +static int vfe_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + if (code->pad == MSM_VFE_PAD_SINK) { + if (code->index >= ARRAY_SIZE(vfe_formats)) + return -EINVAL; + + code->code = vfe_formats[code->index]; + } else { + if (code->index > 0) + return -EINVAL; + + format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, + code->which); + + code->code = format->code; + } + + return 0; +} + +/* + * vfe_enum_frame_size - Handle frame size enumeration + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fse: pointer to v4l2_subdev_frame_size_enum structure + * + * Return -EINVAL or zero on success + */ +static int vfe_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt format; + + if (fse->index != 0) + return -EINVAL; + + format.code = fse->code; + format.width = 1; + format.height = 1; + vfe_try_format(line, cfg, fse->pad, &format, fse->which); + fse->min_width = format.width; + fse->min_height = format.height; + + if (format.code != fse->code) + return -EINVAL; + + format.code = fse->code; + format.width = -1; + format.height = -1; + vfe_try_format(line, cfg, fse->pad, &format, fse->which); + fse->max_width = format.width; + fse->max_height = format.height; + + return 0; +} + +/* + * vfe_get_format - Handle get format by pads subdev method + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int vfe_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + fmt->format = *format; + + return 0; +} + +/* + * vfe_set_format - Handle set format by pads subdev method + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @fmt: pointer to v4l2 subdev format structure + * + * Return -EINVAL or zero on success + */ +static int vfe_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format; + + format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); + if (format == NULL) + return -EINVAL; + + vfe_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); + *format = fmt->format; + + /* Propagate the format from sink to source */ + if (fmt->pad == MSM_VFE_PAD_SINK) { + format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SRC, + fmt->which); + + *format = fmt->format; + vfe_try_format(line, cfg, MSM_VFE_PAD_SRC, format, + fmt->which); + } + + return 0; +} + +/* + * vfe_init_formats - Initialize formats on all pads + * @sd: VFE V4L2 subdevice + * @fh: V4L2 subdev file handle + * + * Initialize all pad formats with default values. + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_subdev_format format = { + .pad = MSM_VFE_PAD_SINK, + .which = fh ? V4L2_SUBDEV_FORMAT_TRY : + V4L2_SUBDEV_FORMAT_ACTIVE, + .format = { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .width = 1920, + .height = 1080 + } + }; + + return vfe_set_format(sd, fh ? fh->pad : NULL, &format); +} + +/* + * msm_vfe_subdev_init - Initialize VFE device structure and resources + * @vfe: VFE device + * @res: VFE module resources table + * + * Return 0 on success or a negative error code otherwise + */ +int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) +{ + struct device *dev = to_device(vfe); + struct platform_device *pdev = to_platform_device(dev); + struct resource *r; + struct camss *camss = to_camss(vfe); + int i; + int ret; + + /* Memory */ + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); + vfe->base = devm_ioremap_resource(dev, r); + if (IS_ERR(vfe->base)) { + dev_err(dev, "could not map memory\n"); + return PTR_ERR(vfe->base); + } + + /* Interrupt */ + + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, + res->interrupt[0]); + if (!r) { + dev_err(dev, "missing IRQ\n"); + return -EINVAL; + } + + vfe->irq = r->start; + snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d", + dev_name(dev), MSM_VFE_NAME, vfe->id); + ret = devm_request_irq(dev, vfe->irq, vfe_isr, + IRQF_TRIGGER_RISING, vfe->irq_name, vfe); + if (ret < 0) { + dev_err(dev, "request_irq failed: %d\n", ret); + return ret; + } + + /* Clocks */ + + vfe->nclocks = 0; + while (res->clock[vfe->nclocks]) + vfe->nclocks++; + + vfe->clock = devm_kzalloc(dev, vfe->nclocks * sizeof(*vfe->clock), + GFP_KERNEL); + if (!vfe->clock) + return -ENOMEM; + + for (i = 0; i < vfe->nclocks; i++) { + vfe->clock[i] = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(vfe->clock[i])) + return PTR_ERR(vfe->clock[i]); + + if (res->clock_rate[i]) { + long clk_rate = clk_round_rate(vfe->clock[i], + res->clock_rate[i]); + if (clk_rate < 0) { + dev_err(dev, "clk round rate failed\n"); + return -EINVAL; + } + ret = clk_set_rate(vfe->clock[i], clk_rate); + if (ret < 0) { + dev_err(dev, "clk set rate failed\n"); + return ret; + } + } + } + + mutex_init(&vfe->power_lock); + vfe->power_count = 0; + + mutex_init(&vfe->stream_lock); + vfe->stream_count = 0; + + spin_lock_init(&vfe->output_lock); + + vfe->id = 0; + vfe->reg_update = 0; + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) { + vfe->line[i].video_out.type = + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + vfe->line[i].video_out.camss = camss; + vfe->line[i].id = i; + } + + init_completion(&vfe->reset_complete); + init_completion(&vfe->halt_complete); + + return 0; +} + +/* + * msm_vfe_get_vfe_id - Get VFE HW module id + * @entity: Pointer to VFE media entity structure + * @id: Return CSID HW module id here + */ +void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id) +{ + struct v4l2_subdev *sd; + struct vfe_line *line; + struct vfe_device *vfe; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + vfe = to_vfe(line); + + *id = vfe->id; +} + +/* + * msm_vfe_get_vfe_line_id - Get VFE line id by media entity + * @entity: Pointer to VFE media entity structure + * @id: Return VFE line id here + */ +void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id) +{ + struct v4l2_subdev *sd; + struct vfe_line *line; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + + *id = line->id; +} + +/* + * vfe_link_setup - Setup VFE connections + * @entity: Pointer to media entity structure + * @local: Pointer to local pad + * @remote: Pointer to remote pad + * @flags: Link flags + * + * Return 0 on success + */ +static int vfe_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + if (flags & MEDIA_LNK_FL_ENABLED) + if (media_entity_remote_pad(local)) + return -EBUSY; + + return 0; +} + +static const struct v4l2_subdev_core_ops vfe_core_ops = { + .s_power = vfe_set_power, +}; + +static const struct v4l2_subdev_video_ops vfe_video_ops = { + .s_stream = vfe_set_stream, +}; + +static const struct v4l2_subdev_pad_ops vfe_pad_ops = { + .enum_mbus_code = vfe_enum_mbus_code, + .enum_frame_size = vfe_enum_frame_size, + .get_fmt = vfe_get_format, + .set_fmt = vfe_set_format, +}; + +static const struct v4l2_subdev_ops vfe_v4l2_ops = { + .core = &vfe_core_ops, + .video = &vfe_video_ops, + .pad = &vfe_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops vfe_v4l2_internal_ops = { + .open = vfe_init_formats, +}; + +static const struct media_entity_operations vfe_media_ops = { + .link_setup = vfe_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +static const struct camss_video_ops camss_vfe_video_ops = { + .queue_buffer = vfe_queue_buffer, + .flush_buffers = vfe_flush_buffers, +}; + +void msm_vfe_stop_streaming(struct vfe_device *vfe) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vfe->line); i++) + msm_video_stop_streaming(&vfe->line[i].video_out); +} + +/* + * msm_vfe_register_entities - Register subdev node for VFE module + * @vfe: VFE device + * @v4l2_dev: V4L2 device + * + * Initialize and register a subdev node for the VFE module. Then + * call msm_video_register() to register the video device node which + * will be connected to this subdev node. Then actually create the + * media link between them. + * + * Return 0 on success or a negative error code otherwise + */ +int msm_vfe_register_entities(struct vfe_device *vfe, + struct v4l2_device *v4l2_dev) +{ + struct device *dev = to_device(vfe); + struct v4l2_subdev *sd; + struct media_pad *pads; + struct camss_video *video_out; + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + char name[32]; + + sd = &vfe->line[i].subdev; + pads = vfe->line[i].pads; + video_out = &vfe->line[i].video_out; + + v4l2_subdev_init(sd, &vfe_v4l2_ops); + sd->internal_ops = &vfe_v4l2_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", + MSM_VFE_NAME, vfe->id, "rdi", i); + v4l2_set_subdevdata(sd, &vfe->line[i]); + + ret = vfe_init_formats(sd, NULL); + if (ret < 0) { + dev_err(dev, "Failed to init format: %d\n", ret); + goto error_init; + } + + pads[MSM_VFE_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + pads[MSM_VFE_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; + + sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; + sd->entity.ops = &vfe_media_ops; + ret = media_entity_pads_init(&sd->entity, MSM_VFE_PADS_NUM, + pads); + if (ret < 0) { + dev_err(dev, "Failed to init media entity: %d\n", ret); + goto error_init; + } + + ret = v4l2_device_register_subdev(v4l2_dev, sd); + if (ret < 0) { + dev_err(dev, "Failed to register subdev: %d\n", ret); + goto error_reg_subdev; + } + + video_out->ops = &camss_vfe_video_ops; + snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d", + MSM_VFE_NAME, vfe->id, "video", i); + ret = msm_video_register(video_out, v4l2_dev, name); + if (ret < 0) { + dev_err(dev, "Failed to register video node: %d\n", + ret); + goto error_reg_video; + } + + ret = media_create_pad_link( + &sd->entity, MSM_VFE_PAD_SRC, + &video_out->vdev.entity, 0, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret < 0) { + dev_err(dev, "Failed to link %s->%s entities: %d\n", + sd->entity.name, video_out->vdev.entity.name, + ret); + goto error_link; + } + } + + return 0; + +error_link: + msm_video_unregister(video_out); + +error_reg_video: + v4l2_device_unregister_subdev(sd); + +error_reg_subdev: + media_entity_cleanup(&sd->entity); + +error_init: + for (i--; i >= 0; i--) { + sd = &vfe->line[i].subdev; + video_out = &vfe->line[i].video_out; + + msm_video_unregister(video_out); + v4l2_device_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + } + + return ret; +} + +/* + * msm_vfe_unregister_entities - Unregister VFE module subdev node + * @vfe: VFE device + */ +void msm_vfe_unregister_entities(struct vfe_device *vfe) +{ + int i; + + mutex_destroy(&vfe->power_lock); + mutex_destroy(&vfe->stream_lock); + + for (i = 0; i < ARRAY_SIZE(vfe->line); i++) { + struct v4l2_subdev *sd = &vfe->line[i].subdev; + struct camss_video *video_out = &vfe->line[i].video_out; + + msm_video_unregister(video_out); + v4l2_device_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + } +} diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h new file mode 100644 index 000000000000..6d2fc57d3c40 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -0,0 +1,114 @@ +/* + * camss-vfe.h + * + * Qualcomm MSM Camera Subsystem - VFE Module + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_VFE_H +#define QC_MSM_CAMSS_VFE_H + +#include +#include +#include +#include +#include + +#include "camss-video.h" + +#define MSM_VFE_PAD_SINK 0 +#define MSM_VFE_PAD_SRC 1 +#define MSM_VFE_PADS_NUM 2 + +#define MSM_VFE_LINE_NUM 3 +#define MSM_VFE_IMAGE_MASTERS_NUM 7 + +#define MSM_VFE_VFE0_UB_SIZE 1023 +#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3) +#define MSM_VFE_VFE1_UB_SIZE 1535 +#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3) + +enum vfe_output_state { + VFE_OUTPUT_OFF, + VFE_OUTPUT_RESERVED, + VFE_OUTPUT_SINGLE, + VFE_OUTPUT_CONTINUOUS, + VFE_OUTPUT_IDLE, + VFE_OUTPUT_STOPPING +}; + +enum vfe_line_id { + VFE_LINE_NONE = -1, + VFE_LINE_RDI0 = 0, + VFE_LINE_RDI1 = 1, + VFE_LINE_RDI2 = 2 +}; + +struct vfe_output { + u8 wm_idx; + + int active_buf; + struct camss_buffer *buf[2]; + struct camss_buffer *last_buffer; + struct list_head pending_bufs; + + unsigned int drop_update_idx; + + enum vfe_output_state state; + unsigned int sequence; +}; + +struct vfe_line { + enum vfe_line_id id; + struct v4l2_subdev subdev; + struct media_pad pads[MSM_VFE_PADS_NUM]; + struct v4l2_mbus_framefmt fmt[MSM_VFE_PADS_NUM]; + struct camss_video video_out; + struct vfe_output output; +}; + +struct vfe_device { + u8 id; + void __iomem *base; + u32 irq; + char irq_name[30]; + struct clk **clock; + int nclocks; + struct completion reset_complete; + struct completion halt_complete; + struct mutex power_lock; + int power_count; + struct mutex stream_lock; + int stream_count; + spinlock_t output_lock; + enum vfe_line_id wm_output_map[MSM_VFE_IMAGE_MASTERS_NUM]; + struct vfe_line line[MSM_VFE_LINE_NUM]; + u32 reg_update; + u8 was_streaming; +}; + +struct resources; + +int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res); + +int msm_vfe_register_entities(struct vfe_device *vfe, + struct v4l2_device *v4l2_dev); + +void msm_vfe_unregister_entities(struct vfe_device *vfe); + +void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id); +void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id); + +void msm_vfe_stop_streaming(struct vfe_device *vfe); + +#endif /* QC_MSM_CAMSS_VFE_H */ -- cgit v1.2.3 From 0ac2586c410fe00d58dd09bf270a22f25d5287b8 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:06 -0400 Subject: media: camss: Add files which handle the video device nodes These files handle the video device nodes of the camss driver. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-video.c | 681 +++++++++++++++++++++ .../media/platform/qcom/camss-8x16/camss-video.h | 64 ++ 2 files changed, 745 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-video.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss-video.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c new file mode 100644 index 000000000000..2e3f0128e4f1 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c @@ -0,0 +1,681 @@ +/* + * camss-video.c + * + * Qualcomm MSM Camera Subsystem - V4L2 device node + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camss-video.h" +#include "camss.h" + +/* + * struct camss_format_info - ISP media bus format information + * @code: V4L2 media bus format code + * @pixelformat: V4L2 pixel format FCC identifier + * @bpp: Bits per pixel when stored in memory + */ +static const struct camss_format_info { + u32 code; + u32 pixelformat; + unsigned int bpp; +} formats[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 16 }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 16 }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 16 }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 16 }, + { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8 }, + { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8 }, + { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8 }, + { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8 }, + { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 10 }, + { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 10 }, + { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 10 }, + { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 10 }, + { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 12 }, + { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 }, + { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 }, + { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 } +}; + +/* ----------------------------------------------------------------------------- + * Helper functions + */ + +/* + * video_mbus_to_pix_mp - Convert v4l2_mbus_framefmt to v4l2_pix_format_mplane + * @mbus: v4l2_mbus_framefmt format (input) + * @pix: v4l2_pix_format_mplane format (output) + * + * Fill the output pix structure with information from the input mbus format. + * + * Return 0 on success or a negative error code otherwise + */ +static unsigned int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus, + struct v4l2_pix_format_mplane *pix) +{ + unsigned int i; + u32 bytesperline; + + memset(pix, 0, sizeof(*pix)); + v4l2_fill_pix_format_mplane(pix, mbus); + + for (i = 0; i < ARRAY_SIZE(formats); ++i) { + if (formats[i].code == mbus->code) + break; + } + + if (WARN_ON(i == ARRAY_SIZE(formats))) + return -EINVAL; + + pix->pixelformat = formats[i].pixelformat; + pix->num_planes = 1; + bytesperline = pix->width * formats[i].bpp / 8; + bytesperline = ALIGN(bytesperline, 8); + pix->plane_fmt[0].bytesperline = bytesperline; + pix->plane_fmt[0].sizeimage = bytesperline * pix->height; + + return 0; +} + +static struct v4l2_subdev *video_remote_subdev(struct camss_video *video, + u32 *pad) +{ + struct media_pad *remote; + + remote = media_entity_remote_pad(&video->pad); + + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) + return NULL; + + if (pad) + *pad = remote->index; + + return media_entity_to_v4l2_subdev(remote->entity); +} + +static int video_get_subdev_format(struct camss_video *video, + struct v4l2_format *format) +{ + struct v4l2_subdev_format fmt; + struct v4l2_subdev *subdev; + u32 pad; + int ret; + + subdev = video_remote_subdev(video, &pad); + if (subdev == NULL) + return -EPIPE; + + fmt.pad = pad; + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; + + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt); + if (ret) + return ret; + + format->type = video->type; + return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp); +} + +/* ----------------------------------------------------------------------------- + * Video queue operations + */ + +static int video_queue_setup(struct vb2_queue *q, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct camss_video *video = vb2_get_drv_priv(q); + + if (*num_planes) { + if (*num_planes != 1) + return -EINVAL; + + if (sizes[0] < video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage) + return -EINVAL; + + return 0; + } + + *num_planes = 1; + + sizes[0] = video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + + return 0; +} + +static int video_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue); + struct camss_buffer *buffer = container_of(vbuf, struct camss_buffer, + vb); + struct sg_table *sgt; + + if (video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage > + vb2_plane_size(vb, 0)) + return -EINVAL; + + vb2_set_plane_payload(vb, 0, + video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage); + + sgt = vb2_dma_sg_plane_desc(vb, 0); + if (!sgt) + return -EFAULT; + + buffer->addr = sg_dma_address(sgt->sgl); + + vbuf->field = V4L2_FIELD_NONE; + + return 0; +} + +static void video_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue); + struct camss_buffer *buffer = container_of(vbuf, struct camss_buffer, + vb); + + video->ops->queue_buffer(video, buffer); +} + +static int video_check_format(struct camss_video *video) +{ + struct v4l2_pix_format_mplane *pix = &video->active_fmt.fmt.pix_mp; + struct v4l2_format format; + struct v4l2_pix_format_mplane *sd_pix = &format.fmt.pix_mp; + int ret; + + ret = video_get_subdev_format(video, &format); + if (ret < 0) + return ret; + + if (pix->pixelformat != sd_pix->pixelformat || + pix->height != sd_pix->height || + pix->width != sd_pix->width || + pix->num_planes != sd_pix->num_planes || + pix->num_planes != 1 || + pix->plane_fmt[0].bytesperline != sd_pix->plane_fmt[0].bytesperline || + pix->plane_fmt[0].sizeimage != sd_pix->plane_fmt[0].sizeimage || + pix->field != format.fmt.pix_mp.field) + return -EPIPE; + + return 0; +} + +static int video_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct camss_video *video = vb2_get_drv_priv(q); + struct video_device *vdev = &video->vdev; + struct media_entity *entity; + struct media_pad *pad; + struct v4l2_subdev *subdev; + int ret; + + ret = media_pipeline_start(&vdev->entity, &video->pipe); + if (ret < 0) + return ret; + + ret = video_check_format(video); + if (ret < 0) + goto error; + + entity = &vdev->entity; + while (1) { + pad = &entity->pads[0]; + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + break; + + pad = media_entity_remote_pad(pad); + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) + break; + + entity = pad->entity; + subdev = media_entity_to_v4l2_subdev(entity); + + ret = v4l2_subdev_call(subdev, video, s_stream, 1); + if (ret < 0 && ret != -ENOIOCTLCMD) + goto error; + } + + return 0; + +error: + media_pipeline_stop(&vdev->entity); + + video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED); + + return ret; +} + +static void video_stop_streaming(struct vb2_queue *q) +{ + struct camss_video *video = vb2_get_drv_priv(q); + struct video_device *vdev = &video->vdev; + struct media_entity *entity; + struct media_pad *pad; + struct v4l2_subdev *subdev; + struct v4l2_subdev *subdev_vfe = NULL; + + entity = &vdev->entity; + while (1) { + pad = &entity->pads[0]; + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + break; + + pad = media_entity_remote_pad(pad); + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) + break; + + entity = pad->entity; + subdev = media_entity_to_v4l2_subdev(entity); + + if (strstr(subdev->name, "vfe")) { + subdev_vfe = subdev; + } else if (strstr(subdev->name, "ispif")) { + v4l2_subdev_call(subdev, video, s_stream, 0); + v4l2_subdev_call(subdev_vfe, video, s_stream, 0); + } else { + v4l2_subdev_call(subdev, video, s_stream, 0); + } + } + + media_pipeline_stop(&vdev->entity); + + video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR); +} + +static const struct vb2_ops msm_video_vb2_q_ops = { + .queue_setup = video_queue_setup, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .buf_prepare = video_buf_prepare, + .buf_queue = video_buf_queue, + .start_streaming = video_start_streaming, + .stop_streaming = video_stop_streaming, +}; + +/* ----------------------------------------------------------------------------- + * V4L2 ioctls + */ + +static int video_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct camss_video *video = video_drvdata(file); + + strlcpy(cap->driver, "qcom-camss", sizeof(cap->driver)); + strlcpy(cap->card, "Qualcomm Camera Subsystem", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(video->camss->dev)); + + return 0; +} + +static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) +{ + struct camss_video *video = video_drvdata(file); + + if (f->type != video->type) + return -EINVAL; + + if (f->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + f->pixelformat = formats[f->index].pixelformat; + + return 0; +} + +static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct camss_video *video = video_drvdata(file); + + *f = video->active_fmt; + + return 0; +} + +static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_mp; + u32 width, height; + u32 bpl; + int j; + + pix_mp = &f->fmt.pix_mp; + + for (j = 0; j < ARRAY_SIZE(formats); j++) + if (pix_mp->pixelformat == formats[j].pixelformat) + break; + + if (j == ARRAY_SIZE(formats)) + j = 0; /* default format */ + + width = pix_mp->width; + height = pix_mp->height; + + memset(pix_mp, 0, sizeof(*pix_mp)); + + pix_mp->pixelformat = formats[j].pixelformat; + pix_mp->width = clamp_t(u32, width, 1, 8191); + pix_mp->height = clamp_t(u32, height, 1, 8191); + pix_mp->num_planes = 1; + bpl = pix_mp->width * formats[j].bpp / 8; + bpl = ALIGN(bpl, 8); + pix_mp->plane_fmt[0].bytesperline = bpl; + pix_mp->plane_fmt[0].sizeimage = bpl * pix_mp->height; + + pix_mp->field = V4L2_FIELD_NONE; + pix_mp->colorspace = V4L2_COLORSPACE_SRGB; + pix_mp->flags = 0; + pix_mp->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix_mp->colorspace); + pix_mp->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, + pix_mp->colorspace, pix_mp->ycbcr_enc); + pix_mp->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace); + + return 0; +} + +static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct camss_video *video = video_drvdata(file); + + return __video_try_fmt(video, f); +} + +static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct camss_video *video = video_drvdata(file); + int ret; + + if (vb2_is_busy(&video->vb2_q)) + return -EBUSY; + + ret = __video_try_fmt(video, f); + if (ret < 0) + return ret; + + video->active_fmt = *f; + + return 0; +} + +static int video_enum_input(struct file *file, void *fh, + struct v4l2_input *input) +{ + if (input->index > 0) + return -EINVAL; + + strlcpy(input->name, "camera", sizeof(input->name)); + input->type = V4L2_INPUT_TYPE_CAMERA; + + return 0; +} + +static int video_g_input(struct file *file, void *fh, unsigned int *input) +{ + *input = 0; + + return 0; +} + +static int video_s_input(struct file *file, void *fh, unsigned int input) +{ + return input == 0 ? 0 : -EINVAL; +} + +static const struct v4l2_ioctl_ops msm_vid_ioctl_ops = { + .vidioc_querycap = video_querycap, + .vidioc_enum_fmt_vid_cap_mplane = video_enum_fmt, + .vidioc_g_fmt_vid_cap_mplane = video_g_fmt, + .vidioc_s_fmt_vid_cap_mplane = video_s_fmt, + .vidioc_try_fmt_vid_cap_mplane = video_try_fmt, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_enum_input = video_enum_input, + .vidioc_g_input = video_g_input, + .vidioc_s_input = video_s_input, +}; + +/* ----------------------------------------------------------------------------- + * V4L2 file operations + */ + +static int video_open(struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct camss_video *video = video_drvdata(file); + struct v4l2_fh *vfh; + int ret; + + mutex_lock(&video->lock); + + vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); + if (vfh == NULL) { + ret = -ENOMEM; + goto error_alloc; + } + + v4l2_fh_init(vfh, vdev); + v4l2_fh_add(vfh); + + file->private_data = vfh; + + ret = v4l2_pipeline_pm_use(&vdev->entity, 1); + if (ret < 0) { + dev_err(video->camss->dev, "Failed to power up pipeline: %d\n", + ret); + goto error_pm_use; + } + + mutex_unlock(&video->lock); + + return 0; + +error_pm_use: + v4l2_fh_release(file); + +error_alloc: + mutex_unlock(&video->lock); + + return ret; +} + +static int video_release(struct file *file) +{ + struct video_device *vdev = video_devdata(file); + + vb2_fop_release(file); + + v4l2_pipeline_pm_use(&vdev->entity, 0); + + file->private_data = NULL; + + return 0; +} + +static const struct v4l2_file_operations msm_vid_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = video_ioctl2, + .open = video_open, + .release = video_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .read = vb2_fop_read, +}; + +/* ----------------------------------------------------------------------------- + * CAMSS video core + */ + +static void msm_video_release(struct video_device *vdev) +{ + struct camss_video *video = video_get_drvdata(vdev); + + media_entity_cleanup(&vdev->entity); + + mutex_destroy(&video->q_lock); + mutex_destroy(&video->lock); + + if (atomic_dec_and_test(&video->camss->ref_count)) + camss_delete(video->camss); +} + +/* + * msm_video_init_format - Helper function to initialize format + * @video: struct camss_video + * + * Initialize pad format with default value. + * + * Return 0 on success or a negative error code otherwise + */ +static int msm_video_init_format(struct camss_video *video) +{ + int ret; + struct v4l2_format format = { + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + .fmt.pix_mp = { + .width = 1920, + .height = 1080, + .pixelformat = formats[0].pixelformat, + }, + }; + + ret = __video_try_fmt(video, &format); + if (ret < 0) + return ret; + + video->active_fmt = format; + + return 0; +} + +/* + * msm_video_register - Register a video device node + * @video: struct camss_video + * @v4l2_dev: V4L2 device + * @name: name to be used for the video device node + * + * Initialize and register a video device node to a V4L2 device. Also + * initialize the vb2 queue. + * + * Return 0 on success or a negative error code otherwise + */ + +int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, + const char *name) +{ + struct media_pad *pad = &video->pad; + struct video_device *vdev; + struct vb2_queue *q; + int ret; + + vdev = &video->vdev; + + mutex_init(&video->q_lock); + + q = &video->vb2_q; + q->drv_priv = video; + q->mem_ops = &vb2_dma_sg_memops; + q->ops = &msm_video_vb2_q_ops; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->buf_struct_size = sizeof(struct camss_buffer); + q->dev = video->camss->dev; + q->lock = &video->q_lock; + ret = vb2_queue_init(q); + if (ret < 0) { + dev_err(v4l2_dev->dev, "Failed to init vb2 queue: %d\n", ret); + goto error_vb2_init; + } + + pad->flags = MEDIA_PAD_FL_SINK; + ret = media_entity_pads_init(&vdev->entity, 1, pad); + if (ret < 0) { + dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n", + ret); + goto error_media_init; + } + + mutex_init(&video->lock); + + ret = msm_video_init_format(video); + if (ret < 0) { + dev_err(v4l2_dev->dev, "Failed to init format: %d\n", ret); + goto error_video_register; + } + + vdev->fops = &msm_vid_fops; + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; + vdev->ioctl_ops = &msm_vid_ioctl_ops; + vdev->release = msm_video_release; + vdev->v4l2_dev = v4l2_dev; + vdev->vfl_dir = VFL_DIR_RX; + vdev->queue = &video->vb2_q; + vdev->lock = &video->lock; + strlcpy(vdev->name, name, sizeof(vdev->name)); + + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + if (ret < 0) { + dev_err(v4l2_dev->dev, "Failed to register video device: %d\n", + ret); + goto error_video_register; + } + + video_set_drvdata(vdev, video); + atomic_inc(&video->camss->ref_count); + + return 0; + +error_video_register: + media_entity_cleanup(&vdev->entity); + mutex_destroy(&video->lock); +error_media_init: + vb2_queue_release(&video->vb2_q); +error_vb2_init: + mutex_destroy(&video->q_lock); + + return ret; +} + +void msm_video_stop_streaming(struct camss_video *video) +{ + if (vb2_is_streaming(&video->vb2_q)) + vb2_queue_release(&video->vb2_q); +} + +void msm_video_unregister(struct camss_video *video) +{ + atomic_inc(&video->camss->ref_count); + video_unregister_device(&video->vdev); + atomic_dec(&video->camss->ref_count); +} diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.h b/drivers/media/platform/qcom/camss-8x16/camss-video.h new file mode 100644 index 000000000000..0d2cef3d224a --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.h @@ -0,0 +1,64 @@ +/* + * camss-video.h + * + * Qualcomm MSM Camera Subsystem - V4L2 device node + * + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_VIDEO_H +#define QC_MSM_CAMSS_VIDEO_H + +#include +#include +#include +#include +#include +#include +#include +#include + +struct camss_buffer { + struct vb2_v4l2_buffer vb; + dma_addr_t addr; + struct list_head queue; +}; + +struct camss_video; + +struct camss_video_ops { + int (*queue_buffer)(struct camss_video *vid, struct camss_buffer *buf); + int (*flush_buffers)(struct camss_video *vid, + enum vb2_buffer_state state); +}; + +struct camss_video { + struct camss *camss; + struct vb2_queue vb2_q; + struct video_device vdev; + struct media_pad pad; + struct v4l2_format active_fmt; + enum v4l2_buf_type type; + struct media_pipeline pipe; + const struct camss_video_ops *ops; + struct mutex lock; + struct mutex q_lock; +}; + +void msm_video_stop_streaming(struct camss_video *video); + +int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, + const char *name); + +void msm_video_unregister(struct camss_video *video); + +#endif /* QC_MSM_CAMSS_VIDEO_H */ -- cgit v1.2.3 From a1d7c116fcf77c710d2922a0b75067a30c69baed Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:07 -0400 Subject: media: camms: Add core files These files implement the platform driver code. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss.c | 699 +++++++++++++++++++++++++ drivers/media/platform/qcom/camss-8x16/camss.h | 97 ++++ 2 files changed, 796 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/camss.c create mode 100644 drivers/media/platform/qcom/camss-8x16/camss.h (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c new file mode 100644 index 000000000000..2dee77a80327 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss.c @@ -0,0 +1,699 @@ +/* + * camss.c + * + * Qualcomm MSM Camera Subsystem - Core + * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "camss.h" + +static const struct resources csiphy_res[] = { + /* CSIPHY0 */ + { + .regulator = { NULL }, + .clock = { "camss_top_ahb", "ispif_ahb", + "camss_ahb", "csiphy0_timer" }, + .clock_rate = { 0, 0, 0, 200000000 }, + .reg = { "csiphy0", "csiphy0_clk_mux" }, + .interrupt = { "csiphy0" } + }, + + /* CSIPHY1 */ + { + .regulator = { NULL }, + .clock = { "camss_top_ahb", "ispif_ahb", + "camss_ahb", "csiphy1_timer" }, + .clock_rate = { 0, 0, 0, 200000000 }, + .reg = { "csiphy1", "csiphy1_clk_mux" }, + .interrupt = { "csiphy1" } + } +}; + +static const struct resources csid_res[] = { + /* CSID0 */ + { + .regulator = { "vdda" }, + .clock = { "camss_top_ahb", "ispif_ahb", + "csi0_ahb", "camss_ahb", + "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, + .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 }, + .reg = { "csid0" }, + .interrupt = { "csid0" } + }, + + /* CSID1 */ + { + .regulator = { "vdda" }, + .clock = { "camss_top_ahb", "ispif_ahb", + "csi1_ahb", "camss_ahb", + "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, + .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 }, + .reg = { "csid1" }, + .interrupt = { "csid1" } + }, +}; + +static const struct resources_ispif ispif_res = { + /* ISPIF */ + .clock = { "camss_top_ahb", "camss_ahb", "ispif_ahb", + "csi0", "csi0_pix", "csi0_rdi", + "csi1", "csi1_pix", "csi1_rdi" }, + .clock_for_reset = { "camss_vfe_vfe", "camss_csi_vfe" }, + .reg = { "ispif", "csi_clk_mux" }, + .interrupt = "ispif" + +}; + +static const struct resources vfe_res = { + /* VFE0 */ + .regulator = { NULL }, + .clock = { "camss_top_ahb", "camss_vfe_vfe", "camss_csi_vfe", + "iface", "bus", "camss_ahb" }, + .clock_rate = { 0, 320000000, 0, 0, 0, 0, 0, 0 }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" } +}; + +/* + * camss_enable_clocks - Enable multiple clocks + * @nclocks: Number of clocks in clock array + * @clock: Clock array + * @dev: Device + * + * Return 0 on success or a negative error code otherwise + */ +int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev) +{ + int ret; + int i; + + for (i = 0; i < nclocks; i++) { + ret = clk_prepare_enable(clock[i]); + if (ret) { + dev_err(dev, "clock enable failed: %d\n", ret); + goto error; + } + } + + return 0; + +error: + for (i--; i >= 0; i--) + clk_disable_unprepare(clock[i]); + + return ret; +} + +/* + * camss_disable_clocks - Disable multiple clocks + * @nclocks: Number of clocks in clock array + * @clock: Clock array + */ +void camss_disable_clocks(int nclocks, struct clk **clock) +{ + int i; + + for (i = nclocks - 1; i >= 0; i--) + clk_disable_unprepare(clock[i]); +} + +/* + * camss_find_sensor - Find a linked media entity which represents a sensor + * @entity: Media entity to start searching from + * + * Return a pointer to sensor media entity or NULL if not found + */ +static struct media_entity *camss_find_sensor(struct media_entity *entity) +{ + struct media_pad *pad; + + while (1) { + pad = &entity->pads[0]; + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + return NULL; + + pad = media_entity_remote_pad(pad); + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) + return NULL; + + entity = pad->entity; + + if (entity->function == MEDIA_ENT_F_CAM_SENSOR) + return entity; + } +} + +/* + * camss_get_pixel_clock - Get pixel clock rate from sensor + * @entity: Media entity in the current pipeline + * @pixel_clock: Received pixel clock value + * + * Return 0 on success or a negative error code otherwise + */ +int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock) +{ + struct media_entity *sensor; + struct v4l2_subdev *subdev; + struct v4l2_ctrl *ctrl; + + sensor = camss_find_sensor(entity); + if (!sensor) + return -ENODEV; + + subdev = media_entity_to_v4l2_subdev(sensor); + + ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); + + if (!ctrl) + return -EINVAL; + + *pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl); + + return 0; +} + +/* + * camss_of_parse_endpoint_node - Parse port endpoint node + * @dev: Device + * @node: Device node to be parsed + * @csd: Parsed data from port endpoint node + * + * Return 0 on success or a negative error code on failure + */ +static int camss_of_parse_endpoint_node(struct device *dev, + struct device_node *node, + struct camss_async_subdev *csd) +{ + struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; + struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2; + struct v4l2_fwnode_endpoint vep = { { 0 } }; + unsigned int i; + + v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + + csd->interface.csiphy_id = vep.base.port; + + mipi_csi2 = &vep.bus.mipi_csi2; + lncfg->clk.pos = mipi_csi2->clock_lane; + lncfg->clk.pol = mipi_csi2->lane_polarities[0]; + lncfg->num_data = mipi_csi2->num_data_lanes; + + lncfg->data = devm_kzalloc(dev, lncfg->num_data * sizeof(*lncfg->data), + GFP_KERNEL); + if (!lncfg->data) + return -ENOMEM; + + for (i = 0; i < lncfg->num_data; i++) { + lncfg->data[i].pos = mipi_csi2->data_lanes[i]; + lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; + } + + return 0; +} + +/* + * camss_of_parse_ports - Parse ports node + * @dev: Device + * @notifier: v4l2_device notifier data + * + * Return number of "port" nodes found in "ports" node + */ +static int camss_of_parse_ports(struct device *dev, + struct v4l2_async_notifier *notifier) +{ + struct device_node *node = NULL; + struct device_node *remote = NULL; + unsigned int size, i; + int ret; + + while ((node = of_graph_get_next_endpoint(dev->of_node, node))) + if (of_device_is_available(node)) + notifier->num_subdevs++; + + size = sizeof(*notifier->subdevs) * notifier->num_subdevs; + notifier->subdevs = devm_kzalloc(dev, size, GFP_KERNEL); + if (!notifier->subdevs) { + dev_err(dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + i = 0; + while ((node = of_graph_get_next_endpoint(dev->of_node, node))) { + struct camss_async_subdev *csd; + + if (!of_device_is_available(node)) + continue; + + csd = devm_kzalloc(dev, sizeof(*csd), GFP_KERNEL); + if (!csd) { + of_node_put(node); + dev_err(dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + notifier->subdevs[i++] = &csd->asd; + + ret = camss_of_parse_endpoint_node(dev, node, csd); + if (ret < 0) { + of_node_put(node); + return ret; + } + + remote = of_graph_get_remote_port_parent(node); + of_node_put(node); + + if (!remote) { + dev_err(dev, "Cannot get remote parent\n"); + return -EINVAL; + } + + csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; + csd->asd.match.fwnode.fwnode = of_fwnode_handle(remote); + } + + return notifier->num_subdevs; +} + +/* + * camss_init_subdevices - Initialize subdev structures and resources + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_init_subdevices(struct camss *camss) +{ + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(camss->csiphy); i++) { + ret = msm_csiphy_subdev_init(&camss->csiphy[i], + &csiphy_res[i], i); + if (ret < 0) { + dev_err(camss->dev, + "Failed to init csiphy%d sub-device: %d\n", + i, ret); + return ret; + } + } + + for (i = 0; i < ARRAY_SIZE(camss->csid); i++) { + ret = msm_csid_subdev_init(&camss->csid[i], + &csid_res[i], i); + if (ret < 0) { + dev_err(camss->dev, + "Failed to init csid%d sub-device: %d\n", + i, ret); + return ret; + } + } + + ret = msm_ispif_subdev_init(&camss->ispif, &ispif_res); + if (ret < 0) { + dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", + ret); + return ret; + } + + ret = msm_vfe_subdev_init(&camss->vfe, &vfe_res); + if (ret < 0) { + dev_err(camss->dev, "Fail to init vfe sub-device: %d\n", ret); + return ret; + } + + return 0; +} + +/* + * camss_register_entities - Register subdev nodes and create links + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_register_entities(struct camss *camss) +{ + int i, j; + int ret; + + for (i = 0; i < ARRAY_SIZE(camss->csiphy); i++) { + ret = msm_csiphy_register_entity(&camss->csiphy[i], + &camss->v4l2_dev); + if (ret < 0) { + dev_err(camss->dev, + "Failed to register csiphy%d entity: %d\n", + i, ret); + goto err_reg_csiphy; + } + } + + for (i = 0; i < ARRAY_SIZE(camss->csid); i++) { + ret = msm_csid_register_entity(&camss->csid[i], + &camss->v4l2_dev); + if (ret < 0) { + dev_err(camss->dev, + "Failed to register csid%d entity: %d\n", + i, ret); + goto err_reg_csid; + } + } + + ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev); + if (ret < 0) { + dev_err(camss->dev, "Failed to register ispif entities: %d\n", + ret); + goto err_reg_ispif; + } + + ret = msm_vfe_register_entities(&camss->vfe, &camss->v4l2_dev); + if (ret < 0) { + dev_err(camss->dev, "Failed to register vfe entities: %d\n", + ret); + goto err_reg_vfe; + } + + for (i = 0; i < ARRAY_SIZE(camss->csiphy); i++) { + for (j = 0; j < ARRAY_SIZE(camss->csid); j++) { + ret = media_create_pad_link( + &camss->csiphy[i].subdev.entity, + MSM_CSIPHY_PAD_SRC, + &camss->csid[j].subdev.entity, + MSM_CSID_PAD_SINK, + 0); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + camss->csiphy[i].subdev.entity.name, + camss->csid[j].subdev.entity.name, + ret); + goto err_link; + } + } + } + + for (i = 0; i < ARRAY_SIZE(camss->csid); i++) { + for (j = 0; j < ARRAY_SIZE(camss->ispif.line); j++) { + ret = media_create_pad_link( + &camss->csid[i].subdev.entity, + MSM_CSID_PAD_SRC, + &camss->ispif.line[j].subdev.entity, + MSM_ISPIF_PAD_SINK, + 0); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + camss->csid[i].subdev.entity.name, + camss->ispif.line[j].subdev.entity.name, + ret); + goto err_link; + } + } + } + + for (i = 0; i < ARRAY_SIZE(camss->ispif.line); i++) { + for (j = 0; j < ARRAY_SIZE(camss->vfe.line); j++) { + ret = media_create_pad_link( + &camss->ispif.line[i].subdev.entity, + MSM_ISPIF_PAD_SRC, + &camss->vfe.line[j].subdev.entity, + MSM_VFE_PAD_SINK, + 0); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + camss->ispif.line[i].subdev.entity.name, + camss->vfe.line[j].subdev.entity.name, + ret); + goto err_link; + } + } + } + + return 0; + +err_link: + msm_vfe_unregister_entities(&camss->vfe); +err_reg_vfe: + msm_ispif_unregister_entities(&camss->ispif); +err_reg_ispif: + + i = ARRAY_SIZE(camss->csid); +err_reg_csid: + for (i--; i >= 0; i--) + msm_csid_unregister_entity(&camss->csid[i]); + + i = ARRAY_SIZE(camss->csiphy); +err_reg_csiphy: + for (i--; i >= 0; i--) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + + return ret; +} + +/* + * camss_unregister_entities - Unregister subdev nodes + * @camss: CAMSS device + * + * Return 0 on success or a negative error code on failure + */ +static void camss_unregister_entities(struct camss *camss) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(camss->csiphy); i++) + msm_csiphy_unregister_entity(&camss->csiphy[i]); + + for (i = 0; i < ARRAY_SIZE(camss->csid); i++) + msm_csid_unregister_entity(&camss->csid[i]); + + msm_ispif_unregister_entities(&camss->ispif); + msm_vfe_unregister_entities(&camss->vfe); +} + +static int camss_subdev_notifier_bound(struct v4l2_async_notifier *async, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct camss *camss = container_of(async, struct camss, notifier); + struct camss_async_subdev *csd = + container_of(asd, struct camss_async_subdev, asd); + u8 id = csd->interface.csiphy_id; + struct csiphy_device *csiphy = &camss->csiphy[id]; + + csiphy->cfg.csi2 = &csd->interface.csi2; + subdev->host_priv = csiphy; + + return 0; +} + +static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) +{ + struct camss *camss = container_of(async, struct camss, notifier); + struct v4l2_device *v4l2_dev = &camss->v4l2_dev; + struct v4l2_subdev *sd; + int ret; + + list_for_each_entry(sd, &v4l2_dev->subdevs, list) { + if (sd->host_priv) { + struct media_entity *sensor = &sd->entity; + struct csiphy_device *csiphy = + (struct csiphy_device *) sd->host_priv; + struct media_entity *input = &csiphy->subdev.entity; + unsigned int i; + + for (i = 0; i < sensor->num_pads; i++) { + if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) + break; + } + if (i == sensor->num_pads) { + dev_err(camss->dev, + "No source pad in external entity\n"); + return -EINVAL; + } + + ret = media_create_pad_link(sensor, i, + input, MSM_CSIPHY_PAD_SINK, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret < 0) { + dev_err(camss->dev, + "Failed to link %s->%s entities: %d\n", + sensor->name, input->name, ret); + return ret; + } + } + } + + ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); + if (ret < 0) + return ret; + + return media_device_register(&camss->media_dev); +} + +static const struct media_device_ops camss_media_ops = { + .link_notify = v4l2_pipeline_link_notify, +}; + +/* + * camss_probe - Probe CAMSS platform device + * @pdev: Pointer to CAMSS platform device + * + * Return 0 on success or a negative error code on failure + */ +static int camss_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct camss *camss; + int ret; + + camss = kzalloc(sizeof(*camss), GFP_KERNEL); + if (!camss) + return -ENOMEM; + + atomic_set(&camss->ref_count, 0); + camss->dev = dev; + platform_set_drvdata(pdev, camss); + + ret = camss_of_parse_ports(dev, &camss->notifier); + if (ret < 0) + return ret; + + ret = camss_init_subdevices(camss); + if (ret < 0) + return ret; + + ret = dma_set_mask_and_coherent(dev, 0xffffffff); + if (ret) + return ret; + + camss->media_dev.dev = camss->dev; + strlcpy(camss->media_dev.model, "Qualcomm Camera Subsystem", + sizeof(camss->media_dev.model)); + camss->media_dev.ops = &camss_media_ops; + media_device_init(&camss->media_dev); + + camss->v4l2_dev.mdev = &camss->media_dev; + ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); + if (ret < 0) { + dev_err(dev, "Failed to register V4L2 device: %d\n", ret); + return ret; + } + + ret = camss_register_entities(camss); + if (ret < 0) + goto err_register_entities; + + if (camss->notifier.num_subdevs) { + camss->notifier.bound = camss_subdev_notifier_bound; + camss->notifier.complete = camss_subdev_notifier_complete; + + ret = v4l2_async_notifier_register(&camss->v4l2_dev, + &camss->notifier); + if (ret) { + dev_err(dev, + "Failed to register async subdev nodes: %d\n", + ret); + goto err_register_subdevs; + } + } else { + ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); + if (ret < 0) { + dev_err(dev, "Failed to register subdev nodes: %d\n", + ret); + goto err_register_subdevs; + } + + ret = media_device_register(&camss->media_dev); + if (ret < 0) { + dev_err(dev, "Failed to register media device: %d\n", + ret); + goto err_register_subdevs; + } + } + + return 0; + +err_register_subdevs: + camss_unregister_entities(camss); +err_register_entities: + v4l2_device_unregister(&camss->v4l2_dev); + + return ret; +} + +void camss_delete(struct camss *camss) +{ + v4l2_device_unregister(&camss->v4l2_dev); + media_device_unregister(&camss->media_dev); + media_device_cleanup(&camss->media_dev); + + kfree(camss); +} + +/* + * camss_remove - Remove CAMSS platform device + * @pdev: Pointer to CAMSS platform device + * + * Always returns 0. + */ +static int camss_remove(struct platform_device *pdev) +{ + struct camss *camss = platform_get_drvdata(pdev); + + msm_vfe_stop_streaming(&camss->vfe); + + v4l2_async_notifier_unregister(&camss->notifier); + camss_unregister_entities(camss); + + if (atomic_read(&camss->ref_count) == 0) + camss_delete(camss); + + return 0; +} + +static const struct of_device_id camss_dt_match[] = { + { .compatible = "qcom,msm8916-camss" }, + { } +}; + +MODULE_DEVICE_TABLE(of, camss_dt_match); + +static struct platform_driver qcom_camss_driver = { + .probe = camss_probe, + .remove = camss_remove, + .driver = { + .name = "qcom-camss", + .of_match_table = camss_dt_match, + }, +}; + +module_platform_driver(qcom_camss_driver); + +MODULE_ALIAS("platform:qcom-camss"); +MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver"); +MODULE_AUTHOR("Todor Tomov "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/qcom/camss-8x16/camss.h b/drivers/media/platform/qcom/camss-8x16/camss.h new file mode 100644 index 000000000000..4619d7634207 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/camss.h @@ -0,0 +1,97 @@ +/* + * camss.h + * + * Qualcomm MSM Camera Subsystem - Core + * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2015-2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef QC_MSM_CAMSS_H +#define QC_MSM_CAMSS_H + +#include +#include +#include +#include +#include +#include +#include + +#include "camss-csid.h" +#include "camss-csiphy.h" +#include "camss-ispif.h" +#include "camss-vfe.h" + +#define CAMSS_CSID_NUM 2 +#define CAMSS_CSIPHY_NUM 2 + +#define to_camss(ptr_module) \ + container_of(ptr_module, struct camss, ptr_module) + +#define to_device(ptr_module) \ + (to_camss(ptr_module)->dev) + +#define module_pointer(ptr_module, index) \ + ((const struct ptr_module##_device (*)[]) &(ptr_module[-(index)])) + +#define to_camss_index(ptr_module, index) \ + container_of(module_pointer(ptr_module, index), \ + struct camss, ptr_module) + +#define to_device_index(ptr_module, index) \ + (to_camss_index(ptr_module, index)->dev) + +#define CAMSS_RES_MAX 15 + +struct resources { + char *regulator[CAMSS_RES_MAX]; + char *clock[CAMSS_RES_MAX]; + s32 clock_rate[CAMSS_RES_MAX]; + char *reg[CAMSS_RES_MAX]; + char *interrupt[CAMSS_RES_MAX]; +}; + +struct resources_ispif { + char *clock[CAMSS_RES_MAX]; + char *clock_for_reset[CAMSS_RES_MAX]; + char *reg[CAMSS_RES_MAX]; + char *interrupt; +}; + +struct camss { + struct v4l2_device v4l2_dev; + struct v4l2_async_notifier notifier; + struct media_device media_dev; + struct device *dev; + struct csiphy_device csiphy[CAMSS_CSIPHY_NUM]; + struct csid_device csid[CAMSS_CSID_NUM]; + struct ispif_device ispif; + struct vfe_device vfe; + atomic_t ref_count; +}; + +struct camss_camera_interface { + u8 csiphy_id; + struct csiphy_csi2_cfg csi2; +}; + +struct camss_async_subdev { + struct camss_camera_interface interface; + struct v4l2_async_subdev asd; +}; + +int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev); +void camss_disable_clocks(int nclocks, struct clk **clock); +int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock); +void camss_delete(struct camss *camss); + +#endif /* QC_MSM_CAMSS_H */ -- cgit v1.2.3 From f5c074947f56533c5ee41a6c5a6df4408eeafc35 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:08 -0400 Subject: media: camss: Enable building Add Makefile and update platform/Kconfig and platform/Makefile to enable building of the QCom CAMSS driver. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Kconfig | 7 +++++++ drivers/media/platform/Makefile | 2 ++ drivers/media/platform/qcom/camss-8x16/Makefile | 11 +++++++++++ 3 files changed, 20 insertions(+) create mode 100644 drivers/media/platform/qcom/camss-8x16/Makefile (limited to 'drivers') diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index df74fa96229d..7e7cc49b8674 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -110,6 +110,13 @@ config VIDEO_PXA27x ---help--- This is a v4l2 driver for the PXA27x Quick Capture Interface +config VIDEO_QCOM_CAMSS + tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST + select VIDEOBUF2_DMA_SG + select V4L2_FWNODE + config VIDEO_S3C_CAMIF tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index a52d7b62292d..c1ef946bf032 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -85,6 +85,8 @@ obj-$(CONFIG_VIDEO_MEDIATEK_MDP) += mtk-mdp/ obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk-jpeg/ +obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/ + obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ obj-y += meson/ diff --git a/drivers/media/platform/qcom/camss-8x16/Makefile b/drivers/media/platform/qcom/camss-8x16/Makefile new file mode 100644 index 000000000000..3c4024fbb768 --- /dev/null +++ b/drivers/media/platform/qcom/camss-8x16/Makefile @@ -0,0 +1,11 @@ +# Makefile for Qualcomm CAMSS driver + +qcom-camss-objs += \ + camss.o \ + camss-csid.o \ + camss-csiphy.o \ + camss-ispif.o \ + camss-vfe.o \ + camss-video.o \ + +obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom-camss.o -- cgit v1.2.3 From 9b5833f7b82f143162f3fe2af5ad05deb1338316 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:09 -0400 Subject: media: camss: vfe: Format conversion support using PIX interface Use VFE PIX input interface and do format conversion in VFE. Supported input format is UYVY (single plane YUV 4:2:2) and its different sample order variations. Supported output formats are: - NV12/NV21 (two plane YUV 4:2:0) - NV16/NV61 (two plane YUV 4:2:2) Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-ispif.c | 2 + drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 705 ++++++++++++++++++--- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 13 +- .../media/platform/qcom/camss-8x16/camss-video.c | 308 ++++++--- .../media/platform/qcom/camss-8x16/camss-video.h | 8 +- 5 files changed, 879 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c index b0478117585e..31e00e534a6a 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -1003,6 +1003,8 @@ static enum ispif_intf ispif_get_intf(enum vfe_line_id line_id) return RDI1; case (VFE_LINE_RDI2): return RDI2; + case (VFE_LINE_PIX): + return PIX0; default: return RDI0; } diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index fe6b8abd49d9..44605e0eb355 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -52,29 +53,53 @@ #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR (1 << 7) #define VFE_0_GLOBAL_RESET_CMD_TESTGEN (1 << 8) +#define VFE_0_MODULE_CFG 0x018 +#define VFE_0_MODULE_CFG_DEMUX (1 << 2) +#define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE (1 << 3) +#define VFE_0_MODULE_CFG_SCALE_ENC (1 << 23) + +#define VFE_0_CORE_CFG 0x01c +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6 +#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7 + #define VFE_0_IRQ_CMD 0x024 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR (1 << 0) #define VFE_0_IRQ_MASK_0 0x028 +#define VFE_0_IRQ_MASK_0_CAMIF_SOF (1 << 0) +#define VFE_0_IRQ_MASK_0_CAMIF_EOF (1 << 1) #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5)) +#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \ + ((n) == VFE_LINE_PIX ? (1 << 4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)) #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) (1 << ((n) + 25)) #define VFE_0_IRQ_MASK_0_RESET_ACK (1 << 31) #define VFE_0_IRQ_MASK_1 0x02c +#define VFE_0_IRQ_MASK_1_CAMIF_ERROR (1 << 0) #define VFE_0_IRQ_MASK_1_VIOLATION (1 << 7) #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK (1 << 8) #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) (1 << ((n) + 9)) +#define VFE_0_IRQ_MASK_1_RDIn_SOF(n) (1 << ((n) + 29)) #define VFE_0_IRQ_CLEAR_0 0x030 #define VFE_0_IRQ_CLEAR_1 0x034 #define VFE_0_IRQ_STATUS_0 0x038 +#define VFE_0_IRQ_STATUS_0_CAMIF_SOF (1 << 0) #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) (1 << ((n) + 5)) +#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \ + ((n) == VFE_LINE_PIX ? (1 << 4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)) #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) (1 << ((n) + 8)) +#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) (1 << ((n) + 25)) #define VFE_0_IRQ_STATUS_0_RESET_ACK (1 << 31) #define VFE_0_IRQ_STATUS_1 0x03c #define VFE_0_IRQ_STATUS_1_VIOLATION (1 << 7) #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK (1 << 8) +#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) (1 << ((n) + 29)) +#define VFE_0_IRQ_COMPOSITE_MASK_0 0x40 #define VFE_0_VIOLATION_STATUS 0x48 #define VFE_0_BUS_CMD 0x4c @@ -83,7 +108,10 @@ #define VFE_0_BUS_CFG 0x050 #define VFE_0_BUS_XBAR_CFG_x(x) (0x58 + 0x4 * ((x) / 2)) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN (1 << 1) +#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4) #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 +#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 5 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 6 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 7 @@ -99,6 +127,8 @@ #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x07c + 0x24 * (n)) #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16 +#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x080 + 0x24 * (n)) +#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x084 + 0x24 * (n)) #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \ (0x088 + 0x24 * (n)) #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \ @@ -130,8 +160,60 @@ #define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3 #define VFE_0_RDI_CFG_x_RDI_Mr_FRAME_BASED_EN(r) (1 << (16 + (r))) +#define VFE_0_CAMIF_CMD 0x2f4 +#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0 +#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1 +#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS (1 << 2) +#define VFE_0_CAMIF_CFG 0x2f8 +#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN (1 << 6) +#define VFE_0_CAMIF_FRAME_CFG 0x300 +#define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x304 +#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x308 +#define VFE_0_CAMIF_SUBSAMPLE_CFG_0 0x30c +#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x314 +#define VFE_0_CAMIF_STATUS 0x31c +#define VFE_0_CAMIF_STATUS_HALT (1 << 31) + #define VFE_0_REG_UPDATE 0x378 #define VFE_0_REG_UPDATE_RDIn(n) (1 << (1 + (n))) +#define VFE_0_REG_UPDATE_line_n(n) \ + ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n)) + +#define VFE_0_DEMUX_CFG 0x424 +#define VFE_0_DEMUX_CFG_PERIOD 0x3 +#define VFE_0_DEMUX_GAIN_0 0x428 +#define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0) +#define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16) +#define VFE_0_DEMUX_GAIN_1 0x42c +#define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0) +#define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16) +#define VFE_0_DEMUX_EVEN_CFG 0x438 +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca +#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9 +#define VFE_0_DEMUX_ODD_CFG 0x43c +#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac +#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c +#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca +#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9 + +#define VFE_0_SCALE_ENC_CBCR_CFG 0x778 +#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x77c +#define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x780 +#define VFE_0_SCALE_ENC_CBCR_H_PAD 0x78c +#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x790 +#define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x794 +#define VFE_0_SCALE_ENC_CBCR_V_PAD 0x7a0 + +#define VFE_0_CLAMP_ENC_MAX_CFG 0x874 +#define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) +#define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8) +#define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16) +#define VFE_0_CLAMP_ENC_MIN_CFG 0x878 +#define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0) +#define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8) +#define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16) #define VFE_0_CGC_OVERRIDE_1 0x974 #define VFE_0_CGC_OVERRIDE_1_IMAGE_Mx_CGC_OVERRIDE(x) (1 << (x)) @@ -145,6 +227,11 @@ /* Frame drop value. NOTE: VAL + UPDATES should not exceed 31 */ #define VFE_FRAME_DROP_VAL 20 +#define VFE_NEXT_SOF_MS 500 + +#define CAMIF_TIMEOUT_SLEEP_US 1000 +#define CAMIF_TIMEOUT_ALL_US 1000000 + static const u32 vfe_formats[] = { MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_VYUY8_2X8, @@ -213,6 +300,32 @@ static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT); } +static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, + u16 width, u16 height, u32 enable) +{ + u32 reg; + + if (enable) { + reg = height - 1; + reg |= (width / 16 - 1) << 16; + + writel_relaxed(reg, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); + + reg = 0x3; + reg |= (height - 1) << 4; + reg |= (width / 8) << 16; + + writel_relaxed(reg, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); + } else { + writel_relaxed(0, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); + writel_relaxed(0, vfe->base + + VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); + } +} + static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per) { u32 reg; @@ -316,7 +429,10 @@ static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm, reg <<= 16; vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); +} +static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm) +{ writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); @@ -355,6 +471,38 @@ static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm, vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); } +static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, + u8 enable) +{ + struct vfe_line *line = container_of(output, struct vfe_line, output); + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + unsigned int i; + + for (i = 0; i < output->wm_num; i++) { + if (i == 0) { + reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA << + VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; + } else if (i == 1) { + reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16) + reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; + } + + if (output->wm_idx[i] % 2 == 1) + reg <<= 16; + + if (enable) + vfe_reg_set(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]), + reg); + else + vfe_reg_clr(vfe, + VFE_0_BUS_XBAR_CFG_x(output->wm_idx[i]), + reg); + } +} + static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) { vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), @@ -366,7 +514,7 @@ static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) { - vfe->reg_update |= VFE_0_REG_UPDATE_RDIn(line_id); + vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); wmb(); writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); wmb(); @@ -376,8 +524,9 @@ static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, enum vfe_line_id line_id, u8 enable) { u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) | - VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(line_id); - u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm); + VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); + u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) | + VFE_0_IRQ_MASK_1_RDIn_SOF(line_id); if (enable) { vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); @@ -388,6 +537,37 @@ static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, } } +static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp, + enum vfe_line_id line_id, u8 enable) +{ + struct vfe_output *output = &vfe->line[line_id].output; + unsigned int i; + u32 irq_en0; + u32 irq_en1; + u32 comp_mask = 0; + + irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF; + irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF; + irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp); + irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); + irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR; + for (i = 0; i < output->wm_num; i++) { + irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW( + output->wm_idx[i]); + comp_mask |= (1 << output->wm_idx[i]) << comp * 8; + } + + if (enable) { + vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); + vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); + } else { + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); + vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); + vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); + } +} + static void vfe_enable_irq_common(struct vfe_device *vfe) { u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK; @@ -398,6 +578,96 @@ static void vfe_enable_irq_common(struct vfe_device *vfe) vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); } +static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 val, even_cfg, odd_cfg; + + writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG); + + val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD; + writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0); + + val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2; + writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1); + + switch (line->fmt[MSM_VFE_PAD_SINK].code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + default: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY; + odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY; + break; + } + + writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG); + writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); +} + +static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + u16 input, output; + u8 interp_reso; + u32 phase_mult; + + writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); + + input = line->fmt[MSM_VFE_PAD_SINK].width; + output = line->fmt[MSM_VFE_PAD_SRC].width / 2; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); + + interp_reso = 3; + phase_mult = input * (1 << (13 + interp_reso)) / output; + reg = (interp_reso << 20) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); + + reg = input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PAD); + + input = line->fmt[MSM_VFE_PAD_SINK].height; + output = line->fmt[MSM_VFE_PAD_SRC].height; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) + output = line->fmt[MSM_VFE_PAD_SRC].height / 2; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); + + interp_reso = 3; + phase_mult = input * (1 << (13 + interp_reso)) / output; + reg = (interp_reso << 20) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); + + reg = input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PAD); +} + +static void vfe_set_clamp_cfg(struct vfe_device *vfe) +{ + u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 | + VFE_0_CLAMP_ENC_MAX_CFG_CH1 | + VFE_0_CLAMP_ENC_MAX_CFG_CH2; + + writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG); + + val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 | + VFE_0_CLAMP_ENC_MIN_CFG_CH1 | + VFE_0_CLAMP_ENC_MIN_CFG_CH2; + + writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); +} + /* * vfe_reset - Trigger reset on VFE module and wait to complete * @vfe: VFE device @@ -458,6 +728,10 @@ static void vfe_init_outputs(struct vfe_device *vfe) output->buf[0] = NULL; output->buf[1] = NULL; INIT_LIST_HEAD(&output->pending_bufs); + + output->wm_num = 1; + if (vfe->line[i].id == VFE_LINE_PIX) + output->wm_num = 2; } } @@ -496,52 +770,148 @@ static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) wmb(); } +static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) +{ + u32 val = VFE_0_MODULE_CFG_DEMUX | + VFE_0_MODULE_CFG_CHROMA_UPSAMPLE | + VFE_0_MODULE_CFG_SCALE_ENC; + + if (enable) + writel_relaxed(val, vfe->base + VFE_0_MODULE_CFG); + else + writel_relaxed(0x0, vfe->base + VFE_0_MODULE_CFG); +} + +static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 val; + + switch (line->fmt[MSM_VFE_PAD_SINK].code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + default: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY; + break; + } + + writel_relaxed(val, vfe->base + VFE_0_CORE_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].width * 2; + val |= line->fmt[MSM_VFE_PAD_SINK].height << 16; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG); + + val = line->fmt[MSM_VFE_PAD_SINK].height - 1; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG); + + val = 0xffffffff; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG_0); + + val = 0xffffffff; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN); + + val = VFE_0_RDI_CFG_x_MIPI_EN_BITS; + vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val); + + val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN; + writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG); +} + +static void vfe_set_camif_cmd(struct vfe_device *vfe, u32 cmd) +{ + writel_relaxed(VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS, + vfe->base + VFE_0_CAMIF_CMD); + + writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); +} + +static int vfe_camif_wait_for_stop(struct vfe_device *vfe) +{ + u32 val; + int ret; + + ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS, + val, + (val & VFE_0_CAMIF_STATUS_HALT), + CAMIF_TIMEOUT_SLEEP_US, + CAMIF_TIMEOUT_ALL_US); + if (ret < 0) + dev_err(to_device(vfe), "%s: camif stop timeout\n", __func__); + + return ret; +} + static void vfe_output_init_addrs(struct vfe_device *vfe, struct vfe_output *output, u8 sync) { - u32 ping_addr = 0; - u32 pong_addr = 0; + u32 ping_addr; + u32 pong_addr; + unsigned int i; output->active_buf = 0; - if (output->buf[0]) - ping_addr = output->buf[0]->addr; - - if (output->buf[1]) - pong_addr = output->buf[1]->addr; - else - pong_addr = ping_addr; + for (i = 0; i < output->wm_num; i++) { + if (output->buf[0]) + ping_addr = output->buf[0]->addr[i]; + else + ping_addr = 0; - vfe_wm_set_ping_addr(vfe, output->wm_idx, ping_addr); - vfe_wm_set_pong_addr(vfe, output->wm_idx, pong_addr); - if (sync) - vfe_bus_reload_wm(vfe, output->wm_idx); + if (output->buf[1]) + pong_addr = output->buf[1]->addr[i]; + else + pong_addr = ping_addr; + + vfe_wm_set_ping_addr(vfe, output->wm_idx[i], ping_addr); + vfe_wm_set_pong_addr(vfe, output->wm_idx[i], pong_addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx[i]); + } } static void vfe_output_update_ping_addr(struct vfe_device *vfe, struct vfe_output *output, u8 sync) { - u32 addr = 0; + u32 addr; + unsigned int i; - if (output->buf[0]) - addr = output->buf[0]->addr; + for (i = 0; i < output->wm_num; i++) { + if (output->buf[0]) + addr = output->buf[0]->addr[i]; + else + addr = 0; - vfe_wm_set_ping_addr(vfe, output->wm_idx, addr); - if (sync) - vfe_bus_reload_wm(vfe, output->wm_idx); + vfe_wm_set_ping_addr(vfe, output->wm_idx[i], addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx[i]); + } } static void vfe_output_update_pong_addr(struct vfe_device *vfe, struct vfe_output *output, u8 sync) { - u32 addr = 0; + u32 addr; + unsigned int i; - if (output->buf[1]) - addr = output->buf[1]->addr; + for (i = 0; i < output->wm_num; i++) { + if (output->buf[1]) + addr = output->buf[1]->addr[i]; + else + addr = 0; - vfe_wm_set_pong_addr(vfe, output->wm_idx, addr); - if (sync) - vfe_bus_reload_wm(vfe, output->wm_idx); + vfe_wm_set_pong_addr(vfe, output->wm_idx[i], addr); + if (sync) + vfe_bus_reload_wm(vfe, output->wm_idx[i]); + } } @@ -576,14 +946,19 @@ static void vfe_output_frame_drop(struct vfe_device *vfe, u32 drop_pattern) { u8 drop_period; + unsigned int i; /* We need to toggle update period to be valid on next frame */ output->drop_update_idx++; output->drop_update_idx %= VFE_FRAME_DROP_UPDATES; drop_period = VFE_FRAME_DROP_VAL + output->drop_update_idx; - vfe_wm_set_framedrop_period(vfe, output->wm_idx, drop_period); - vfe_wm_set_framedrop_pattern(vfe, output->wm_idx, drop_pattern); + for (i = 0; i < output->wm_num; i++) { + vfe_wm_set_framedrop_period(vfe, output->wm_idx[i], + drop_period); + vfe_wm_set_framedrop_pattern(vfe, output->wm_idx[i], + drop_pattern); + } vfe_reg_update(vfe, container_of(output, struct vfe_line, output)->id); } @@ -720,6 +1095,7 @@ static int vfe_get_output(struct vfe_line *line) struct vfe_device *vfe = to_vfe(line); struct vfe_output *output; unsigned long flags; + int i; int wm_idx; spin_lock_irqsave(&vfe->output_lock, flags); @@ -733,20 +1109,24 @@ static int vfe_get_output(struct vfe_line *line) output->active_buf = 0; - /* We will use only one wm per output for now */ - wm_idx = vfe_reserve_wm(vfe, line->id); - if (wm_idx < 0) { - dev_err(to_device(vfe), "Can not reserve wm\n"); - goto error_get_wm; + for (i = 0; i < output->wm_num; i++) { + wm_idx = vfe_reserve_wm(vfe, line->id); + if (wm_idx < 0) { + dev_err(to_device(vfe), "Can not reserve wm\n"); + goto error_get_wm; + } + output->wm_idx[i] = wm_idx; } + output->drop_update_idx = 0; - output->wm_idx = wm_idx; spin_unlock_irqrestore(&vfe->output_lock, flags); return 0; error_get_wm: + for (i--; i >= 0; i--) + vfe_release_wm(vfe, output->wm_idx[i]); output->state = VFE_OUTPUT_OFF; error: spin_unlock_irqrestore(&vfe->output_lock, flags); @@ -759,19 +1139,17 @@ static int vfe_put_output(struct vfe_line *line) struct vfe_device *vfe = to_vfe(line); struct vfe_output *output = &line->output; unsigned long flags; - int ret; + unsigned int i; spin_lock_irqsave(&vfe->output_lock, flags); - ret = vfe_release_wm(vfe, output->wm_idx); - if (ret < 0) - goto out; + for (i = 0; i < output->wm_num; i++) + vfe_release_wm(vfe, output->wm_idx[i]); output->state = VFE_OUTPUT_OFF; -out: spin_unlock_irqrestore(&vfe->output_lock, flags); - return ret; + return 0; } static int vfe_enable_output(struct vfe_line *line) @@ -779,6 +1157,7 @@ static int vfe_enable_output(struct vfe_line *line) struct vfe_device *vfe = to_vfe(line); struct vfe_output *output = &line->output; unsigned long flags; + unsigned int i; u16 ub_size; switch (vfe->id) { @@ -794,7 +1173,7 @@ static int vfe_enable_output(struct vfe_line *line) spin_lock_irqsave(&vfe->output_lock, flags); - vfe->reg_update &= ~VFE_0_REG_UPDATE_RDIn(line->id); + vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line->id); if (output->state != VFE_OUTPUT_RESERVED) { dev_err(to_device(vfe), "Output is not in reserved state %d\n", @@ -831,24 +1210,58 @@ static int vfe_enable_output(struct vfe_line *line) } output->sequence = 0; + output->wait_sof = 0; + output->wait_reg_update = 0; + reinit_completion(&output->sof); + reinit_completion(&output->reg_update); vfe_output_init_addrs(vfe, output, 0); - vfe_set_cgc_override(vfe, output->wm_idx, 1); - - vfe_enable_irq_wm_line(vfe, output->wm_idx, line->id, 1); - - vfe_bus_connect_wm_to_rdi(vfe, output->wm_idx, line->id); - - vfe_set_rdi_cid(vfe, line->id, 0); - - vfe_wm_set_ub_cfg(vfe, output->wm_idx, - (ub_size + 1) * output->wm_idx, ub_size); - - vfe_wm_frame_based(vfe, output->wm_idx, 1); - vfe_wm_enable(vfe, output->wm_idx, 1); + if (line->id != VFE_LINE_PIX) { + vfe_set_cgc_override(vfe, output->wm_idx[0], 1); + vfe_enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 1); + vfe_bus_connect_wm_to_rdi(vfe, output->wm_idx[0], line->id); + vfe_wm_set_subsample(vfe, output->wm_idx[0]); + vfe_set_rdi_cid(vfe, line->id, 0); + vfe_wm_set_ub_cfg(vfe, output->wm_idx[0], + (ub_size + 1) * output->wm_idx[0], ub_size); + vfe_wm_frame_based(vfe, output->wm_idx[0], 1); + vfe_wm_enable(vfe, output->wm_idx[0], 1); + vfe_bus_reload_wm(vfe, output->wm_idx[0]); + } else { + ub_size /= output->wm_num; + for (i = 0; i < output->wm_num; i++) { + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + + vfe_set_cgc_override(vfe, output->wm_idx[i], 1); + vfe_wm_set_subsample(vfe, output->wm_idx[i]); + vfe_wm_set_ub_cfg(vfe, output->wm_idx[i], + (ub_size + 1) * output->wm_idx[i], + ub_size); + if ((i == 1) && (p == V4L2_PIX_FMT_NV12 || + p == V4L2_PIX_FMT_NV21)) + vfe_wm_line_based(vfe, output->wm_idx[i], + line->fmt[MSM_VFE_PAD_SRC].width, + line->fmt[MSM_VFE_PAD_SRC].height / 2, + 1); + else + vfe_wm_line_based(vfe, output->wm_idx[i], + line->fmt[MSM_VFE_PAD_SRC].width, + line->fmt[MSM_VFE_PAD_SRC].height, + 1); - vfe_bus_reload_wm(vfe, output->wm_idx); + vfe_wm_enable(vfe, output->wm_idx[i], 1); + vfe_bus_reload_wm(vfe, output->wm_idx[i]); + } + vfe_enable_irq_pix_line(vfe, 0, line->id, 1); + vfe_set_module_cfg(vfe, 1); + vfe_set_camif_cfg(vfe, line); + vfe_set_xbar_cfg(vfe, output, 1); + vfe_set_demux_cfg(vfe, line); + vfe_set_scale_cfg(vfe, line); + vfe_set_clamp_cfg(vfe); + vfe_set_camif_cmd(vfe, VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY); + } vfe_reg_update(vfe, line->id); @@ -862,15 +1275,56 @@ static int vfe_disable_output(struct vfe_line *line) struct vfe_device *vfe = to_vfe(line); struct vfe_output *output = &line->output; unsigned long flags; + unsigned long time; + unsigned int i; spin_lock_irqsave(&vfe->output_lock, flags); - vfe_wm_enable(vfe, output->wm_idx, 0); - vfe_bus_disconnect_wm_from_rdi(vfe, output->wm_idx, line->id); - vfe_reg_update(vfe, line->id); + output->wait_sof = 1; + spin_unlock_irqrestore(&vfe->output_lock, flags); + + time = wait_for_completion_timeout(&output->sof, + msecs_to_jiffies(VFE_NEXT_SOF_MS)); + if (!time) + dev_err(to_device(vfe), "VFE sof timeout\n"); + spin_lock_irqsave(&vfe->output_lock, flags); + for (i = 0; i < output->wm_num; i++) + vfe_wm_enable(vfe, output->wm_idx[i], 0); + + vfe_reg_update(vfe, line->id); + output->wait_reg_update = 1; spin_unlock_irqrestore(&vfe->output_lock, flags); + time = wait_for_completion_timeout(&output->reg_update, + msecs_to_jiffies(VFE_NEXT_SOF_MS)); + if (!time) + dev_err(to_device(vfe), "VFE reg update timeout\n"); + + spin_lock_irqsave(&vfe->output_lock, flags); + + if (line->id != VFE_LINE_PIX) { + vfe_wm_frame_based(vfe, output->wm_idx[0], 0); + vfe_bus_disconnect_wm_from_rdi(vfe, output->wm_idx[0], line->id); + vfe_enable_irq_wm_line(vfe, output->wm_idx[0], line->id, 0); + vfe_set_cgc_override(vfe, output->wm_idx[0], 0); + spin_unlock_irqrestore(&vfe->output_lock, flags); + } else { + for (i = 0; i < output->wm_num; i++) { + vfe_wm_line_based(vfe, output->wm_idx[i], 0, 0, 0); + vfe_set_cgc_override(vfe, output->wm_idx[i], 0); + } + + vfe_enable_irq_pix_line(vfe, 0, line->id, 0); + vfe_set_module_cfg(vfe, 0); + vfe_set_xbar_cfg(vfe, output, 0); + + vfe_set_camif_cmd(vfe, VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY); + spin_unlock_irqrestore(&vfe->output_lock, flags); + + vfe_camif_wait_for_stop(vfe); + } + return 0; } @@ -938,6 +1392,10 @@ static int vfe_disable(struct vfe_line *line) { struct vfe_device *vfe = to_vfe(line); + vfe_disable_output(line); + + vfe_put_output(line); + mutex_lock(&vfe->stream_lock); if (vfe->stream_count == 1) @@ -947,11 +1405,26 @@ static int vfe_disable(struct vfe_line *line) mutex_unlock(&vfe->stream_lock); - vfe_disable_output(line); + return 0; +} - vfe_put_output(line); +/* + * vfe_isr_sof - Process start of frame interrupt + * @vfe: VFE Device + * @line_id: VFE line + */ +static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id) +{ + struct vfe_output *output; + unsigned long flags; - return 0; + spin_lock_irqsave(&vfe->output_lock, flags); + output = &vfe->line[line_id].output; + if (output->wait_sof) { + output->wait_sof = 0; + complete(&output->sof); + } + spin_unlock_irqrestore(&vfe->output_lock, flags); } /* @@ -965,9 +1438,17 @@ static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) unsigned long flags; spin_lock_irqsave(&vfe->output_lock, flags); - vfe->reg_update &= ~VFE_0_REG_UPDATE_RDIn(line_id); + vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id); output = &vfe->line[line_id].output; + + if (output->wait_reg_update) { + output->wait_reg_update = 0; + complete(&output->reg_update); + spin_unlock_irqrestore(&vfe->output_lock, flags); + return; + } + if (output->state == VFE_OUTPUT_STOPPING) { /* Release last buffer when hw is idle */ if (output->last_buffer) { @@ -1021,10 +1502,11 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) { struct camss_buffer *ready_buf; struct vfe_output *output; - dma_addr_t new_addr; + dma_addr_t *new_addr; unsigned long flags; u32 active_index; u64 ts = ktime_get_ns(); + unsigned int i; active_index = vfe_wm_get_ping_pong_status(vfe, wm); @@ -1067,9 +1549,13 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm) } if (active_index) - vfe_wm_set_ping_addr(vfe, wm, new_addr); + for (i = 0; i < output->wm_num; i++) + vfe_wm_set_ping_addr(vfe, output->wm_idx[i], + new_addr[i]); else - vfe_wm_set_pong_addr(vfe, wm, new_addr); + for (i = 0; i < output->wm_num; i++) + vfe_wm_set_pong_addr(vfe, output->wm_idx[i], + new_addr[i]); spin_unlock_irqrestore(&vfe->output_lock, flags); @@ -1084,6 +1570,22 @@ out_unlock: spin_unlock_irqrestore(&vfe->output_lock, flags); } +/* + * vfe_isr_wm_done - Process composite image done interrupt + * @vfe: VFE Device + * @comp: Composite image id + */ +static void vfe_isr_comp_done(struct vfe_device *vfe, u8 comp) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(vfe->wm_output_map); i++) + if (vfe->wm_output_map[i] == VFE_LINE_PIX) { + vfe_isr_wm_done(vfe, i); + break; + } +} + /* * vfe_isr - ISPIF module interrupt handler * @irq: Interrupt line @@ -1096,7 +1598,7 @@ static irqreturn_t vfe_isr(int irq, void *dev) struct vfe_device *vfe = dev; u32 value0, value1; u32 violation; - int i; + int i, j; value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); @@ -1121,10 +1623,25 @@ static irqreturn_t vfe_isr(int irq, void *dev) writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); } - for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) - if (value0 & VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(i)) + for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) + if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i)) vfe_isr_reg_update(vfe, i); + if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF) + vfe_isr_sof(vfe, VFE_LINE_PIX); + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) + if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i)) + vfe_isr_sof(vfe, i); + + for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++) + if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) { + vfe_isr_comp_done(vfe, i); + for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++) + if (vfe->wm_output_map[j] == VFE_LINE_PIX) + value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j); + } + for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i)) vfe_isr_wm_done(vfe, i); @@ -1394,6 +1911,7 @@ static void vfe_try_format(struct vfe_line *line, enum v4l2_subdev_format_whence which) { unsigned int i; + u32 code; switch (pad) { case MSM_VFE_PAD_SINK: @@ -1418,9 +1936,40 @@ static void vfe_try_format(struct vfe_line *line, case MSM_VFE_PAD_SRC: /* Set and return a format same as sink pad */ + code = fmt->code; + *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); + if (line->id == VFE_LINE_PIX) + switch (fmt->code) { + case MEDIA_BUS_FMT_YUYV8_2X8: + if (code == MEDIA_BUS_FMT_YUYV8_1_5X8) + fmt->code = MEDIA_BUS_FMT_YUYV8_1_5X8; + else + fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + if (code == MEDIA_BUS_FMT_YVYU8_1_5X8) + fmt->code = MEDIA_BUS_FMT_YVYU8_1_5X8; + else + fmt->code = MEDIA_BUS_FMT_YVYU8_2X8; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + default: + if (code == MEDIA_BUS_FMT_UYVY8_1_5X8) + fmt->code = MEDIA_BUS_FMT_UYVY8_1_5X8; + else + fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + if (code == MEDIA_BUS_FMT_VYUY8_1_5X8) + fmt->code = MEDIA_BUS_FMT_VYUY8_1_5X8; + else + fmt->code = MEDIA_BUS_FMT_VYUY8_2X8; + break; + } + break; } @@ -1668,11 +2217,13 @@ int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) vfe->id = 0; vfe->reg_update = 0; - for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) { + for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { vfe->line[i].video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; vfe->line[i].video_out.camss = camss; vfe->line[i].id = i; + init_completion(&vfe->line[i].output.sof); + init_completion(&vfe->line[i].output.reg_update); } init_completion(&vfe->reset_complete); @@ -1810,8 +2361,13 @@ int msm_vfe_register_entities(struct vfe_device *vfe, v4l2_subdev_init(sd, &vfe_v4l2_ops); sd->internal_ops = &vfe_v4l2_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", - MSM_VFE_NAME, vfe->id, "rdi", i); + if (i == VFE_LINE_PIX) + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s", + MSM_VFE_NAME, vfe->id, "pix"); + else + snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s%d", + MSM_VFE_NAME, vfe->id, "rdi", i); + v4l2_set_subdevdata(sd, &vfe->line[i]); ret = vfe_init_formats(sd, NULL); @@ -1841,7 +2397,8 @@ int msm_vfe_register_entities(struct vfe_device *vfe, video_out->ops = &camss_vfe_video_ops; snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d", MSM_VFE_NAME, vfe->id, "video", i); - ret = msm_video_register(video_out, v4l2_dev, name); + ret = msm_video_register(video_out, v4l2_dev, name, + i == VFE_LINE_PIX ? 1 : 0); if (ret < 0) { dev_err(dev, "Failed to register video node: %d\n", ret); diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index 6d2fc57d3c40..b0598e46c457 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -30,8 +30,9 @@ #define MSM_VFE_PAD_SRC 1 #define MSM_VFE_PADS_NUM 2 -#define MSM_VFE_LINE_NUM 3 +#define MSM_VFE_LINE_NUM 4 #define MSM_VFE_IMAGE_MASTERS_NUM 7 +#define MSM_VFE_COMPOSITE_IRQ_NUM 4 #define MSM_VFE_VFE0_UB_SIZE 1023 #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3) @@ -51,11 +52,13 @@ enum vfe_line_id { VFE_LINE_NONE = -1, VFE_LINE_RDI0 = 0, VFE_LINE_RDI1 = 1, - VFE_LINE_RDI2 = 2 + VFE_LINE_RDI2 = 2, + VFE_LINE_PIX = 3 }; struct vfe_output { - u8 wm_idx; + u8 wm_num; + u8 wm_idx[3]; int active_buf; struct camss_buffer *buf[2]; @@ -66,6 +69,10 @@ struct vfe_output { enum vfe_output_state state; unsigned int sequence; + int wait_sof; + int wait_reg_update; + struct completion sof; + struct completion reg_update; }; struct vfe_line { diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c index 2e3f0128e4f1..8a45314c42c1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-video.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c @@ -27,72 +27,155 @@ #include "camss-video.h" #include "camss.h" +struct fract { + u8 numerator; + u8 denominator; +}; + /* * struct camss_format_info - ISP media bus format information * @code: V4L2 media bus format code * @pixelformat: V4L2 pixel format FCC identifier - * @bpp: Bits per pixel when stored in memory + * @planes: Number of planes + * @hsub: Horizontal subsampling (for each plane) + * @vsub: Vertical subsampling (for each plane) + * @bpp: Bits per pixel when stored in memory (for each plane) */ -static const struct camss_format_info { +struct camss_format_info { u32 code; u32 pixelformat; - unsigned int bpp; -} formats[] = { - { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 16 }, - { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 16 }, - { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 16 }, - { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 16 }, - { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 8 }, - { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 8 }, - { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 8 }, - { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 8 }, - { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 10 }, - { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 10 }, - { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 10 }, - { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 10 }, - { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 12 }, - { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 12 }, - { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 12 }, - { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 12 } + u8 planes; + struct fract hsub[3]; + struct fract vsub[3]; + unsigned int bpp[3]; +}; + +static const struct camss_format_info formats_rdi[] = { + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_UYVY, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_VYUY, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_YVYU, 1, + { { 1, 1 } }, { { 1, 1 } }, { 16 } }, + { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1, + { { 1, 1 } }, { { 1, 1 } }, { 8 } }, + { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 10 } }, + { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, + { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1, + { { 1, 1 } }, { { 1, 1 } }, { 12 } }, +}; + +static const struct camss_format_info formats_pix[] = { + { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1, + { { 1, 1 } }, { { 2, 3 } }, { 8 } }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV16, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV16, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV16, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV16, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_NV61, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_YVYU8_2X8, V4L2_PIX_FMT_NV61, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_PIX_FMT_NV61, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, + { MEDIA_BUS_FMT_VYUY8_2X8, V4L2_PIX_FMT_NV61, 1, + { { 1, 1 } }, { { 1, 2 } }, { 8 } }, }; /* ----------------------------------------------------------------------------- * Helper functions */ +static int video_find_format(u32 code, u32 pixelformat, + const struct camss_format_info *formats, + unsigned int nformats) +{ + int i; + + for (i = 0; i < nformats; i++) { + if (formats[i].code == code && + formats[i].pixelformat == pixelformat) + return i; + } + + for (i = 0; i < nformats; i++) + if (formats[i].code == code) + return i; + + WARN_ON(1); + + return -EINVAL; +} + /* * video_mbus_to_pix_mp - Convert v4l2_mbus_framefmt to v4l2_pix_format_mplane * @mbus: v4l2_mbus_framefmt format (input) * @pix: v4l2_pix_format_mplane format (output) + * @f: a pointer to formats array element to be used for the conversion * * Fill the output pix structure with information from the input mbus format. * * Return 0 on success or a negative error code otherwise */ -static unsigned int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus, - struct v4l2_pix_format_mplane *pix) +static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus, + struct v4l2_pix_format_mplane *pix, + const struct camss_format_info *f) { unsigned int i; u32 bytesperline; memset(pix, 0, sizeof(*pix)); v4l2_fill_pix_format_mplane(pix, mbus); - - for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (formats[i].code == mbus->code) - break; + pix->pixelformat = f->pixelformat; + pix->num_planes = f->planes; + for (i = 0; i < pix->num_planes; i++) { + bytesperline = pix->width / f->hsub[i].numerator * + f->hsub[i].denominator * f->bpp[i] / 8; + bytesperline = ALIGN(bytesperline, 8); + pix->plane_fmt[i].bytesperline = bytesperline; + pix->plane_fmt[i].sizeimage = pix->height / + f->vsub[i].numerator * f->vsub[i].denominator * + bytesperline; } - if (WARN_ON(i == ARRAY_SIZE(formats))) - return -EINVAL; - - pix->pixelformat = formats[i].pixelformat; - pix->num_planes = 1; - bytesperline = pix->width * formats[i].bpp / 8; - bytesperline = ALIGN(bytesperline, 8); - pix->plane_fmt[0].bytesperline = bytesperline; - pix->plane_fmt[0].sizeimage = bytesperline * pix->height; - return 0; } @@ -131,8 +214,16 @@ static int video_get_subdev_format(struct camss_video *video, if (ret) return ret; + ret = video_find_format(fmt.format.code, + format->fmt.pix_mp.pixelformat, + video->formats, video->nformats); + if (ret < 0) + return ret; + format->type = video->type; - return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp); + + return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp, + &video->formats[ret]); } /* ----------------------------------------------------------------------------- @@ -144,44 +235,73 @@ static int video_queue_setup(struct vb2_queue *q, unsigned int sizes[], struct device *alloc_devs[]) { struct camss_video *video = vb2_get_drv_priv(q); + const struct v4l2_pix_format_mplane *format = + &video->active_fmt.fmt.pix_mp; + unsigned int i; if (*num_planes) { - if (*num_planes != 1) + if (*num_planes != format->num_planes) return -EINVAL; - if (sizes[0] < video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage) - return -EINVAL; + for (i = 0; i < *num_planes; i++) + if (sizes[i] < format->plane_fmt[i].sizeimage) + return -EINVAL; return 0; } - *num_planes = 1; + *num_planes = format->num_planes; - sizes[0] = video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + for (i = 0; i < *num_planes; i++) + sizes[i] = format->plane_fmt[i].sizeimage; return 0; } -static int video_buf_prepare(struct vb2_buffer *vb) +static int video_buf_init(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue); struct camss_buffer *buffer = container_of(vbuf, struct camss_buffer, vb); + const struct v4l2_pix_format_mplane *format = + &video->active_fmt.fmt.pix_mp; struct sg_table *sgt; + unsigned int i; - if (video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage > - vb2_plane_size(vb, 0)) - return -EINVAL; + for (i = 0; i < format->num_planes; i++) { + sgt = vb2_dma_sg_plane_desc(vb, i); + if (!sgt) + return -EFAULT; - vb2_set_plane_payload(vb, 0, - video->active_fmt.fmt.pix_mp.plane_fmt[0].sizeimage); + buffer->addr[i] = sg_dma_address(sgt->sgl); + } + + if (format->pixelformat == V4L2_PIX_FMT_NV12 || + format->pixelformat == V4L2_PIX_FMT_NV21 || + format->pixelformat == V4L2_PIX_FMT_NV16 || + format->pixelformat == V4L2_PIX_FMT_NV61) + buffer->addr[1] = buffer->addr[0] + + format->plane_fmt[0].bytesperline * + format->height; + + return 0; +} + +static int video_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct camss_video *video = vb2_get_drv_priv(vb->vb2_queue); + const struct v4l2_pix_format_mplane *format = + &video->active_fmt.fmt.pix_mp; + unsigned int i; - sgt = vb2_dma_sg_plane_desc(vb, 0); - if (!sgt) - return -EFAULT; + for (i = 0; i < format->num_planes; i++) { + if (format->plane_fmt[i].sizeimage > vb2_plane_size(vb, i)) + return -EINVAL; - buffer->addr = sg_dma_address(sgt->sgl); + vb2_set_plane_payload(vb, i, format->plane_fmt[i].sizeimage); + } vbuf->field = V4L2_FIELD_NONE; @@ -203,8 +323,10 @@ static int video_check_format(struct camss_video *video) struct v4l2_pix_format_mplane *pix = &video->active_fmt.fmt.pix_mp; struct v4l2_format format; struct v4l2_pix_format_mplane *sd_pix = &format.fmt.pix_mp; + unsigned int i; int ret; + sd_pix->pixelformat = pix->pixelformat; ret = video_get_subdev_format(video, &format); if (ret < 0) return ret; @@ -213,12 +335,16 @@ static int video_check_format(struct camss_video *video) pix->height != sd_pix->height || pix->width != sd_pix->width || pix->num_planes != sd_pix->num_planes || - pix->num_planes != 1 || - pix->plane_fmt[0].bytesperline != sd_pix->plane_fmt[0].bytesperline || - pix->plane_fmt[0].sizeimage != sd_pix->plane_fmt[0].sizeimage || pix->field != format.fmt.pix_mp.field) return -EPIPE; + for (i = 0; i < pix->num_planes; i++) + if (pix->plane_fmt[i].bytesperline != + sd_pix->plane_fmt[i].bytesperline || + pix->plane_fmt[i].sizeimage != + sd_pix->plane_fmt[i].sizeimage) + return -EINVAL; + return 0; } @@ -274,7 +400,6 @@ static void video_stop_streaming(struct vb2_queue *q) struct media_entity *entity; struct media_pad *pad; struct v4l2_subdev *subdev; - struct v4l2_subdev *subdev_vfe = NULL; entity = &vdev->entity; while (1) { @@ -289,14 +414,7 @@ static void video_stop_streaming(struct vb2_queue *q) entity = pad->entity; subdev = media_entity_to_v4l2_subdev(entity); - if (strstr(subdev->name, "vfe")) { - subdev_vfe = subdev; - } else if (strstr(subdev->name, "ispif")) { - v4l2_subdev_call(subdev, video, s_stream, 0); - v4l2_subdev_call(subdev_vfe, video, s_stream, 0); - } else { - v4l2_subdev_call(subdev, video, s_stream, 0); - } + v4l2_subdev_call(subdev, video, s_stream, 0); } media_pipeline_stop(&vdev->entity); @@ -308,6 +426,7 @@ static const struct vb2_ops msm_video_vb2_q_ops = { .queue_setup = video_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, + .buf_init = video_buf_init, .buf_prepare = video_buf_prepare, .buf_queue = video_buf_queue, .start_streaming = video_start_streaming, @@ -334,14 +453,34 @@ static int video_querycap(struct file *file, void *fh, static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct camss_video *video = video_drvdata(file); + int i, j, k; if (f->type != video->type) return -EINVAL; - if (f->index >= ARRAY_SIZE(formats)) + if (f->index >= video->nformats) + return -EINVAL; + + /* find index "i" of "k"th unique pixelformat in formats array */ + k = -1; + for (i = 0; i < video->nformats; i++) { + for (j = 0; j < i; j++) { + if (video->formats[i].pixelformat == + video->formats[j].pixelformat) + break; + } + + if (j == i) + k++; + + if (k == f->index) + break; + } + + if (k < f->index) return -EINVAL; - f->pixelformat = formats[f->index].pixelformat; + f->pixelformat = video->formats[i].pixelformat; return 0; } @@ -358,32 +497,38 @@ static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f) static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pix_mp; + const struct camss_format_info *fi; u32 width, height; u32 bpl; - int j; + int i, j; pix_mp = &f->fmt.pix_mp; - for (j = 0; j < ARRAY_SIZE(formats); j++) - if (pix_mp->pixelformat == formats[j].pixelformat) + for (j = 0; j < video->nformats; j++) + if (pix_mp->pixelformat == video->formats[j].pixelformat) break; - if (j == ARRAY_SIZE(formats)) + if (j == video->nformats) j = 0; /* default format */ + fi = &video->formats[j]; width = pix_mp->width; height = pix_mp->height; memset(pix_mp, 0, sizeof(*pix_mp)); - pix_mp->pixelformat = formats[j].pixelformat; + pix_mp->pixelformat = fi->pixelformat; pix_mp->width = clamp_t(u32, width, 1, 8191); pix_mp->height = clamp_t(u32, height, 1, 8191); - pix_mp->num_planes = 1; - bpl = pix_mp->width * formats[j].bpp / 8; - bpl = ALIGN(bpl, 8); - pix_mp->plane_fmt[0].bytesperline = bpl; - pix_mp->plane_fmt[0].sizeimage = bpl * pix_mp->height; + pix_mp->num_planes = fi->planes; + for (i = 0; i < pix_mp->num_planes; i++) { + bpl = pix_mp->width / fi->hsub[i].numerator * + fi->hsub[i].denominator * fi->bpp[i] / 8; + bpl = ALIGN(bpl, 8); + pix_mp->plane_fmt[i].bytesperline = bpl; + pix_mp->plane_fmt[i].sizeimage = pix_mp->height / + fi->vsub[i].numerator * fi->vsub[i].denominator * bpl; + } pix_mp->field = V4L2_FIELD_NONE; pix_mp->colorspace = V4L2_COLORSPACE_SRGB; @@ -564,7 +709,7 @@ static int msm_video_init_format(struct camss_video *video) .fmt.pix_mp = { .width = 1920, .height = 1080, - .pixelformat = formats[0].pixelformat, + .pixelformat = video->formats[0].pixelformat, }, }; @@ -590,7 +735,7 @@ static int msm_video_init_format(struct camss_video *video) */ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, - const char *name) + const char *name, int is_pix) { struct media_pad *pad = &video->pad; struct video_device *vdev; @@ -627,6 +772,13 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, mutex_init(&video->lock); + video->formats = formats_rdi; + video->nformats = ARRAY_SIZE(formats_rdi); + if (is_pix) { + video->formats = formats_pix; + video->nformats = ARRAY_SIZE(formats_pix); + } + ret = msm_video_init_format(video); if (ret < 0) { dev_err(v4l2_dev->dev, "Failed to init format: %d\n", ret); diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.h b/drivers/media/platform/qcom/camss-8x16/camss-video.h index 0d2cef3d224a..e3b459fb4754 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-video.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.h @@ -29,7 +29,7 @@ struct camss_buffer { struct vb2_v4l2_buffer vb; - dma_addr_t addr; + dma_addr_t addr[3]; struct list_head queue; }; @@ -41,6 +41,8 @@ struct camss_video_ops { enum vb2_buffer_state state); }; +struct camss_format_info; + struct camss_video { struct camss *camss; struct vb2_queue vb2_q; @@ -52,12 +54,14 @@ struct camss_video { const struct camss_video_ops *ops; struct mutex lock; struct mutex q_lock; + const struct camss_format_info *formats; + unsigned int nformats; }; void msm_video_stop_streaming(struct camss_video *video); int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, - const char *name); + const char *name, int is_pix); void msm_video_unregister(struct camss_video *video); -- cgit v1.2.3 From 7b4aff6f810421c44aac57f4e58898d307720e12 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:11 -0400 Subject: media: camss: vfe: Support for frame padding Add support for horizontal and vertical frame padding. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 85 +++++++++++++++++----- .../media/platform/qcom/camss-8x16/camss-video.c | 53 ++++++++++---- .../media/platform/qcom/camss-8x16/camss-video.h | 2 + 3 files changed, 109 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 44605e0eb355..de9f1ae871af 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -300,21 +300,75 @@ static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_FRM_BASED_SHIFT); } +#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) + +static int vfe_word_per_line(uint32_t format, uint32_t pixel_per_line) +{ + int val = 0; + + switch (format) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + val = CALC_WORD(pixel_per_line, 1, 8); + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + val = CALC_WORD(pixel_per_line, 2, 8); + break; + } + + return val; +} + +static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, + u16 *width, u16 *height, u16 *bytesperline) +{ + switch (pix->pixelformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[0].bytesperline; + if (plane == 1) + *height /= 2; + break; + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + *width = pix->width; + *height = pix->height; + *bytesperline = pix->plane_fmt[0].bytesperline; + break; + } +} + static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, - u16 width, u16 height, u32 enable) + struct v4l2_pix_format_mplane *pix, + u8 plane, u32 enable) { u32 reg; if (enable) { + u16 width = 0, height = 0, bytesperline = 0, wpl; + + vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline); + + wpl = vfe_word_per_line(pix->pixelformat, width); + reg = height - 1; - reg |= (width / 16 - 1) << 16; + reg |= ((wpl + 1) / 2 - 1) << 16; writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); + wpl = vfe_word_per_line(pix->pixelformat, bytesperline); + reg = 0x3; reg |= (height - 1) << 4; - reg |= (width / 8) << 16; + reg |= wpl << 16; writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); @@ -1231,25 +1285,14 @@ static int vfe_enable_output(struct vfe_line *line) } else { ub_size /= output->wm_num; for (i = 0; i < output->wm_num; i++) { - u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; - vfe_set_cgc_override(vfe, output->wm_idx[i], 1); vfe_wm_set_subsample(vfe, output->wm_idx[i]); vfe_wm_set_ub_cfg(vfe, output->wm_idx[i], (ub_size + 1) * output->wm_idx[i], ub_size); - if ((i == 1) && (p == V4L2_PIX_FMT_NV12 || - p == V4L2_PIX_FMT_NV21)) - vfe_wm_line_based(vfe, output->wm_idx[i], - line->fmt[MSM_VFE_PAD_SRC].width, - line->fmt[MSM_VFE_PAD_SRC].height / 2, - 1); - else - vfe_wm_line_based(vfe, output->wm_idx[i], - line->fmt[MSM_VFE_PAD_SRC].width, - line->fmt[MSM_VFE_PAD_SRC].height, - 1); - + vfe_wm_line_based(vfe, output->wm_idx[i], + &line->video_out.active_fmt.fmt.pix_mp, + i, 1); vfe_wm_enable(vfe, output->wm_idx[i], 1); vfe_bus_reload_wm(vfe, output->wm_idx[i]); } @@ -1311,7 +1354,7 @@ static int vfe_disable_output(struct vfe_line *line) spin_unlock_irqrestore(&vfe->output_lock, flags); } else { for (i = 0; i < output->wm_num; i++) { - vfe_wm_line_based(vfe, output->wm_idx[i], 0, 0, 0); + vfe_wm_line_based(vfe, output->wm_idx[i], NULL, i, 0); vfe_set_cgc_override(vfe, output->wm_idx[i], 0); } @@ -2395,6 +2438,12 @@ int msm_vfe_register_entities(struct vfe_device *vfe, } video_out->ops = &camss_vfe_video_ops; + video_out->bpl_alignment = 8; + video_out->line_based = 0; + if (i == VFE_LINE_PIX) { + video_out->bpl_alignment = 16; + video_out->line_based = 1; + } snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d", MSM_VFE_NAME, vfe->id, "video", i); ret = msm_video_register(video_out, v4l2_dev, name, diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c index 8a45314c42c1..cf4219e871bd 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-video.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c @@ -150,6 +150,7 @@ static int video_find_format(u32 code, u32 pixelformat, * @mbus: v4l2_mbus_framefmt format (input) * @pix: v4l2_pix_format_mplane format (output) * @f: a pointer to formats array element to be used for the conversion + * @alignment: bytesperline alignment value * * Fill the output pix structure with information from the input mbus format. * @@ -157,7 +158,8 @@ static int video_find_format(u32 code, u32 pixelformat, */ static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus, struct v4l2_pix_format_mplane *pix, - const struct camss_format_info *f) + const struct camss_format_info *f, + unsigned int alignment) { unsigned int i; u32 bytesperline; @@ -169,7 +171,7 @@ static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus, for (i = 0; i < pix->num_planes; i++) { bytesperline = pix->width / f->hsub[i].numerator * f->hsub[i].denominator * f->bpp[i] / 8; - bytesperline = ALIGN(bytesperline, 8); + bytesperline = ALIGN(bytesperline, alignment); pix->plane_fmt[i].bytesperline = bytesperline; pix->plane_fmt[i].sizeimage = pix->height / f->vsub[i].numerator * f->vsub[i].denominator * @@ -223,7 +225,7 @@ static int video_get_subdev_format(struct camss_video *video, format->type = video->type; return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp, - &video->formats[ret]); + &video->formats[ret], video->bpl_alignment); } /* ----------------------------------------------------------------------------- @@ -323,7 +325,6 @@ static int video_check_format(struct camss_video *video) struct v4l2_pix_format_mplane *pix = &video->active_fmt.fmt.pix_mp; struct v4l2_format format; struct v4l2_pix_format_mplane *sd_pix = &format.fmt.pix_mp; - unsigned int i; int ret; sd_pix->pixelformat = pix->pixelformat; @@ -338,13 +339,6 @@ static int video_check_format(struct camss_video *video) pix->field != format.fmt.pix_mp.field) return -EPIPE; - for (i = 0; i < pix->num_planes; i++) - if (pix->plane_fmt[i].bytesperline != - sd_pix->plane_fmt[i].bytesperline || - pix->plane_fmt[i].sizeimage != - sd_pix->plane_fmt[i].sizeimage) - return -EINVAL; - return 0; } @@ -498,12 +492,25 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pix_mp; const struct camss_format_info *fi; + struct v4l2_plane_pix_format *p; + u32 bytesperline[3] = { 0 }; + u32 sizeimage[3] = { 0 }; u32 width, height; - u32 bpl; + u32 bpl, lines; int i, j; pix_mp = &f->fmt.pix_mp; + if (video->line_based) + for (i = 0; i < pix_mp->num_planes && i < 3; i++) { + p = &pix_mp->plane_fmt[i]; + bytesperline[i] = clamp_t(u32, p->bytesperline, + 1, 65528); + sizeimage[i] = clamp_t(u32, p->sizeimage, + bytesperline[i], + bytesperline[i] * 4096); + } + for (j = 0; j < video->nformats; j++) if (pix_mp->pixelformat == video->formats[j].pixelformat) break; @@ -524,7 +531,7 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f) for (i = 0; i < pix_mp->num_planes; i++) { bpl = pix_mp->width / fi->hsub[i].numerator * fi->hsub[i].denominator * fi->bpp[i] / 8; - bpl = ALIGN(bpl, 8); + bpl = ALIGN(bpl, video->bpl_alignment); pix_mp->plane_fmt[i].bytesperline = bpl; pix_mp->plane_fmt[i].sizeimage = pix_mp->height / fi->vsub[i].numerator * fi->vsub[i].denominator * bpl; @@ -538,6 +545,26 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f) pix_mp->colorspace, pix_mp->ycbcr_enc); pix_mp->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace); + if (video->line_based) + for (i = 0; i < pix_mp->num_planes; i++) { + p = &pix_mp->plane_fmt[i]; + p->bytesperline = clamp_t(u32, p->bytesperline, + 1, 65528); + p->sizeimage = clamp_t(u32, p->sizeimage, + p->bytesperline, + p->bytesperline * 4096); + lines = p->sizeimage / p->bytesperline; + + if (p->bytesperline < bytesperline[i]) + p->bytesperline = ALIGN(bytesperline[i], 8); + + if (p->sizeimage < p->bytesperline * lines) + p->sizeimage = p->bytesperline * lines; + + if (p->sizeimage < sizeimage[i]) + p->sizeimage = sizeimage[i]; + } + return 0; } diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.h b/drivers/media/platform/qcom/camss-8x16/camss-video.h index e3b459fb4754..38bd1f2eec54 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-video.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.h @@ -54,6 +54,8 @@ struct camss_video { const struct camss_video_ops *ops; struct mutex lock; struct mutex q_lock; + unsigned int bpl_alignment; + unsigned int line_based; const struct camss_format_info *formats; unsigned int nformats; }; -- cgit v1.2.3 From 810b659880e016e4fcf09f2ef4db8528f25cfe48 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:12 -0400 Subject: media: camss: vfe: Add interface for scaling Add compose selection ioctls to handle scaling configuration. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 184 ++++++++++++++++++++- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 1 + 2 files changed, 183 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index de9f1ae871af..c6b230b76c31 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -232,6 +232,8 @@ #define CAMIF_TIMEOUT_SLEEP_US 1000 #define CAMIF_TIMEOUT_ALL_US 1000000 +#define SCALER_RATIO_MAX 16 + static const u32 vfe_formats[] = { MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_VYUY8_2X8, @@ -1938,6 +1940,25 @@ __vfe_get_format(struct vfe_line *line, return &line->fmt[pad]; } +/* + * __vfe_get_compose - Get pointer to compose selection structure + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE compose rectangle structure + */ +static struct v4l2_rect * +__vfe_get_compose(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_compose(&line->subdev, cfg, + MSM_VFE_PAD_SINK); + + return &line->compose; +} /* * vfe_try_format - Handle try format by pad subdev method @@ -1984,7 +2005,14 @@ static void vfe_try_format(struct vfe_line *line, *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); - if (line->id == VFE_LINE_PIX) + if (line->id == VFE_LINE_PIX) { + struct v4l2_rect *rect; + + rect = __vfe_get_compose(line, cfg, which); + + fmt->width = rect->width; + fmt->height = rect->height; + switch (fmt->code) { case MEDIA_BUS_FMT_YUYV8_2X8: if (code == MEDIA_BUS_FMT_YUYV8_1_5X8) @@ -2012,6 +2040,7 @@ static void vfe_try_format(struct vfe_line *line, fmt->code = MEDIA_BUS_FMT_VYUY8_2X8; break; } + } break; } @@ -2019,6 +2048,45 @@ static void vfe_try_format(struct vfe_line *line, fmt->colorspace = V4L2_COLORSPACE_SRGB; } +/* + * vfe_try_compose - Handle try compose selection by pad subdev method + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @rect: pointer to v4l2 rect structure + * @which: wanted subdev format + */ +static void vfe_try_compose(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_rect *rect, + enum v4l2_subdev_format_whence which) +{ + struct v4l2_mbus_framefmt *fmt; + + fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); + + if (rect->width > fmt->width) + rect->width = fmt->width; + + if (rect->height > fmt->height) + rect->height = fmt->height; + + if (fmt->width > rect->width * SCALER_RATIO_MAX) + rect->width = (fmt->width + SCALER_RATIO_MAX - 1) / + SCALER_RATIO_MAX; + + rect->width &= ~0x1; + + if (fmt->height > rect->height * SCALER_RATIO_MAX) + rect->height = (fmt->height + SCALER_RATIO_MAX - 1) / + SCALER_RATIO_MAX; + + if (rect->width < 16) + rect->width = 16; + + if (rect->height < 4) + rect->height = 4; +} + /* * vfe_enum_mbus_code - Handle pixel format enumeration * @sd: VFE V4L2 subdevice @@ -2114,6 +2182,10 @@ static int vfe_get_format(struct v4l2_subdev *sd, return 0; } +static int vfe_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel); + /* * vfe_set_format - Handle set format by pads subdev method * @sd: VFE V4L2 subdevice @@ -2136,19 +2208,125 @@ static int vfe_set_format(struct v4l2_subdev *sd, vfe_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; - /* Propagate the format from sink to source */ if (fmt->pad == MSM_VFE_PAD_SINK) { + struct v4l2_subdev_selection sel = { 0 }; + int ret; + + /* Propagate the format from sink to source */ format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SRC, fmt->which); *format = fmt->format; vfe_try_format(line, cfg, MSM_VFE_PAD_SRC, format, fmt->which); + + if (line->id != VFE_LINE_PIX) + return 0; + + /* Reset sink pad compose selection */ + sel.which = fmt->which; + sel.pad = MSM_VFE_PAD_SINK; + sel.target = V4L2_SEL_TGT_COMPOSE; + sel.r.width = fmt->format.width; + sel.r.height = fmt->format.height; + ret = vfe_set_selection(sd, cfg, &sel); + if (ret < 0) + return ret; + } + + return 0; +} + +/* + * vfe_get_selection - Handle get selection by pads subdev method + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @sel: pointer to v4l2 subdev selection structure + * + * Return -EINVAL or zero on success + */ +static int vfe_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_subdev_format fmt = { 0 }; + struct v4l2_rect *compose; + int ret; + + if (line->id != VFE_LINE_PIX || sel->pad != MSM_VFE_PAD_SINK) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + fmt.pad = sel->pad; + fmt.which = sel->which; + ret = vfe_get_format(sd, cfg, &fmt); + if (ret < 0) + return ret; + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = fmt.format.width; + sel->r.height = fmt.format.height; + break; + case V4L2_SEL_TGT_COMPOSE: + compose = __vfe_get_compose(line, cfg, sel->which); + if (compose == NULL) + return -EINVAL; + + sel->r = *compose; + break; + default: + return -EINVAL; } return 0; } +/* + * vfe_set_selection - Handle set selection by pads subdev method + * @sd: VFE V4L2 subdevice + * @cfg: V4L2 subdev pad configuration + * @sel: pointer to v4l2 subdev selection structure + * + * Return -EINVAL or zero on success + */ +int vfe_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct vfe_line *line = v4l2_get_subdevdata(sd); + struct v4l2_rect *compose; + struct v4l2_subdev_format fmt = { 0 }; + int ret; + + if (line->id != VFE_LINE_PIX || sel->pad != MSM_VFE_PAD_SINK) + return -EINVAL; + + if (sel->target != V4L2_SEL_TGT_COMPOSE) + return -EINVAL; + + compose = __vfe_get_compose(line, cfg, sel->which); + if (compose == NULL) + return -EINVAL; + + vfe_try_compose(line, cfg, &sel->r, sel->which); + *compose = sel->r; + + /* Reset source pad format width and height */ + fmt.which = sel->which; + fmt.pad = MSM_VFE_PAD_SRC; + ret = vfe_get_format(sd, cfg, &fmt); + if (ret < 0) + return ret; + + fmt.format.width = compose->width; + fmt.format.height = compose->height; + ret = vfe_set_format(sd, cfg, &fmt); + + return ret; +} + /* * vfe_init_formats - Initialize formats on all pads * @sd: VFE V4L2 subdevice @@ -2342,6 +2520,8 @@ static const struct v4l2_subdev_pad_ops vfe_pad_ops = { .enum_frame_size = vfe_enum_frame_size, .get_fmt = vfe_get_format, .set_fmt = vfe_set_format, + .get_selection = vfe_get_selection, + .set_selection = vfe_set_selection, }; static const struct v4l2_subdev_ops vfe_v4l2_ops = { diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index b0598e46c457..6518c7ab99bb 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -80,6 +80,7 @@ struct vfe_line { struct v4l2_subdev subdev; struct media_pad pads[MSM_VFE_PADS_NUM]; struct v4l2_mbus_framefmt fmt[MSM_VFE_PADS_NUM]; + struct v4l2_rect compose; struct camss_video video_out; struct vfe_output output; }; -- cgit v1.2.3 From cce91b14692cb4378fcb6fc32607f6219e1901b3 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:13 -0400 Subject: media: camss: vfe: Configure scaler module in VFE Add scaler module configuration support to be able to apply scaling. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 59 +++++++++++++++++----- 1 file changed, 46 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index c6b230b76c31..cc1fc6805f0e 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -198,13 +198,16 @@ #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9 +#define VFE_0_SCALE_ENC_Y_CFG 0x75c +#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x760 +#define VFE_0_SCALE_ENC_Y_H_PHASE 0x764 +#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x76c +#define VFE_0_SCALE_ENC_Y_V_PHASE 0x770 #define VFE_0_SCALE_ENC_CBCR_CFG 0x778 #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x77c #define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x780 -#define VFE_0_SCALE_ENC_CBCR_H_PAD 0x78c #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x790 #define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x794 -#define VFE_0_SCALE_ENC_CBCR_V_PAD 0x7a0 #define VFE_0_CLAMP_ENC_MAX_CFG 0x874 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) @@ -670,6 +673,20 @@ static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); } +static inline u8 vfe_calc_interp_reso(u16 input, u16 output) +{ + if (input / output >= 16) + return 0; + + if (input / output >= 8) + return 1; + + if (input / output >= 4) + return 2; + + return 3; +} + static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) { u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; @@ -678,35 +695,51 @@ static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) u8 interp_reso; u32 phase_mult; + writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG); + + input = line->fmt[MSM_VFE_PAD_SINK].width; + output = line->compose.width; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (13 + interp_reso)) / output; + reg = (interp_reso << 20) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE); + + input = line->fmt[MSM_VFE_PAD_SINK].height; + output = line->compose.height; + reg = (output << 16) | input; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE); + + interp_reso = vfe_calc_interp_reso(input, output); + phase_mult = input * (1 << (13 + interp_reso)) / output; + reg = (interp_reso << 20) | phase_mult; + writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE); + writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); input = line->fmt[MSM_VFE_PAD_SINK].width; - output = line->fmt[MSM_VFE_PAD_SRC].width / 2; + output = line->compose.width / 2; reg = (output << 16) | input; writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); - interp_reso = 3; + interp_reso = vfe_calc_interp_reso(input, output); phase_mult = input * (1 << (13 + interp_reso)) / output; reg = (interp_reso << 20) | phase_mult; writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); - reg = input; - writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PAD); - input = line->fmt[MSM_VFE_PAD_SINK].height; - output = line->fmt[MSM_VFE_PAD_SRC].height; + output = line->compose.height; if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) - output = line->fmt[MSM_VFE_PAD_SRC].height / 2; + output = line->compose.height / 2; reg = (output << 16) | input; writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); - interp_reso = 3; + interp_reso = vfe_calc_interp_reso(input, output); phase_mult = input * (1 << (13 + interp_reso)) / output; reg = (interp_reso << 20) | phase_mult; writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); - - reg = input; - writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PAD); } static void vfe_set_clamp_cfg(struct vfe_device *vfe) -- cgit v1.2.3 From 780bf2fe36e028c1f2884b18c327bf5adc6f9e08 Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:14 -0400 Subject: media: camss: vfe: Add interface for cropping Extend selection ioctls to handle cropping configuration. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 191 ++++++++++++++++----- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 1 + 2 files changed, 150 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index cc1fc6805f0e..680e059a952c 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -1993,6 +1993,26 @@ __vfe_get_compose(struct vfe_line *line, return &line->compose; } +/* + * __vfe_get_crop - Get pointer to crop selection structure + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @which: TRY or ACTIVE format + * + * Return pointer to TRY or ACTIVE crop rectangle structure + */ +static struct v4l2_rect * +__vfe_get_crop(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_crop(&line->subdev, cfg, + MSM_VFE_PAD_SRC); + + return &line->crop; +} + /* * vfe_try_format - Handle try format by pad subdev method * @line: VFE line @@ -2041,7 +2061,7 @@ static void vfe_try_format(struct vfe_line *line, if (line->id == VFE_LINE_PIX) { struct v4l2_rect *rect; - rect = __vfe_get_compose(line, cfg, which); + rect = __vfe_get_crop(line, cfg, which); fmt->width = rect->width; fmt->height = rect->height; @@ -2120,6 +2140,49 @@ static void vfe_try_compose(struct vfe_line *line, rect->height = 4; } +/* + * vfe_try_crop - Handle try crop selection by pad subdev method + * @line: VFE line + * @cfg: V4L2 subdev pad configuration + * @rect: pointer to v4l2 rect structure + * @which: wanted subdev format + */ +static void vfe_try_crop(struct vfe_line *line, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_rect *rect, + enum v4l2_subdev_format_whence which) +{ + struct v4l2_rect *compose; + + compose = __vfe_get_compose(line, cfg, which); + + if (rect->width > compose->width) + rect->width = compose->width; + + if (rect->width + rect->left > compose->width) + rect->left = compose->width - rect->width; + + if (rect->height > compose->height) + rect->height = compose->height; + + if (rect->height + rect->top > compose->height) + rect->top = compose->height - rect->height; + + /* wm in line based mode writes multiple of 16 horizontally */ + rect->left += (rect->width & 0xf) >> 1; + rect->width &= ~0xf; + + if (rect->width < 16) { + rect->left = 0; + rect->width = 16; + } + + if (rect->height < 4) { + rect->top = 0; + rect->height = 4; + } +} + /* * vfe_enum_mbus_code - Handle pixel format enumeration * @sd: VFE V4L2 subdevice @@ -2284,34 +2347,58 @@ static int vfe_get_selection(struct v4l2_subdev *sd, { struct vfe_line *line = v4l2_get_subdevdata(sd); struct v4l2_subdev_format fmt = { 0 }; - struct v4l2_rect *compose; + struct v4l2_rect *rect; int ret; - if (line->id != VFE_LINE_PIX || sel->pad != MSM_VFE_PAD_SINK) + if (line->id != VFE_LINE_PIX) return -EINVAL; - switch (sel->target) { - case V4L2_SEL_TGT_COMPOSE_BOUNDS: - fmt.pad = sel->pad; - fmt.which = sel->which; - ret = vfe_get_format(sd, cfg, &fmt); - if (ret < 0) - return ret; - sel->r.left = 0; - sel->r.top = 0; - sel->r.width = fmt.format.width; - sel->r.height = fmt.format.height; - break; - case V4L2_SEL_TGT_COMPOSE: - compose = __vfe_get_compose(line, cfg, sel->which); - if (compose == NULL) + if (sel->pad == MSM_VFE_PAD_SINK) + switch (sel->target) { + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + fmt.pad = sel->pad; + fmt.which = sel->which; + ret = vfe_get_format(sd, cfg, &fmt); + if (ret < 0) + return ret; + + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = fmt.format.width; + sel->r.height = fmt.format.height; + break; + case V4L2_SEL_TGT_COMPOSE: + rect = __vfe_get_compose(line, cfg, sel->which); + if (rect == NULL) + return -EINVAL; + + sel->r = *rect; + break; + default: return -EINVAL; + } + else if (sel->pad == MSM_VFE_PAD_SRC) + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + rect = __vfe_get_compose(line, cfg, sel->which); + if (rect == NULL) + return -EINVAL; - sel->r = *compose; - break; - default: - return -EINVAL; - } + sel->r.left = rect->left; + sel->r.top = rect->top; + sel->r.width = rect->width; + sel->r.height = rect->height; + break; + case V4L2_SEL_TGT_CROP: + rect = __vfe_get_crop(line, cfg, sel->which); + if (rect == NULL) + return -EINVAL; + + sel->r = *rect; + break; + default: + return -EINVAL; + } return 0; } @@ -2329,33 +2416,53 @@ int vfe_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_selection *sel) { struct vfe_line *line = v4l2_get_subdevdata(sd); - struct v4l2_rect *compose; - struct v4l2_subdev_format fmt = { 0 }; + struct v4l2_rect *rect; int ret; - if (line->id != VFE_LINE_PIX || sel->pad != MSM_VFE_PAD_SINK) + if (line->id != VFE_LINE_PIX) return -EINVAL; - if (sel->target != V4L2_SEL_TGT_COMPOSE) - return -EINVAL; + if (sel->target == V4L2_SEL_TGT_COMPOSE && + sel->pad == MSM_VFE_PAD_SINK) { + struct v4l2_subdev_selection crop = { 0 }; - compose = __vfe_get_compose(line, cfg, sel->which); - if (compose == NULL) - return -EINVAL; + rect = __vfe_get_compose(line, cfg, sel->which); + if (rect == NULL) + return -EINVAL; + + vfe_try_compose(line, cfg, &sel->r, sel->which); + *rect = sel->r; + + /* Reset source crop selection */ + crop.which = sel->which; + crop.pad = MSM_VFE_PAD_SRC; + crop.target = V4L2_SEL_TGT_CROP; + crop.r = *rect; + ret = vfe_set_selection(sd, cfg, &crop); + } else if (sel->target == V4L2_SEL_TGT_CROP && + sel->pad == MSM_VFE_PAD_SRC) { + struct v4l2_subdev_format fmt = { 0 }; + + rect = __vfe_get_crop(line, cfg, sel->which); + if (rect == NULL) + return -EINVAL; - vfe_try_compose(line, cfg, &sel->r, sel->which); - *compose = sel->r; + vfe_try_crop(line, cfg, &sel->r, sel->which); + *rect = sel->r; - /* Reset source pad format width and height */ - fmt.which = sel->which; - fmt.pad = MSM_VFE_PAD_SRC; - ret = vfe_get_format(sd, cfg, &fmt); - if (ret < 0) - return ret; + /* Reset source pad format width and height */ + fmt.which = sel->which; + fmt.pad = MSM_VFE_PAD_SRC; + ret = vfe_get_format(sd, cfg, &fmt); + if (ret < 0) + return ret; - fmt.format.width = compose->width; - fmt.format.height = compose->height; - ret = vfe_set_format(sd, cfg, &fmt); + fmt.format.width = rect->width; + fmt.format.height = rect->height; + ret = vfe_set_format(sd, cfg, &fmt); + } else { + ret = -EINVAL; + } return ret; } diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index 6518c7ab99bb..3651ece53caa 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -81,6 +81,7 @@ struct vfe_line { struct media_pad pads[MSM_VFE_PADS_NUM]; struct v4l2_mbus_framefmt fmt[MSM_VFE_PADS_NUM]; struct v4l2_rect compose; + struct v4l2_rect crop; struct camss_video video_out; struct vfe_output output; }; -- cgit v1.2.3 From 4cd0e35425c772c7e3c9a5df61688e2feade56fb Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:15 -0400 Subject: media: camss: vfe: Configure crop module in VFE Add crop module configuration support to be able to apply cropping. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 41 +++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 680e059a952c..c62a1ba5dc3b 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -57,6 +57,7 @@ #define VFE_0_MODULE_CFG_DEMUX (1 << 2) #define VFE_0_MODULE_CFG_CHROMA_UPSAMPLE (1 << 3) #define VFE_0_MODULE_CFG_SCALE_ENC (1 << 23) +#define VFE_0_MODULE_CFG_CROP_ENC (1 << 27) #define VFE_0_CORE_CFG 0x01c #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4 @@ -209,6 +210,11 @@ #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x790 #define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x794 +#define VFE_0_CROP_ENC_Y_WIDTH 0x854 +#define VFE_0_CROP_ENC_Y_HEIGHT 0x858 +#define VFE_0_CROP_ENC_CBCR_WIDTH 0x85c +#define VFE_0_CROP_ENC_CBCR_HEIGHT 0x860 + #define VFE_0_CLAMP_ENC_MAX_CFG 0x874 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) #define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8) @@ -742,6 +748,37 @@ static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); } +static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line) +{ + u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; + u32 reg; + u16 first, last; + + first = line->crop.left; + last = line->crop.left + line->crop.width - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH); + + first = line->crop.top; + last = line->crop.top + line->crop.height - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT); + + first = line->crop.left / 2; + last = line->crop.left / 2 + line->crop.width / 2 - 1; + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH); + + first = line->crop.top; + last = line->crop.top + line->crop.height - 1; + if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) { + first = line->crop.top / 2; + last = line->crop.top / 2 + line->crop.height / 2 - 1; + } + reg = (first << 16) | last; + writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT); +} + static void vfe_set_clamp_cfg(struct vfe_device *vfe) { u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 | @@ -863,7 +900,8 @@ static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) { u32 val = VFE_0_MODULE_CFG_DEMUX | VFE_0_MODULE_CFG_CHROMA_UPSAMPLE | - VFE_0_MODULE_CFG_SCALE_ENC; + VFE_0_MODULE_CFG_SCALE_ENC | + VFE_0_MODULE_CFG_CROP_ENC; if (enable) writel_relaxed(val, vfe->base + VFE_0_MODULE_CFG); @@ -1337,6 +1375,7 @@ static int vfe_enable_output(struct vfe_line *line) vfe_set_xbar_cfg(vfe, output, 1); vfe_set_demux_cfg(vfe, line); vfe_set_scale_cfg(vfe, line); + vfe_set_crop_cfg(vfe, line); vfe_set_clamp_cfg(vfe); vfe_set_camif_cmd(vfe, VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY); } -- cgit v1.2.3 From bbde31047434678f60820c7187ca7b7ed6e1809f Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Tue, 8 Aug 2017 09:30:17 -0400 Subject: media: camss: Use optimal clock frequency rates Use standard V4L2 control to get pixel clock rate from a sensor linked in the media controller pipeline. Then calculate clock rates on CSIPHY, CSID and VFE to use the lowest possible. If the currnet pixel clock rate of the sensor cannot be read then use the highest possible. This case covers also the CSID test generator usage. If VFE is already powered on by another pipeline, check that the current VFE clock rate is high enough for the new pipeline. If not return busy error code as VFE clock rate cannot be changed while VFE is running. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/qcom/camss-8x16/camss-csid.c | 139 ++++++++-- .../media/platform/qcom/camss-8x16/camss-csid.h | 2 +- .../media/platform/qcom/camss-8x16/camss-csiphy.c | 113 ++++++-- .../media/platform/qcom/camss-8x16/camss-csiphy.h | 2 +- .../media/platform/qcom/camss-8x16/camss-ispif.c | 23 +- .../media/platform/qcom/camss-8x16/camss-ispif.h | 4 +- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 289 ++++++++++++++++++--- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 2 +- drivers/media/platform/qcom/camss-8x16/camss.c | 67 ++++- drivers/media/platform/qcom/camss-8x16/camss.h | 15 +- 10 files changed, 547 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss-8x16/camss-csid.c index 5c09e83e4a2b..792c14a9f59c 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c @@ -69,6 +69,7 @@ struct csid_fmts { u8 data_type; u8 decode_format; u8 bpp; + u8 spp; /* bus samples per pixel */ }; static const struct csid_fmts csid_input_fmts[] = { @@ -76,97 +77,113 @@ static const struct csid_fmts csid_input_fmts[] = { MEDIA_BUS_FMT_UYVY8_2X8, DATA_TYPE_YUV422_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 16, + 8, + 2, }, { MEDIA_BUS_FMT_VYUY8_2X8, DATA_TYPE_YUV422_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 16, + 8, + 2, }, { MEDIA_BUS_FMT_YUYV8_2X8, DATA_TYPE_YUV422_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 16, + 8, + 2, }, { MEDIA_BUS_FMT_YVYU8_2X8, DATA_TYPE_YUV422_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, - 16, + 8, + 2, }, { MEDIA_BUS_FMT_SBGGR8_1X8, DATA_TYPE_RAW_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, 8, + 1, }, { MEDIA_BUS_FMT_SGBRG8_1X8, DATA_TYPE_RAW_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, 8, + 1, }, { MEDIA_BUS_FMT_SGRBG8_1X8, DATA_TYPE_RAW_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, 8, + 1, }, { MEDIA_BUS_FMT_SRGGB8_1X8, DATA_TYPE_RAW_8BIT, DECODE_FORMAT_UNCOMPRESSED_8_BIT, 8, + 1, }, { MEDIA_BUS_FMT_SBGGR10_1X10, DATA_TYPE_RAW_10BIT, DECODE_FORMAT_UNCOMPRESSED_10_BIT, 10, + 1, }, { MEDIA_BUS_FMT_SGBRG10_1X10, DATA_TYPE_RAW_10BIT, DECODE_FORMAT_UNCOMPRESSED_10_BIT, 10, + 1, }, { MEDIA_BUS_FMT_SGRBG10_1X10, DATA_TYPE_RAW_10BIT, DECODE_FORMAT_UNCOMPRESSED_10_BIT, 10, + 1, }, { MEDIA_BUS_FMT_SRGGB10_1X10, DATA_TYPE_RAW_10BIT, DECODE_FORMAT_UNCOMPRESSED_10_BIT, 10, + 1, }, { MEDIA_BUS_FMT_SBGGR12_1X12, DATA_TYPE_RAW_12BIT, DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, + 1, }, { MEDIA_BUS_FMT_SGBRG12_1X12, DATA_TYPE_RAW_12BIT, DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, + 1, }, { MEDIA_BUS_FMT_SGRBG12_1X12, DATA_TYPE_RAW_12BIT, DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, + 1, }, { MEDIA_BUS_FMT_SRGGB12_1X12, DATA_TYPE_RAW_12BIT, DECODE_FORMAT_UNCOMPRESSED_12_BIT, 12, + 1, } }; @@ -204,6 +221,67 @@ static irqreturn_t csid_isr(int irq, void *dev) return IRQ_HANDLED; } +/* + * csid_set_clock_rates - Calculate and set clock rates on CSID module + * @csiphy: CSID device + */ +static int csid_set_clock_rates(struct csid_device *csid) +{ + struct device *dev = to_device_index(csid, csid->id); + u32 pixel_clock; + int i, j; + int ret; + + ret = camss_get_pixel_clock(&csid->subdev.entity, &pixel_clock); + if (ret) + pixel_clock = 0; + + for (i = 0; i < csid->nclocks; i++) { + struct camss_clock *clock = &csid->clock[i]; + + if (!strcmp(clock->name, "csi0") || + !strcmp(clock->name, "csi1")) { + u8 bpp = csid_get_fmt_entry( + csid->fmt[MSM_CSIPHY_PAD_SINK].code)->bpp; + u8 num_lanes = csid->phy.lane_cnt; + u64 min_rate = pixel_clock * bpp / (2 * num_lanes * 4); + long rate; + + camss_add_clock_margin(&min_rate); + + for (j = 0; j < clock->nfreqs; j++) + if (min_rate < clock->freq[j]) + break; + + if (j == clock->nfreqs) { + dev_err(dev, + "Pixel clock is too high for CSID\n"); + return -EINVAL; + } + + /* if sensor pixel clock is not available */ + /* set highest possible CSID clock rate */ + if (min_rate == 0) + j = clock->nfreqs - 1; + + rate = clk_round_rate(clock->clk, clock->freq[j]); + if (rate < 0) { + dev_err(dev, "clk round rate failed: %ld\n", + rate); + return -EINVAL; + } + + ret = clk_set_rate(clock->clk, rate); + if (ret < 0) { + dev_err(dev, "clk set rate failed: %d\n", ret); + return ret; + } + } + } + + return 0; +} + /* * csid_reset - Trigger reset on CSID module and wait to complete * @csid: CSID device @@ -249,6 +327,12 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) if (ret < 0) return ret; + ret = csid_set_clock_rates(csid); + if (ret < 0) { + regulator_disable(csid->vdda); + return ret; + } + ret = camss_enable_clocks(csid->nclocks, csid->clock, dev); if (ret < 0) { regulator_disable(csid->vdda); @@ -316,7 +400,8 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) struct v4l2_mbus_framefmt *f = &csid->fmt[MSM_CSID_PAD_SRC]; u8 bpp = csid_get_fmt_entry(f->code)->bpp; - u32 num_bytes_per_line = f->width * bpp / 8; + u8 spp = csid_get_fmt_entry(f->code)->spp; + u32 num_bytes_per_line = f->width * bpp * spp / 8; u32 num_lines = f->height; /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */ @@ -719,7 +804,7 @@ int msm_csid_subdev_init(struct csid_device *csid, struct device *dev = to_device_index(csid, id); struct platform_device *pdev = to_platform_device(dev); struct resource *r; - int i; + int i, j; int ret; csid->id = id; @@ -766,26 +851,30 @@ int msm_csid_subdev_init(struct csid_device *csid, return -ENOMEM; for (i = 0; i < csid->nclocks; i++) { - csid->clock[i] = devm_clk_get(dev, res->clock[i]); - if (IS_ERR(csid->clock[i])) - return PTR_ERR(csid->clock[i]); - - if (res->clock_rate[i]) { - long clk_rate = clk_round_rate(csid->clock[i], - res->clock_rate[i]); - if (clk_rate < 0) { - dev_err(to_device_index(csid, csid->id), - "clk round rate failed: %ld\n", - clk_rate); - return -EINVAL; - } - ret = clk_set_rate(csid->clock[i], clk_rate); - if (ret < 0) { - dev_err(to_device_index(csid, csid->id), - "clk set rate failed: %d\n", ret); - return ret; - } + struct camss_clock *clock = &csid->clock[i]; + + clock->clk = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(clock->clk)) + return PTR_ERR(clock->clk); + + clock->name = res->clock[i]; + + clock->nfreqs = 0; + while (res->clock_rate[i][clock->nfreqs]) + clock->nfreqs++; + + if (!clock->nfreqs) { + clock->freq = NULL; + continue; } + + clock->freq = devm_kzalloc(dev, clock->nfreqs * + sizeof(*clock->freq), GFP_KERNEL); + if (!clock->freq) + return -ENOMEM; + + for (j = 0; j < clock->nfreqs; j++) + clock->freq[j] = res->clock_rate[i][j]; } /* Regulator */ diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.h b/drivers/media/platform/qcom/camss-8x16/camss-csid.h index 3186c11ac07d..4df70183c994 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.h @@ -56,7 +56,7 @@ struct csid_device { void __iomem *base; u32 irq; char irq_name[30]; - struct clk **clock; + struct camss_clock *clock; int nclocks; struct regulator *vdda; struct completion reset_complete; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c index ed03775c9b3a..e9040b193486 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c @@ -157,6 +157,69 @@ static irqreturn_t csiphy_isr(int irq, void *dev) return IRQ_HANDLED; } +/* + * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module + * @csiphy: CSIPHY device + */ +static int csiphy_set_clock_rates(struct csiphy_device *csiphy) +{ + struct device *dev = to_device_index(csiphy, csiphy->id); + u32 pixel_clock; + int i, j; + int ret; + + ret = camss_get_pixel_clock(&csiphy->subdev.entity, &pixel_clock); + if (ret) + pixel_clock = 0; + + for (i = 0; i < csiphy->nclocks; i++) { + struct camss_clock *clock = &csiphy->clock[i]; + + if (!strcmp(clock->name, "csiphy0_timer") || + !strcmp(clock->name, "csiphy1_timer")) { + u8 bpp = csiphy_get_bpp( + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); + u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; + u64 min_rate = pixel_clock * bpp / (2 * num_lanes * 4); + long round_rate; + + camss_add_clock_margin(&min_rate); + + for (j = 0; j < clock->nfreqs; j++) + if (min_rate < clock->freq[j]) + break; + + if (j == clock->nfreqs) { + dev_err(dev, + "Pixel clock is too high for CSIPHY\n"); + return -EINVAL; + } + + /* if sensor pixel clock is not available */ + /* set highest possible CSIPHY clock rate */ + if (min_rate == 0) + j = clock->nfreqs - 1; + + round_rate = clk_round_rate(clock->clk, clock->freq[j]); + if (round_rate < 0) { + dev_err(dev, "clk round rate failed: %ld\n", + round_rate); + return -EINVAL; + } + + csiphy->timer_clk_rate = round_rate; + + ret = clk_set_rate(clock->clk, csiphy->timer_clk_rate); + if (ret < 0) { + dev_err(dev, "clk set rate failed: %d\n", ret); + return ret; + } + } + } + + return 0; +} + /* * csiphy_reset - Perform software reset on CSIPHY module * @csiphy: CSIPHY device @@ -184,6 +247,10 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) u8 hw_version; int ret; + ret = csiphy_set_clock_rates(csiphy); + if (ret < 0) + return ret; + ret = camss_enable_clocks(csiphy->nclocks, csiphy->clock, dev); if (ret < 0) return ret; @@ -616,7 +683,7 @@ int msm_csiphy_subdev_init(struct csiphy_device *csiphy, struct device *dev = to_device_index(csiphy, id); struct platform_device *pdev = to_platform_device(dev); struct resource *r; - int i; + int i, j; int ret; csiphy->id = id; @@ -671,30 +738,30 @@ int msm_csiphy_subdev_init(struct csiphy_device *csiphy, return -ENOMEM; for (i = 0; i < csiphy->nclocks; i++) { - csiphy->clock[i] = devm_clk_get(dev, res->clock[i]); - if (IS_ERR(csiphy->clock[i])) - return PTR_ERR(csiphy->clock[i]); - - if (res->clock_rate[i]) { - long clk_rate = clk_round_rate(csiphy->clock[i], - res->clock_rate[i]); - if (clk_rate < 0) { - dev_err(to_device_index(csiphy, csiphy->id), - "clk round rate failed: %ld\n", - clk_rate); - return -EINVAL; - } - ret = clk_set_rate(csiphy->clock[i], clk_rate); - if (ret < 0) { - dev_err(to_device_index(csiphy, csiphy->id), - "clk set rate failed: %d\n", ret); - return ret; - } + struct camss_clock *clock = &csiphy->clock[i]; - if (!strcmp(res->clock[i], "csiphy0_timer") || - !strcmp(res->clock[i], "csiphy1_timer")) - csiphy->timer_clk_rate = clk_rate; + clock->clk = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(clock->clk)) + return PTR_ERR(clock->clk); + + clock->name = res->clock[i]; + + clock->nfreqs = 0; + while (res->clock_rate[i][clock->nfreqs]) + clock->nfreqs++; + + if (!clock->nfreqs) { + clock->freq = NULL; + continue; } + + clock->freq = devm_kzalloc(dev, clock->nfreqs * + sizeof(*clock->freq), GFP_KERNEL); + if (!clock->freq) + return -ENOMEM; + + for (j = 0; j < clock->nfreqs; j++) + clock->freq[j] = res->clock_rate[i][j]; } return 0; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h index e886e6d88fd2..ba8781122065 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.h @@ -57,7 +57,7 @@ struct csiphy_device { void __iomem *base_clk_mux; u32 irq; char irq_name[30]; - struct clk **clock; + struct camss_clock *clock; int nclocks; u32 timer_clk_rate; struct csiphy_config cfg; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c index 31e00e534a6a..54d1946f5213 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -954,9 +954,14 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, return -ENOMEM; for (i = 0; i < ispif->nclocks; i++) { - ispif->clock[i] = devm_clk_get(dev, res->clock[i]); - if (IS_ERR(ispif->clock[i])) - return PTR_ERR(ispif->clock[i]); + struct camss_clock *clock = &ispif->clock[i]; + + clock->clk = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(clock->clk)) + return PTR_ERR(clock->clk); + + clock->freq = NULL; + clock->nfreqs = 0; } ispif->nclocks_for_reset = 0; @@ -969,10 +974,14 @@ int msm_ispif_subdev_init(struct ispif_device *ispif, return -ENOMEM; for (i = 0; i < ispif->nclocks_for_reset; i++) { - ispif->clock_for_reset[i] = devm_clk_get(dev, - res->clock_for_reset[i]); - if (IS_ERR(ispif->clock_for_reset[i])) - return PTR_ERR(ispif->clock_for_reset[i]); + struct camss_clock *clock = &ispif->clock_for_reset[i]; + + clock->clk = devm_clk_get(dev, res->clock_for_reset[i]); + if (IS_ERR(clock->clk)) + return PTR_ERR(clock->clk); + + clock->freq = NULL; + clock->nfreqs = 0; } for (i = 0; i < ARRAY_SIZE(ispif->line); i++) diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h index 6a1c9bd65477..6659020525d1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h @@ -60,9 +60,9 @@ struct ispif_device { void __iomem *base_clk_mux; u32 irq; char irq_name[30]; - struct clk **clock; + struct camss_clock *clock; int nclocks; - struct clk **clock_for_reset; + struct camss_clock *clock_for_reset; int nclocks_for_reset; struct completion reset_complete; int power_count; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index c62a1ba5dc3b..1c86b10e204b 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -243,25 +243,95 @@ #define SCALER_RATIO_MAX 16 -static const u32 vfe_formats[] = { - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_SBGGR8_1X8, - MEDIA_BUS_FMT_SGBRG8_1X8, - MEDIA_BUS_FMT_SGRBG8_1X8, - MEDIA_BUS_FMT_SRGGB8_1X8, - MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SGBRG10_1X10, - MEDIA_BUS_FMT_SGRBG10_1X10, - MEDIA_BUS_FMT_SRGGB10_1X10, - MEDIA_BUS_FMT_SBGGR12_1X12, - MEDIA_BUS_FMT_SGBRG12_1X12, - MEDIA_BUS_FMT_SGRBG12_1X12, - MEDIA_BUS_FMT_SRGGB12_1X12, +static const struct { + u32 code; + u8 bpp; +} vfe_formats[] = { + { + MEDIA_BUS_FMT_UYVY8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_VYUY8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_YUYV8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_YVYU8_2X8, + 8, + }, + { + MEDIA_BUS_FMT_SBGGR8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SGBRG8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SGRBG8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SRGGB8_1X8, + 8, + }, + { + MEDIA_BUS_FMT_SBGGR10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SGBRG10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SGRBG10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SRGGB10_1X10, + 10, + }, + { + MEDIA_BUS_FMT_SBGGR12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SGBRG12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SGRBG12_1X12, + 12, + }, + { + MEDIA_BUS_FMT_SRGGB12_1X12, + 12, + } }; +/* + * vfe_get_bpp - map media bus format to bits per pixel + * @code: media bus format code + * + * Return number of bits per pixel + */ +static u8 vfe_get_bpp(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(vfe_formats); i++) + if (code == vfe_formats[i].code) + return vfe_formats[i].bpp; + + WARN(1, "Unknown format\n"); + + return vfe_formats[0].bpp; +} + static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) { u32 bits = readl_relaxed(vfe->base + reg); @@ -1766,6 +1836,138 @@ static irqreturn_t vfe_isr(int irq, void *dev) return IRQ_HANDLED; } +/* + * vfe_set_clock_rates - Calculate and set clock rates on VFE module + * @vfe: VFE device + * + * Return 0 on success or a negative error code otherwise + */ +static int vfe_set_clock_rates(struct vfe_device *vfe) +{ + struct device *dev = to_device(vfe); + u32 pixel_clock[MSM_VFE_LINE_NUM]; + int i, j; + int ret; + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { + ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, + &pixel_clock[i]); + if (ret) + pixel_clock[i] = 0; + } + + for (i = 0; i < vfe->nclocks; i++) { + struct camss_clock *clock = &vfe->clock[i]; + + if (!strcmp(clock->name, "camss_vfe_vfe")) { + u64 min_rate = 0; + long rate; + + for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) { + u32 tmp; + u8 bpp; + + if (j == VFE_LINE_PIX) { + tmp = pixel_clock[j]; + } else { + bpp = vfe_get_bpp(vfe->line[j]. + fmt[MSM_VFE_PAD_SINK].code); + tmp = pixel_clock[j] * bpp / 64; + } + + if (min_rate < tmp) + min_rate = tmp; + } + + camss_add_clock_margin(&min_rate); + + for (j = 0; j < clock->nfreqs; j++) + if (min_rate < clock->freq[j]) + break; + + if (j == clock->nfreqs) { + dev_err(dev, + "Pixel clock is too high for VFE"); + return -EINVAL; + } + + /* if sensor pixel clock is not available */ + /* set highest possible VFE clock rate */ + if (min_rate == 0) + j = clock->nfreqs - 1; + + rate = clk_round_rate(clock->clk, clock->freq[j]); + if (rate < 0) { + dev_err(dev, "clk round rate failed: %ld\n", + rate); + return -EINVAL; + } + + ret = clk_set_rate(clock->clk, rate); + if (ret < 0) { + dev_err(dev, "clk set rate failed: %d\n", ret); + return ret; + } + } + } + + return 0; +} + +/* + * vfe_check_clock_rates - Check current clock rates on VFE module + * @vfe: VFE device + * + * Return 0 if current clock rates are suitable for a new pipeline + * or a negative error code otherwise + */ +static int vfe_check_clock_rates(struct vfe_device *vfe) +{ + u32 pixel_clock[MSM_VFE_LINE_NUM]; + int i, j; + int ret; + + for (i = VFE_LINE_RDI0; i <= VFE_LINE_PIX; i++) { + ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity, + &pixel_clock[i]); + if (ret) + pixel_clock[i] = 0; + } + + for (i = 0; i < vfe->nclocks; i++) { + struct camss_clock *clock = &vfe->clock[i]; + + if (!strcmp(clock->name, "camss_vfe_vfe")) { + u64 min_rate = 0; + unsigned long rate; + + for (j = VFE_LINE_RDI0; j <= VFE_LINE_PIX; j++) { + u32 tmp; + u8 bpp; + + if (j == VFE_LINE_PIX) { + tmp = pixel_clock[j]; + } else { + bpp = vfe_get_bpp(vfe->line[j]. + fmt[MSM_VFE_PAD_SINK].code); + tmp = pixel_clock[j] * bpp / 64; + } + + if (min_rate < tmp) + min_rate = tmp; + } + + camss_add_clock_margin(&min_rate); + + rate = clk_get_rate(clock->clk); + if (rate < min_rate) + return -EBUSY; + } + } + + return 0; +} + /* * vfe_get - Power up and reset VFE module * @vfe: VFE Device @@ -1779,6 +1981,10 @@ static int vfe_get(struct vfe_device *vfe) mutex_lock(&vfe->power_lock); if (vfe->power_count == 0) { + ret = vfe_set_clock_rates(vfe); + if (ret < 0) + goto error_clocks; + ret = camss_enable_clocks(vfe->nclocks, vfe->clock, to_device(vfe)); if (ret < 0) @@ -1791,6 +1997,10 @@ static int vfe_get(struct vfe_device *vfe) vfe_reset_output_maps(vfe); vfe_init_outputs(vfe); + } else { + ret = vfe_check_clock_rates(vfe); + if (ret < 0) + goto error_clocks; } vfe->power_count++; @@ -2074,7 +2284,7 @@ static void vfe_try_format(struct vfe_line *line, /* Set format on sink pad */ for (i = 0; i < ARRAY_SIZE(vfe_formats); i++) - if (fmt->code == vfe_formats[i]) + if (fmt->code == vfe_formats[i].code) break; /* If not found, use UYVY as default */ @@ -2241,7 +2451,7 @@ static int vfe_enum_mbus_code(struct v4l2_subdev *sd, if (code->index >= ARRAY_SIZE(vfe_formats)) return -EINVAL; - code->code = vfe_formats[code->index]; + code->code = vfe_formats[code->index].code; } else { if (code->index > 0) return -EINVAL; @@ -2544,7 +2754,7 @@ int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) struct platform_device *pdev = to_platform_device(dev); struct resource *r; struct camss *camss = to_camss(vfe); - int i; + int i, j; int ret; /* Memory */ @@ -2587,23 +2797,30 @@ int msm_vfe_subdev_init(struct vfe_device *vfe, const struct resources *res) return -ENOMEM; for (i = 0; i < vfe->nclocks; i++) { - vfe->clock[i] = devm_clk_get(dev, res->clock[i]); - if (IS_ERR(vfe->clock[i])) - return PTR_ERR(vfe->clock[i]); - - if (res->clock_rate[i]) { - long clk_rate = clk_round_rate(vfe->clock[i], - res->clock_rate[i]); - if (clk_rate < 0) { - dev_err(dev, "clk round rate failed\n"); - return -EINVAL; - } - ret = clk_set_rate(vfe->clock[i], clk_rate); - if (ret < 0) { - dev_err(dev, "clk set rate failed\n"); - return ret; - } + struct camss_clock *clock = &vfe->clock[i]; + + clock->clk = devm_clk_get(dev, res->clock[i]); + if (IS_ERR(clock->clk)) + return PTR_ERR(clock->clk); + + clock->name = res->clock[i]; + + clock->nfreqs = 0; + while (res->clock_rate[i][clock->nfreqs]) + clock->nfreqs++; + + if (!clock->nfreqs) { + clock->freq = NULL; + continue; } + + clock->freq = devm_kzalloc(dev, clock->nfreqs * + sizeof(*clock->freq), GFP_KERNEL); + if (!clock->freq) + return -ENOMEM; + + for (j = 0; j < clock->nfreqs; j++) + clock->freq[j] = res->clock_rate[i][j]; } mutex_init(&vfe->power_lock); diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index 3651ece53caa..88c29d0dcafa 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -91,7 +91,7 @@ struct vfe_device { void __iomem *base; u32 irq; char irq_name[30]; - struct clk **clock; + struct camss_clock *clock; int nclocks; struct completion reset_complete; struct completion halt_complete; diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c index 2dee77a80327..a3760b5dd1d1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss.c +++ b/drivers/media/platform/qcom/camss-8x16/camss.c @@ -33,13 +33,19 @@ #include "camss.h" +#define CAMSS_CLOCK_MARGIN_NUMERATOR 105 +#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 + static const struct resources csiphy_res[] = { /* CSIPHY0 */ { .regulator = { NULL }, .clock = { "camss_top_ahb", "ispif_ahb", "camss_ahb", "csiphy0_timer" }, - .clock_rate = { 0, 0, 0, 200000000 }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000 } }, .reg = { "csiphy0", "csiphy0_clk_mux" }, .interrupt = { "csiphy0" } }, @@ -49,7 +55,10 @@ static const struct resources csiphy_res[] = { .regulator = { NULL }, .clock = { "camss_top_ahb", "ispif_ahb", "camss_ahb", "csiphy1_timer" }, - .clock_rate = { 0, 0, 0, 200000000 }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000 } }, .reg = { "csiphy1", "csiphy1_clk_mux" }, .interrupt = { "csiphy1" } } @@ -62,7 +71,14 @@ static const struct resources csid_res[] = { .clock = { "camss_top_ahb", "ispif_ahb", "csi0_ahb", "camss_ahb", "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, - .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, .reg = { "csid0" }, .interrupt = { "csid0" } }, @@ -73,7 +89,14 @@ static const struct resources csid_res[] = { .clock = { "camss_top_ahb", "ispif_ahb", "csi1_ahb", "camss_ahb", "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, - .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 }, + .clock_rate = { { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, .reg = { "csid1" }, .interrupt = { "csid1" } }, @@ -95,11 +118,34 @@ static const struct resources vfe_res = { .regulator = { NULL }, .clock = { "camss_top_ahb", "camss_vfe_vfe", "camss_csi_vfe", "iface", "bus", "camss_ahb" }, - .clock_rate = { 0, 320000000, 0, 0, 0, 0, 0, 0 }, + .clock_rate = { { 0 }, + { 50000000, 80000000, 100000000, 160000000, + 177780000, 200000000, 266670000, 320000000, + 400000000, 465000000 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + { 0 } }, .reg = { "vfe0" }, .interrupt = { "vfe0" } }; +/* + * camss_add_clock_margin - Add margin to clock frequency rate + * @rate: Clock frequency rate + * + * When making calculations with physical clock frequency values + * some safety margin must be added. Add it. + */ +inline void camss_add_clock_margin(u64 *rate) +{ + *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR; + *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR); +} + /* * camss_enable_clocks - Enable multiple clocks * @nclocks: Number of clocks in clock array @@ -108,13 +154,14 @@ static const struct resources vfe_res = { * * Return 0 on success or a negative error code otherwise */ -int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev) +int camss_enable_clocks(int nclocks, struct camss_clock *clock, + struct device *dev) { int ret; int i; for (i = 0; i < nclocks; i++) { - ret = clk_prepare_enable(clock[i]); + ret = clk_prepare_enable(clock[i].clk); if (ret) { dev_err(dev, "clock enable failed: %d\n", ret); goto error; @@ -125,7 +172,7 @@ int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev) error: for (i--; i >= 0; i--) - clk_disable_unprepare(clock[i]); + clk_disable_unprepare(clock[i].clk); return ret; } @@ -135,12 +182,12 @@ error: * @nclocks: Number of clocks in clock array * @clock: Clock array */ -void camss_disable_clocks(int nclocks, struct clk **clock) +void camss_disable_clocks(int nclocks, struct camss_clock *clock) { int i; for (i = nclocks - 1; i >= 0; i--) - clk_disable_unprepare(clock[i]); + clk_disable_unprepare(clock[i].clk); } /* diff --git a/drivers/media/platform/qcom/camss-8x16/camss.h b/drivers/media/platform/qcom/camss-8x16/camss.h index 4619d7634207..4ad223443e4b 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss.h +++ b/drivers/media/platform/qcom/camss-8x16/camss.h @@ -55,7 +55,7 @@ struct resources { char *regulator[CAMSS_RES_MAX]; char *clock[CAMSS_RES_MAX]; - s32 clock_rate[CAMSS_RES_MAX]; + u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX]; char *reg[CAMSS_RES_MAX]; char *interrupt[CAMSS_RES_MAX]; }; @@ -89,8 +89,17 @@ struct camss_async_subdev { struct v4l2_async_subdev asd; }; -int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev); -void camss_disable_clocks(int nclocks, struct clk **clock); +struct camss_clock { + struct clk *clk; + const char *name; + u32 *freq; + u32 nfreqs; +}; + +void camss_add_clock_margin(u64 *rate); +int camss_enable_clocks(int nclocks, struct camss_clock *clock, + struct device *dev); +void camss_disable_clocks(int nclocks, struct camss_clock *clock); int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock); void camss_delete(struct camss *camss); -- cgit v1.2.3 From be744eec2327a19543215f08a7f763010ff8a39f Mon Sep 17 00:00:00 2001 From: Todor Tomov Date: Fri, 18 Aug 2017 04:16:34 -0400 Subject: media: camss: Add abbreviations explanation Add abbreviations explanation at the top header blocks in source files. Signed-off-by: Todor Tomov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-csid.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-csid.h | 2 +- drivers/media/platform/qcom/camss-8x16/camss-ispif.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-ispif.h | 2 +- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 2 +- drivers/media/platform/qcom/camss-8x16/camss-vfe.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.c b/drivers/media/platform/qcom/camss-8x16/camss-csid.c index 792c14a9f59c..64df82817de3 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.c @@ -1,7 +1,7 @@ /* * camss-csid.c * - * Qualcomm MSM Camera Subsystem - CSID Module + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module * * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csid.h b/drivers/media/platform/qcom/camss-8x16/camss-csid.h index 4df70183c994..8682d3081bc3 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csid.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-csid.h @@ -1,7 +1,7 @@ /* * camss-csid.h * - * Qualcomm MSM Camera Subsystem - CSID Module + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module * * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c index 54d1946f5213..24da529397b5 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.c @@ -1,7 +1,7 @@ /* * camss-ispif.c * - * Qualcomm MSM Camera Subsystem - ISPIF Module + * Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h index 6659020525d1..f668306020c3 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-ispif.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-ispif.h @@ -1,7 +1,7 @@ /* * camss-ispif.h * - * Qualcomm MSM Camera Subsystem - ISPIF Module + * Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module * * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 1c86b10e204b..94d635e00aa1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -1,7 +1,7 @@ /* * camss-vfe.c * - * Qualcomm MSM Camera Subsystem - VFE Module + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h index 88c29d0dcafa..53d5b66a9dfb 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.h +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.h @@ -1,7 +1,7 @@ /* * camss-vfe.h * - * Qualcomm MSM Camera Subsystem - VFE Module + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2015-2017 Linaro Ltd. -- cgit v1.2.3 From 07aac5dc0d1b9ccbf031ef3195bf11f65f732583 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Aug 2017 15:33:25 -0400 Subject: media: qcom: mark long long consts as such Fix those warnings when building on i386: drivers/media/platform/qcom/camss-8x16/camss-csiphy.c:333:22: warning: constant 1000000000000 is so big it is long long drivers/media/platform/qcom/camss-8x16/camss-csiphy.c:339:32: warning: constant 1000000000000 is so big it is long long Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-csiphy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c index e9040b193486..072c6cf053f6 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-csiphy.c @@ -330,13 +330,13 @@ static u8 csiphy_settle_cnt_calc(struct csiphy_device *csiphy) } mipi_clock = pixel_clock * bpp / (2 * num_lanes); - ui = div_u64(1000000000000, mipi_clock); + ui = div_u64(1000000000000LL, mipi_clock); ui /= 2; t_hs_prepare_max = 85000 + 6 * ui; t_hs_prepare_zero_min = 145000 + 10 * ui; t_hs_settle = (t_hs_prepare_max + t_hs_prepare_zero_min) / 2; - timer_period = div_u64(1000000000000, csiphy->timer_clk_rate); + timer_period = div_u64(1000000000000LL, csiphy->timer_clk_rate); settle_cnt = t_hs_settle / timer_period; return settle_cnt; -- cgit v1.2.3 From 6e893ca25e9ea87aeb5400af58518111e42582fe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 26 Aug 2017 15:34:37 -0400 Subject: media: qcom: don't go past the array As reported by smatch: drivers/media/platform/qcom/camss-8x16/camss-vfe.c:1136 vfe_release_wm() error: buffer overflow 'vfe->wm_output_map' 7 <= 7 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss-8x16/camss-vfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index 94d635e00aa1..b21b3c2dc77f 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -1130,7 +1130,7 @@ static int vfe_reserve_wm(struct vfe_device *vfe, enum vfe_line_id line_id) static int vfe_release_wm(struct vfe_device *vfe, u8 wm) { - if (wm > ARRAY_SIZE(vfe->wm_output_map)) + if (wm >= ARRAY_SIZE(vfe->wm_output_map)) return -EINVAL; vfe->wm_output_map[wm] = VFE_LINE_NONE; -- cgit v1.2.3 From 5160fb4bbd7add491b93fbf859cae5804f3de8bf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 23 Aug 2017 09:30:19 -0400 Subject: media: omap3isp: fix uninitialized variable use A debug printk statement was copied incorrectly into the new csi1 parser code and causes a warning there: drivers/media/platform/omap3isp/isp.c: In function 'isp_probe': include/linux/dynamic_debug.h:134:3: error: 'i' may be used uninitialized in this function [-Werror=maybe-uninitialized] Since there is only one lane, the index is never set. This changes the debug print to always print a zero instead, keeping the original format of the message. Fixes: 9211434bad30 ("media: omap3isp: Parse CSI1 configuration from the device tree") Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Reviewed-by: Sebastian Reichel Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/isp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 83aea08b832d..1a428fe9f070 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2092,7 +2092,7 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, buscfg->bus.ccp2.lanecfg.data[0].pol = vep.bus.mipi_csi1.lane_polarity[1]; - dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i, + dev_dbg(dev, "data lane polarity %u, pos %u\n", buscfg->bus.ccp2.lanecfg.data[0].pol, buscfg->bus.ccp2.lanecfg.data[0].pos); -- cgit v1.2.3 From 72c901582c366da670181b9a13dea28d2078b905 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 24 Aug 2017 01:58:39 -0400 Subject: media: smiapp: check memory allocation failure Check memory allocation failure and return -ENOMEM in such a case. Signed-off-by: Christophe JAILLET Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index aff55e1dffe7..700f433261d0 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -841,6 +841,8 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) &client->dev, compressed_max_bpp - sensor->compressed_min_bpp + 1, sizeof(*sensor->valid_link_freqs), GFP_KERNEL); + if (!sensor->valid_link_freqs) + return -ENOMEM; for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) { const struct smiapp_csi_data_format *f = -- cgit v1.2.3 From 428359cbfe086f43cb84b7ab7b48e7e7862700e2 Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Wed, 2 Aug 2017 12:52:57 -0400 Subject: media: staging: greybus: light: fix memory leak in v4l2 register We are allocating memory for the v4l2 flash configuration structure and leak it in the normal path. Just use the stack for this as we do not use it outside of this function. Also use IS_ERR() instead of IS_ERR_OR_NULL() to check return value from v4l2_flash_init() for it never returns NULL. Fixes: 2870b52bae4c ("greybus: lights: add lights implementation") Reported-by: Sakari Ailus Signed-off-by: Rui Miguel Silva Reviewed-by: Viresh Kumar Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/greybus/light.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index 129ceed39829..81469d087e74 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -534,25 +534,20 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) { struct gb_connection *connection = get_conn_from_light(light); struct device *dev = &connection->bundle->dev; - struct v4l2_flash_config *sd_cfg; + struct v4l2_flash_config sd_cfg = { {0} }; struct led_classdev_flash *fled; struct led_classdev *iled = NULL; struct gb_channel *channel_torch, *channel_ind, *channel_flash; - int ret = 0; - - sd_cfg = kcalloc(1, sizeof(*sd_cfg), GFP_KERNEL); - if (!sd_cfg) - return -ENOMEM; channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH); if (channel_torch) __gb_lights_channel_v4l2_config(&channel_torch->intensity_uA, - &sd_cfg->torch_intensity); + &sd_cfg.torch_intensity); channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR); if (channel_ind) { __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA, - &sd_cfg->indicator_intensity); + &sd_cfg.indicator_intensity); iled = &channel_ind->fled.led_cdev; } @@ -561,27 +556,21 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) fled = &channel_flash->fled; - snprintf(sd_cfg->dev_name, sizeof(sd_cfg->dev_name), "%s", light->name); + snprintf(sd_cfg.dev_name, sizeof(sd_cfg.dev_name), "%s", light->name); /* Set the possible values to faults, in our case all faults */ - sd_cfg->flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT | + sd_cfg.flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT | LED_FAULT_OVER_TEMPERATURE | LED_FAULT_SHORT_CIRCUIT | LED_FAULT_OVER_CURRENT | LED_FAULT_INDICATOR | LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE | LED_FAULT_LED_OVER_TEMPERATURE; light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, iled, - &v4l2_flash_ops, sd_cfg); - if (IS_ERR_OR_NULL(light->v4l2_flash)) { - ret = PTR_ERR(light->v4l2_flash); - goto out_free; - } + &v4l2_flash_ops, &sd_cfg); + if (IS_ERR(light->v4l2_flash)) + return PTR_ERR(light->v4l2_flash); - return ret; - -out_free: - kfree(sd_cfg); - return ret; + return 0; } static void gb_lights_light_v4l2_unregister(struct gb_light *light) -- cgit v1.2.3 From 503dd28af108888c505e8d6a86f4acf5eb20f3b7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 18 Jul 2017 09:26:59 -0400 Subject: media: v4l2-flash-led-class: Create separate sub-devices for indicators The V4L2 flash interface allows controlling multiple LEDs through a single sub-devices if, and only if, these LEDs are of different types. This approach scales badly for flash controllers that drive multiple flash LEDs or for LED specific associations. Essentially, the original assumption of a LED driver chip that drives a single flash LED and an indicator LED is no longer valid. Address the matter by registering one sub-device per LED. Signed-off-by: Sakari Ailus Reviewed-by: Jacek Anaszewski Acked-by: Pavel Machek Reviewed-by: Rui Miguel Silva (for greybus/light) Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/leds/leds-aat1290.c | 4 +- drivers/leds/leds-max77693.c | 4 +- drivers/media/v4l2-core/v4l2-flash-led-class.c | 113 +++++++++++++++---------- drivers/staging/greybus/light.c | 23 +++-- include/media/v4l2-flash-led-class.h | 40 ++++++--- 5 files changed, 117 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c index a21e19297745..424898e6c69d 100644 --- a/drivers/leds/leds-aat1290.c +++ b/drivers/leds/leds-aat1290.c @@ -432,7 +432,7 @@ static void aat1290_init_v4l2_flash_config(struct aat1290_led *led, strlcpy(v4l2_sd_cfg->dev_name, led_cdev->name, sizeof(v4l2_sd_cfg->dev_name)); - s = &v4l2_sd_cfg->torch_intensity; + s = &v4l2_sd_cfg->intensity; s->min = led->mm_current_scale[0]; s->max = led_cfg->max_mm_current; s->step = 1; @@ -504,7 +504,7 @@ static int aat1290_led_probe(struct platform_device *pdev) /* Create V4L2 Flash subdev. */ led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node), - fled_cdev, NULL, &v4l2_flash_ops, + fled_cdev, &v4l2_flash_ops, &v4l2_sd_cfg); if (IS_ERR(led->v4l2_flash)) { ret = PTR_ERR(led->v4l2_flash); diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c index 2d3062d53325..adf0f191f794 100644 --- a/drivers/leds/leds-max77693.c +++ b/drivers/leds/leds-max77693.c @@ -856,7 +856,7 @@ static void max77693_init_v4l2_flash_config(struct max77693_sub_led *sub_led, "%s %d-%04x", sub_led->fled_cdev.led_cdev.name, i2c_adapter_id(i2c->adapter), i2c->addr); - s = &v4l2_sd_cfg->torch_intensity; + s = &v4l2_sd_cfg->intensity; s->min = TORCH_IOUT_MIN; s->max = sub_led->fled_cdev.led_cdev.max_brightness * TORCH_IOUT_STEP; s->step = TORCH_IOUT_STEP; @@ -931,7 +931,7 @@ static int max77693_register_led(struct max77693_sub_led *sub_led, /* Register in the V4L2 subsystem. */ sub_led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node), - fled_cdev, NULL, &v4l2_flash_ops, + fled_cdev, &v4l2_flash_ops, &v4l2_sd_cfg); if (IS_ERR(sub_led->v4l2_flash)) { ret = PTR_ERR(sub_led->v4l2_flash); diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index aabc85dbb8b5..4ceef217de83 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -197,7 +197,7 @@ static int v4l2_flash_s_ctrl(struct v4l2_ctrl *c) { struct v4l2_flash *v4l2_flash = v4l2_ctrl_to_v4l2_flash(c); struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; - struct led_classdev *led_cdev = &fled_cdev->led_cdev; + struct led_classdev *led_cdev = fled_cdev ? &fled_cdev->led_cdev : NULL; struct v4l2_ctrl **ctrls = v4l2_flash->ctrls; bool external_strobe; int ret = 0; @@ -299,10 +299,26 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, struct v4l2_flash_ctrl_data *ctrl_init_data) { struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; - struct led_classdev *led_cdev = &fled_cdev->led_cdev; + struct led_classdev *led_cdev = fled_cdev ? &fled_cdev->led_cdev : NULL; struct v4l2_ctrl_config *ctrl_cfg; u32 mask; + /* Init INDICATOR_INTENSITY ctrl data */ + if (v4l2_flash->iled_cdev) { + ctrl_init_data[INDICATOR_INTENSITY].cid = + V4L2_CID_FLASH_INDICATOR_INTENSITY; + ctrl_cfg = &ctrl_init_data[INDICATOR_INTENSITY].config; + __lfs_to_v4l2_ctrl_config(&flash_cfg->intensity, + ctrl_cfg); + ctrl_cfg->id = V4L2_CID_FLASH_INDICATOR_INTENSITY; + ctrl_cfg->min = 0; + ctrl_cfg->flags = V4L2_CTRL_FLAG_VOLATILE | + V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + } + + if (!led_cdev || WARN_ON(!(led_cdev->flags & LED_DEV_CAP_FLASH))) + return; + /* Init FLASH_FAULT ctrl data */ if (flash_cfg->flash_faults) { ctrl_init_data[FLASH_FAULT].cid = V4L2_CID_FLASH_FAULT; @@ -330,27 +346,11 @@ static void __fill_ctrl_init_data(struct v4l2_flash *v4l2_flash, /* Init TORCH_INTENSITY ctrl data */ ctrl_init_data[TORCH_INTENSITY].cid = V4L2_CID_FLASH_TORCH_INTENSITY; ctrl_cfg = &ctrl_init_data[TORCH_INTENSITY].config; - __lfs_to_v4l2_ctrl_config(&flash_cfg->torch_intensity, ctrl_cfg); + __lfs_to_v4l2_ctrl_config(&flash_cfg->intensity, ctrl_cfg); ctrl_cfg->id = V4L2_CID_FLASH_TORCH_INTENSITY; ctrl_cfg->flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - /* Init INDICATOR_INTENSITY ctrl data */ - if (v4l2_flash->iled_cdev) { - ctrl_init_data[INDICATOR_INTENSITY].cid = - V4L2_CID_FLASH_INDICATOR_INTENSITY; - ctrl_cfg = &ctrl_init_data[INDICATOR_INTENSITY].config; - __lfs_to_v4l2_ctrl_config(&flash_cfg->indicator_intensity, - ctrl_cfg); - ctrl_cfg->id = V4L2_CID_FLASH_INDICATOR_INTENSITY; - ctrl_cfg->min = 0; - ctrl_cfg->flags = V4L2_CTRL_FLAG_VOLATILE | - V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - } - - if (!(led_cdev->flags & LED_DEV_CAP_FLASH)) - return; - /* Init FLASH_STROBE ctrl data */ ctrl_init_data[FLASH_STROBE].cid = V4L2_CID_FLASH_STROBE; ctrl_cfg = &ctrl_init_data[FLASH_STROBE].config; @@ -485,7 +485,9 @@ static int __sync_device_with_v4l2_controls(struct v4l2_flash *v4l2_flash) struct v4l2_ctrl **ctrls = v4l2_flash->ctrls; int ret = 0; - v4l2_flash_set_led_brightness(v4l2_flash, ctrls[TORCH_INTENSITY]); + if (ctrls[TORCH_INTENSITY]) + v4l2_flash_set_led_brightness(v4l2_flash, + ctrls[TORCH_INTENSITY]); if (ctrls[INDICATOR_INTENSITY]) v4l2_flash_set_led_brightness(v4l2_flash, @@ -527,19 +529,21 @@ static int v4l2_flash_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_flash *v4l2_flash = v4l2_subdev_to_v4l2_flash(sd); struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; - struct led_classdev *led_cdev = &fled_cdev->led_cdev; + struct led_classdev *led_cdev = fled_cdev ? &fled_cdev->led_cdev : NULL; struct led_classdev *led_cdev_ind = v4l2_flash->iled_cdev; int ret = 0; if (!v4l2_fh_is_singular(&fh->vfh)) return 0; - mutex_lock(&led_cdev->led_access); + if (led_cdev) { + mutex_lock(&led_cdev->led_access); - led_sysfs_disable(led_cdev); - led_trigger_remove(led_cdev); + led_sysfs_disable(led_cdev); + led_trigger_remove(led_cdev); - mutex_unlock(&led_cdev->led_access); + mutex_unlock(&led_cdev->led_access); + } if (led_cdev_ind) { mutex_lock(&led_cdev_ind->led_access); @@ -556,9 +560,11 @@ static int v4l2_flash_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; out_sync_device: - mutex_lock(&led_cdev->led_access); - led_sysfs_enable(led_cdev); - mutex_unlock(&led_cdev->led_access); + if (led_cdev) { + mutex_lock(&led_cdev->led_access); + led_sysfs_enable(led_cdev); + mutex_unlock(&led_cdev->led_access); + } if (led_cdev_ind) { mutex_lock(&led_cdev_ind->led_access); @@ -573,21 +579,24 @@ static int v4l2_flash_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_flash *v4l2_flash = v4l2_subdev_to_v4l2_flash(sd); struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev; - struct led_classdev *led_cdev = &fled_cdev->led_cdev; + struct led_classdev *led_cdev = fled_cdev ? &fled_cdev->led_cdev : NULL; struct led_classdev *led_cdev_ind = v4l2_flash->iled_cdev; int ret = 0; if (!v4l2_fh_is_singular(&fh->vfh)) return 0; - mutex_lock(&led_cdev->led_access); + if (led_cdev) { + mutex_lock(&led_cdev->led_access); - if (v4l2_flash->ctrls[STROBE_SOURCE]) - ret = v4l2_ctrl_s_ctrl(v4l2_flash->ctrls[STROBE_SOURCE], + if (v4l2_flash->ctrls[STROBE_SOURCE]) + ret = v4l2_ctrl_s_ctrl( + v4l2_flash->ctrls[STROBE_SOURCE], V4L2_FLASH_STROBE_SOURCE_SOFTWARE); - led_sysfs_enable(led_cdev); + led_sysfs_enable(led_cdev); - mutex_unlock(&led_cdev->led_access); + mutex_unlock(&led_cdev->led_access); + } if (led_cdev_ind) { mutex_lock(&led_cdev_ind->led_access); @@ -605,25 +614,19 @@ static const struct v4l2_subdev_internal_ops v4l2_flash_subdev_internal_ops = { static const struct v4l2_subdev_ops v4l2_flash_subdev_ops; -struct v4l2_flash *v4l2_flash_init( +static struct v4l2_flash *__v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, - struct led_classdev_flash *fled_cdev, - struct led_classdev *iled_cdev, - const struct v4l2_flash_ops *ops, - struct v4l2_flash_config *config) + struct led_classdev_flash *fled_cdev, struct led_classdev *iled_cdev, + const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config) { struct v4l2_flash *v4l2_flash; - struct led_classdev *led_cdev; struct v4l2_subdev *sd; int ret; - if (!fled_cdev || !config) + if (!config) return ERR_PTR(-EINVAL); - led_cdev = &fled_cdev->led_cdev; - - v4l2_flash = devm_kzalloc(led_cdev->dev, sizeof(*v4l2_flash), - GFP_KERNEL); + v4l2_flash = devm_kzalloc(dev, sizeof(*v4l2_flash), GFP_KERNEL); if (!v4l2_flash) return ERR_PTR(-ENOMEM); @@ -632,7 +635,7 @@ struct v4l2_flash *v4l2_flash_init( v4l2_flash->iled_cdev = iled_cdev; v4l2_flash->ops = ops; sd->dev = dev; - sd->fwnode = fwn ? fwn : dev_fwnode(led_cdev->dev); + sd->fwnode = fwn ? fwn : dev_fwnode(dev); v4l2_subdev_init(sd, &v4l2_flash_subdev_ops); sd->internal_ops = &v4l2_flash_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -664,8 +667,26 @@ err_init_controls: return ERR_PTR(ret); } + +struct v4l2_flash *v4l2_flash_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev_flash *fled_cdev, + const struct v4l2_flash_ops *ops, + struct v4l2_flash_config *config) +{ + return __v4l2_flash_init(dev, fwn, fled_cdev, NULL, ops, config); +} EXPORT_SYMBOL_GPL(v4l2_flash_init); +struct v4l2_flash *v4l2_flash_indicator_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev *iled_cdev, + struct v4l2_flash_config *config) +{ + return __v4l2_flash_init(dev, fwn, NULL, iled_cdev, NULL, config); +} +EXPORT_SYMBOL_GPL(v4l2_flash_indicator_init); + void v4l2_flash_release(struct v4l2_flash *v4l2_flash) { struct v4l2_subdev *sd; diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index 81469d087e74..3f4148c92308 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -58,6 +58,7 @@ struct gb_light { bool ready; #if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS) struct v4l2_flash *v4l2_flash; + struct v4l2_flash *v4l2_flash_ind; #endif }; @@ -534,7 +535,7 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) { struct gb_connection *connection = get_conn_from_light(light); struct device *dev = &connection->bundle->dev; - struct v4l2_flash_config sd_cfg = { {0} }; + struct v4l2_flash_config sd_cfg = { {0} }, sd_cfg_ind = { {0} }; struct led_classdev_flash *fled; struct led_classdev *iled = NULL; struct gb_channel *channel_torch, *channel_ind, *channel_flash; @@ -542,12 +543,12 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH); if (channel_torch) __gb_lights_channel_v4l2_config(&channel_torch->intensity_uA, - &sd_cfg.torch_intensity); + &sd_cfg.intensity); channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR); if (channel_ind) { __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA, - &sd_cfg.indicator_intensity); + &sd_cfg_ind.intensity); iled = &channel_ind->fled.led_cdev; } @@ -557,6 +558,8 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) fled = &channel_flash->fled; snprintf(sd_cfg.dev_name, sizeof(sd_cfg.dev_name), "%s", light->name); + snprintf(sd_cfg_ind.dev_name, sizeof(sd_cfg_ind.dev_name), + "%s indicator", light->name); /* Set the possible values to faults, in our case all faults */ sd_cfg.flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT | @@ -565,16 +568,26 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE | LED_FAULT_LED_OVER_TEMPERATURE; - light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, iled, - &v4l2_flash_ops, &sd_cfg); + light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, &v4l2_flash_ops, + &sd_cfg); if (IS_ERR(light->v4l2_flash)) return PTR_ERR(light->v4l2_flash); + if (channel_ind) { + light->v4l2_flash_ind = + v4l2_flash_indicator_init(dev, NULL, iled, &sd_cfg_ind); + if (IS_ERR(light->v4l2_flash_ind)) { + v4l2_flash_release(light->v4l2_flash); + return PTR_ERR(light->v4l2_flash_ind); + } + } + return 0; } static void gb_lights_light_v4l2_unregister(struct gb_light *light) { + v4l2_flash_release(light->v4l2_flash_ind); v4l2_flash_release(light->v4l2_flash); } #else diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h index 54e31a805a88..1b515166ad60 100644 --- a/include/media/v4l2-flash-led-class.h +++ b/include/media/v4l2-flash-led-class.h @@ -56,8 +56,7 @@ struct v4l2_flash_ops { * struct v4l2_flash_config - V4L2 Flash sub-device initialization data * @dev_name: the name of the media entity, * unique in the system - * @torch_intensity: constraints for the LED in torch mode - * @indicator_intensity: constraints for the indicator LED + * @intensity: non-flash strobe constraints for the LED * @flash_faults: bitmask of flash faults that the LED flash class * device can report; corresponding LED_FAULT* bit * definitions are available in the header file @@ -66,8 +65,7 @@ struct v4l2_flash_ops { */ struct v4l2_flash_config { char dev_name[32]; - struct led_flash_setting torch_intensity; - struct led_flash_setting indicator_intensity; + struct led_flash_setting intensity; u32 flash_faults; unsigned int has_external_strobe:1; }; @@ -110,8 +108,6 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c) * @dev: flash device, e.g. an I2C device * @fwn: fwnode_handle of the LED, may be NULL if the same as device's * @fled_cdev: LED flash class device to wrap - * @iled_cdev: LED flash class device representing indicator LED associated - * with fled_cdev, may be NULL * @ops: V4L2 Flash device ops * @config: initialization data for V4L2 Flash sub-device * @@ -124,9 +120,24 @@ static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c) struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev *iled_cdev, - const struct v4l2_flash_ops *ops, - struct v4l2_flash_config *config); + const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config); + +/** + * v4l2_flash_indicator_init - initialize V4L2 indicator sub-device + * @dev: flash device, e.g. an I2C device + * @fwn: fwnode_handle of the LED, may be NULL if the same as device's + * @iled_cdev: LED flash class device representing the indicator LED + * @config: initialization data for V4L2 Flash sub-device + * + * Create V4L2 Flash sub-device wrapping given LED subsystem device. + * + * Returns: A valid pointer, or, when an error occurs, the return + * value is encoded using ERR_PTR(). Use IS_ERR() to check and + * PTR_ERR() to obtain the numeric return value. + */ +struct v4l2_flash *v4l2_flash_indicator_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev *iled_cdev, struct v4l2_flash_config *config); /** * v4l2_flash_release - release V4L2 Flash sub-device @@ -140,9 +151,14 @@ void v4l2_flash_release(struct v4l2_flash *v4l2_flash); static inline struct v4l2_flash *v4l2_flash_init( struct device *dev, struct fwnode_handle *fwn, struct led_classdev_flash *fled_cdev, - struct led_classdev *iled_cdev, - const struct v4l2_flash_ops *ops, - struct v4l2_flash_config *config) + const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config) +{ + return NULL; +} + +static inline struct v4l2_flash *v4l2_flash_indicator_init( + struct device *dev, struct fwnode_handle *fwn, + struct led_classdev *iled_cdev, struct v4l2_flash_config *config) { return NULL; } -- cgit v1.2.3 From a56ba8fbcb55f3c5fc06f803469e7412f9e13c18 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 26 Apr 2015 17:56:54 -0400 Subject: media: leds: as3645a: Add LED flash class driver Add a LED flash class driver for the as3654a flash controller. A V4L2 flash driver for it already exists (drivers/media/i2c/as3645a.c), and this driver is based on that. Signed-off-by: Sakari Ailus Acked-by: Jacek Anaszewski Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 6 + drivers/leds/Kconfig | 8 + drivers/leds/Makefile | 1 + drivers/leds/leds-as3645a.c | 763 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 778 insertions(+) create mode 100644 drivers/leds/leds-as3645a.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index af94fff63da8..eb930ebecfcb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2123,6 +2123,12 @@ S: Maintained F: arch/arm64/ F: Documentation/arm64/ +AS3645A LED FLASH CONTROLLER DRIVER +M: Sakari Ailus +L: linux-leds@vger.kernel.org +S: Maintained +F: drivers/leds/leds-as3645a.c + AS3645A LED FLASH CONTROLLER DRIVER M: Laurent Pinchart L: linux-media@vger.kernel.org diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 594b24d410c3..bad3a4098104 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -58,6 +58,14 @@ config LEDS_AAT1290 help This option enables support for the LEDs on the AAT1290. +config LEDS_AS3645A + tristate "AS3645A LED flash controller support" + depends on I2C && LEDS_CLASS_FLASH + help + Enable LED flash class support for AS3645A LED flash + controller. V4L2 flash API is provided as well if + CONFIG_V4L2_FLASH_API is enabled. + config LEDS_BCM6328 tristate "LED Support for Broadcom BCM6328" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 909dae62ba05..7d7b26552923 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o # LED Platform Drivers obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o obj-$(CONFIG_LEDS_AAT1290) += leds-aat1290.o +obj-$(CONFIG_LEDS_AS3645A) += leds-as3645a.o obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c new file mode 100644 index 000000000000..bbbbe0898233 --- /dev/null +++ b/drivers/leds/leds-as3645a.c @@ -0,0 +1,763 @@ +/* + * drivers/leds/leds-as3645a.c - AS3645A and LM3555 flash controllers driver + * + * Copyright (C) 2008-2011 Nokia Corporation + * Copyright (c) 2011, 2017 Intel Corporation. + * + * Based on drivers/media/i2c/as3645a.c. + * + * Contact: Sakari Ailus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define AS_TIMER_US_TO_CODE(t) (((t) / 1000 - 100) / 50) +#define AS_TIMER_CODE_TO_US(c) ((50 * (c) + 100) * 1000) + +/* Register definitions */ + +/* Read-only Design info register: Reset state: xxxx 0001 */ +#define AS_DESIGN_INFO_REG 0x00 +#define AS_DESIGN_INFO_FACTORY(x) (((x) >> 4)) +#define AS_DESIGN_INFO_MODEL(x) ((x) & 0x0f) + +/* Read-only Version control register: Reset state: 0000 0000 + * for first engineering samples + */ +#define AS_VERSION_CONTROL_REG 0x01 +#define AS_VERSION_CONTROL_RFU(x) (((x) >> 4)) +#define AS_VERSION_CONTROL_VERSION(x) ((x) & 0x0f) + +/* Read / Write (Indicator and timer register): Reset state: 0000 1111 */ +#define AS_INDICATOR_AND_TIMER_REG 0x02 +#define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT 0 +#define AS_INDICATOR_AND_TIMER_VREF_SHIFT 4 +#define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT 6 + +/* Read / Write (Current set register): Reset state: 0110 1001 */ +#define AS_CURRENT_SET_REG 0x03 +#define AS_CURRENT_ASSIST_LIGHT_SHIFT 0 +#define AS_CURRENT_LED_DET_ON (1 << 3) +#define AS_CURRENT_FLASH_CURRENT_SHIFT 4 + +/* Read / Write (Control register): Reset state: 1011 0100 */ +#define AS_CONTROL_REG 0x04 +#define AS_CONTROL_MODE_SETTING_SHIFT 0 +#define AS_CONTROL_STROBE_ON (1 << 2) +#define AS_CONTROL_OUT_ON (1 << 3) +#define AS_CONTROL_EXT_TORCH_ON (1 << 4) +#define AS_CONTROL_STROBE_TYPE_EDGE (0 << 5) +#define AS_CONTROL_STROBE_TYPE_LEVEL (1 << 5) +#define AS_CONTROL_COIL_PEAK_SHIFT 6 + +/* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */ +#define AS_FAULT_INFO_REG 0x05 +#define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT (1 << 1) +#define AS_FAULT_INFO_INDICATOR_LED (1 << 2) +#define AS_FAULT_INFO_LED_AMOUNT (1 << 3) +#define AS_FAULT_INFO_TIMEOUT (1 << 4) +#define AS_FAULT_INFO_OVER_TEMPERATURE (1 << 5) +#define AS_FAULT_INFO_SHORT_CIRCUIT (1 << 6) +#define AS_FAULT_INFO_OVER_VOLTAGE (1 << 7) + +/* Boost register */ +#define AS_BOOST_REG 0x0d +#define AS_BOOST_CURRENT_DISABLE (0 << 0) +#define AS_BOOST_CURRENT_ENABLE (1 << 0) + +/* Password register is used to unlock boost register writing */ +#define AS_PASSWORD_REG 0x0f +#define AS_PASSWORD_UNLOCK_VALUE 0x55 + +#define AS_NAME "as3645a" +#define AS_I2C_ADDR (0x60 >> 1) /* W:0x60, R:0x61 */ + +#define AS_FLASH_TIMEOUT_MIN 100000 /* us */ +#define AS_FLASH_TIMEOUT_MAX 850000 +#define AS_FLASH_TIMEOUT_STEP 50000 + +#define AS_FLASH_INTENSITY_MIN 200000 /* uA */ +#define AS_FLASH_INTENSITY_MAX_1LED 500000 +#define AS_FLASH_INTENSITY_MAX_2LEDS 400000 +#define AS_FLASH_INTENSITY_STEP 20000 + +#define AS_TORCH_INTENSITY_MIN 20000 /* uA */ +#define AS_TORCH_INTENSITY_MAX 160000 +#define AS_TORCH_INTENSITY_STEP 20000 + +#define AS_INDICATOR_INTENSITY_MIN 0 /* uA */ +#define AS_INDICATOR_INTENSITY_MAX 10000 +#define AS_INDICATOR_INTENSITY_STEP 2500 + +#define AS_PEAK_mA_MAX 2000 +#define AS_PEAK_mA_TO_REG(a) \ + ((min_t(u32, AS_PEAK_mA_MAX, a) - 1250) / 250) + +enum as_mode { + AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT, + AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT, + AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT, + AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT, +}; + +struct as3645a_config { + u32 flash_timeout_us; + u32 flash_max_ua; + u32 assist_max_ua; + u32 indicator_max_ua; + u32 voltage_reference; + u32 peak; +}; + +struct as3645a_names { + char flash[32]; + char indicator[32]; +}; + +struct as3645a { + struct i2c_client *client; + + struct mutex mutex; + + struct led_classdev_flash fled; + struct led_classdev iled_cdev; + + struct v4l2_flash *vf; + struct v4l2_flash *vfind; + + struct device_node *flash_node; + struct device_node *indicator_node; + + struct as3645a_config cfg; + + enum as_mode mode; + unsigned int timeout; + unsigned int flash_current; + unsigned int assist_current; + unsigned int indicator_current; + enum v4l2_flash_strobe_source strobe_source; +}; + +#define fled_to_as3645a(__fled) container_of(__fled, struct as3645a, fled) +#define iled_cdev_to_as3645a(__iled_cdev) \ + container_of(__iled_cdev, struct as3645a, iled_cdev) + +/* Return negative errno else zero on success */ +static int as3645a_write(struct as3645a *flash, u8 addr, u8 val) +{ + struct i2c_client *client = flash->client; + int rval; + + rval = i2c_smbus_write_byte_data(client, addr, val); + + dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val, + rval < 0 ? "fail" : "ok"); + + return rval; +} + +/* Return negative errno else a data byte received from the device. */ +static int as3645a_read(struct as3645a *flash, u8 addr) +{ + struct i2c_client *client = flash->client; + int rval; + + rval = i2c_smbus_read_byte_data(client, addr); + + dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval, + rval < 0 ? "fail" : "ok"); + + return rval; +} + +/* ----------------------------------------------------------------------------- + * Hardware configuration and trigger + */ + +/** + * as3645a_set_config - Set flash configuration registers + * @flash: The flash + * + * Configure the hardware with flash, assist and indicator currents, as well as + * flash timeout. + * + * Return 0 on success, or a negative error code if an I2C communication error + * occurred. + */ +static int as3645a_set_current(struct as3645a *flash) +{ + u8 val; + + val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT) + | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT) + | AS_CURRENT_LED_DET_ON; + + return as3645a_write(flash, AS_CURRENT_SET_REG, val); +} + +static int as3645a_set_timeout(struct as3645a *flash) +{ + u8 val; + + val = flash->timeout << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT; + + val |= (flash->cfg.voltage_reference + << AS_INDICATOR_AND_TIMER_VREF_SHIFT) + | ((flash->indicator_current ? flash->indicator_current - 1 : 0) + << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT); + + return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val); +} + +/** + * as3645a_set_control - Set flash control register + * @flash: The flash + * @mode: Desired output mode + * @on: Desired output state + * + * Configure the hardware with output mode and state. + * + * Return 0 on success, or a negative error code if an I2C communication error + * occurred. + */ +static int +as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on) +{ + u8 reg; + + /* Configure output parameters and operation mode. */ + reg = (flash->cfg.peak << AS_CONTROL_COIL_PEAK_SHIFT) + | (on ? AS_CONTROL_OUT_ON : 0) + | mode; + + if (mode == AS_MODE_FLASH && + flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) + reg |= AS_CONTROL_STROBE_TYPE_LEVEL + | AS_CONTROL_STROBE_ON; + + return as3645a_write(flash, AS_CONTROL_REG, reg); +} + +static int as3645a_get_fault(struct led_classdev_flash *fled, u32 *fault) +{ + struct as3645a *flash = fled_to_as3645a(fled); + int rval; + + /* NOTE: reading register clears fault status */ + rval = as3645a_read(flash, AS_FAULT_INFO_REG); + if (rval < 0) + return rval; + + if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT) + *fault |= LED_FAULT_OVER_CURRENT; + + if (rval & AS_FAULT_INFO_INDICATOR_LED) + *fault |= LED_FAULT_INDICATOR; + + dev_dbg(&flash->client->dev, "%u connected LEDs\n", + rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1); + + if (rval & AS_FAULT_INFO_TIMEOUT) + *fault |= LED_FAULT_TIMEOUT; + + if (rval & AS_FAULT_INFO_OVER_TEMPERATURE) + *fault |= LED_FAULT_OVER_TEMPERATURE; + + if (rval & AS_FAULT_INFO_SHORT_CIRCUIT) + *fault |= LED_FAULT_OVER_CURRENT; + + if (rval & AS_FAULT_INFO_OVER_VOLTAGE) + *fault |= LED_FAULT_INPUT_VOLTAGE; + + return rval; +} + +static unsigned int __as3645a_current_to_reg(unsigned int min, unsigned int max, + unsigned int step, + unsigned int val) +{ + if (val < min) + val = min; + + if (val > max) + val = max; + + return (val - min) / step; +} + +static unsigned int as3645a_current_to_reg(struct as3645a *flash, bool is_flash, + unsigned int ua) +{ + if (is_flash) + return __as3645a_current_to_reg(AS_TORCH_INTENSITY_MIN, + flash->cfg.assist_max_ua, + AS_TORCH_INTENSITY_STEP, ua); + else + return __as3645a_current_to_reg(AS_FLASH_INTENSITY_MIN, + flash->cfg.flash_max_ua, + AS_FLASH_INTENSITY_STEP, ua); +} + +static int as3645a_set_indicator_brightness(struct led_classdev *iled_cdev, + enum led_brightness brightness) +{ + struct as3645a *flash = iled_cdev_to_as3645a(iled_cdev); + int rval; + + flash->indicator_current = brightness; + + rval = as3645a_set_timeout(flash); + if (rval) + return rval; + + return as3645a_set_control(flash, AS_MODE_INDICATOR, brightness); +} + +static int as3645a_set_assist_brightness(struct led_classdev *fled_cdev, + enum led_brightness brightness) +{ + struct led_classdev_flash *fled = lcdev_to_flcdev(fled_cdev); + struct as3645a *flash = fled_to_as3645a(fled); + int rval; + + if (brightness) { + /* Register value 0 is 20 mA. */ + flash->assist_current = brightness - 1; + + rval = as3645a_set_current(flash); + if (rval) + return rval; + } + + return as3645a_set_control(flash, AS_MODE_ASSIST, brightness); +} + +static int as3645a_set_flash_brightness(struct led_classdev_flash *fled, + u32 brightness_ua) +{ + struct as3645a *flash = fled_to_as3645a(fled); + + flash->flash_current = as3645a_current_to_reg(flash, true, brightness_ua); + + return as3645a_set_current(flash); +} + +static int as3645a_set_flash_timeout(struct led_classdev_flash *fled, + u32 timeout_us) +{ + struct as3645a *flash = fled_to_as3645a(fled); + + flash->timeout = AS_TIMER_US_TO_CODE(timeout_us); + + return as3645a_set_timeout(flash); +} + +static int as3645a_set_strobe(struct led_classdev_flash *fled, bool state) +{ + struct as3645a *flash = fled_to_as3645a(fled); + + return as3645a_set_control(flash, AS_MODE_FLASH, state); +} + +static const struct led_flash_ops as3645a_led_flash_ops = { + .flash_brightness_set = as3645a_set_flash_brightness, + .timeout_set = as3645a_set_flash_timeout, + .strobe_set = as3645a_set_strobe, + .fault_get = as3645a_get_fault, +}; + +static int as3645a_setup(struct as3645a *flash) +{ + struct device *dev = &flash->client->dev; + u32 fault = 0; + int rval; + + /* clear errors */ + rval = as3645a_read(flash, AS_FAULT_INFO_REG); + if (rval < 0) + return rval; + + dev_dbg(dev, "Fault info: %02x\n", rval); + + rval = as3645a_set_current(flash); + if (rval < 0) + return rval; + + rval = as3645a_set_timeout(flash); + if (rval < 0) + return rval; + + rval = as3645a_set_control(flash, AS_MODE_INDICATOR, false); + if (rval < 0) + return rval; + + /* read status */ + rval = as3645a_get_fault(&flash->fled, &fault); + if (rval < 0) + return rval; + + dev_dbg(dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n", + as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG)); + dev_dbg(dev, "AS_CURRENT_SET_REG: %02x\n", + as3645a_read(flash, AS_CURRENT_SET_REG)); + dev_dbg(dev, "AS_CONTROL_REG: %02x\n", + as3645a_read(flash, AS_CONTROL_REG)); + + return rval & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0; +} + +static int as3645a_detect(struct as3645a *flash) +{ + struct device *dev = &flash->client->dev; + int rval, man, model, rfu, version; + const char *vendor; + + rval = as3645a_read(flash, AS_DESIGN_INFO_REG); + if (rval < 0) { + dev_err(dev, "can't read design info reg\n"); + return rval; + } + + man = AS_DESIGN_INFO_FACTORY(rval); + model = AS_DESIGN_INFO_MODEL(rval); + + rval = as3645a_read(flash, AS_VERSION_CONTROL_REG); + if (rval < 0) { + dev_err(dev, "can't read version control reg\n"); + return rval; + } + + rfu = AS_VERSION_CONTROL_RFU(rval); + version = AS_VERSION_CONTROL_VERSION(rval); + + /* Verify the chip model and version. */ + if (model != 0x01 || rfu != 0x00) { + dev_err(dev, "AS3645A not detected " + "(model %d rfu %d)\n", model, rfu); + return -ENODEV; + } + + switch (man) { + case 1: + vendor = "AMS, Austria Micro Systems"; + break; + case 2: + vendor = "ADI, Analog Devices Inc."; + break; + case 3: + vendor = "NSC, National Semiconductor"; + break; + case 4: + vendor = "NXP"; + break; + case 5: + vendor = "TI, Texas Instrument"; + break; + default: + vendor = "Unknown"; + } + + dev_info(dev, "Chip vendor: %s (%d) Version: %d\n", vendor, + man, version); + + rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE); + if (rval < 0) + return rval; + + return as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE); +} + +static int as3645a_parse_node(struct as3645a *flash, + struct as3645a_names *names, + struct device_node *node) +{ + struct as3645a_config *cfg = &flash->cfg; + const char *name; + int rval; + + flash->flash_node = of_get_child_by_name(node, "flash"); + if (!flash->flash_node) { + dev_err(&flash->client->dev, "can't find flash node\n"); + return -ENODEV; + } + + rval = of_property_read_string(flash->flash_node, "label", &name); + if (!rval) + strlcpy(names->flash, name, sizeof(names->flash)); + else + snprintf(names->flash, sizeof(names->flash), + "%s:flash", node->name); + + rval = of_property_read_u32(flash->flash_node, "flash-timeout-us", + &cfg->flash_timeout_us); + if (rval < 0) { + dev_err(&flash->client->dev, + "can't read flash-timeout-us property for flash\n"); + goto out_err; + } + + rval = of_property_read_u32(flash->flash_node, "flash-max-microamp", + &cfg->flash_max_ua); + if (rval < 0) { + dev_err(&flash->client->dev, + "can't read flash-max-microamp property for flash\n"); + goto out_err; + } + + rval = of_property_read_u32(flash->flash_node, "led-max-microamp", + &cfg->assist_max_ua); + if (rval < 0) { + dev_err(&flash->client->dev, + "can't read led-max-microamp property for flash\n"); + goto out_err; + } + + of_property_read_u32(flash->flash_node, "voltage-reference", + &cfg->voltage_reference); + + of_property_read_u32(flash->flash_node, "peak-current-limit", + &cfg->peak); + cfg->peak = AS_PEAK_mA_TO_REG(cfg->peak); + + flash->indicator_node = of_get_child_by_name(node, "indicator"); + if (!flash->indicator_node) { + dev_warn(&flash->client->dev, + "can't find indicator node\n"); + goto out_err; + } + + rval = of_property_read_string(flash->indicator_node, "label", &name); + if (!rval) + strlcpy(names->indicator, name, sizeof(names->indicator)); + else + snprintf(names->indicator, sizeof(names->indicator), + "%s:indicator", node->name); + + rval = of_property_read_u32(flash->indicator_node, "led-max-microamp", + &cfg->indicator_max_ua); + if (rval < 0) { + dev_err(&flash->client->dev, + "can't read led-max-microamp property for indicator\n"); + goto out_err; + } + + return 0; + +out_err: + of_node_put(flash->flash_node); + of_node_put(flash->indicator_node); + + return rval; +} + +static int as3645a_led_class_setup(struct as3645a *flash, + struct as3645a_names *names) +{ + struct led_classdev *fled_cdev = &flash->fled.led_cdev; + struct led_classdev *iled_cdev = &flash->iled_cdev; + struct led_flash_setting *cfg; + int rval; + + iled_cdev->name = names->indicator; + iled_cdev->brightness_set_blocking = as3645a_set_indicator_brightness; + iled_cdev->max_brightness = + flash->cfg.indicator_max_ua / AS_INDICATOR_INTENSITY_STEP; + iled_cdev->flags = LED_CORE_SUSPENDRESUME; + + rval = led_classdev_register(&flash->client->dev, iled_cdev); + if (rval < 0) + return rval; + + cfg = &flash->fled.brightness; + cfg->min = AS_FLASH_INTENSITY_MIN; + cfg->max = flash->cfg.flash_max_ua; + cfg->step = AS_FLASH_INTENSITY_STEP; + cfg->val = flash->cfg.flash_max_ua; + + cfg = &flash->fled.timeout; + cfg->min = AS_FLASH_TIMEOUT_MIN; + cfg->max = flash->cfg.flash_timeout_us; + cfg->step = AS_FLASH_TIMEOUT_STEP; + cfg->val = flash->cfg.flash_timeout_us; + + flash->fled.ops = &as3645a_led_flash_ops; + + fled_cdev->name = names->flash; + fled_cdev->brightness_set_blocking = as3645a_set_assist_brightness; + /* Value 0 is off in LED class. */ + fled_cdev->max_brightness = + as3645a_current_to_reg(flash, false, + flash->cfg.assist_max_ua) + 1; + fled_cdev->flags = LED_DEV_CAP_FLASH | LED_CORE_SUSPENDRESUME; + + rval = led_classdev_flash_register(&flash->client->dev, &flash->fled); + if (rval) { + led_classdev_unregister(iled_cdev); + dev_err(&flash->client->dev, + "led_classdev_flash_register() failed, error %d\n", + rval); + } + + return rval; +} + +static int as3645a_v4l2_setup(struct as3645a *flash) +{ + struct led_classdev_flash *fled = &flash->fled; + struct led_classdev *led = &fled->led_cdev; + struct v4l2_flash_config cfg = { + .intensity = { + .min = AS_TORCH_INTENSITY_MIN, + .max = flash->cfg.assist_max_ua, + .step = AS_TORCH_INTENSITY_STEP, + .val = flash->cfg.assist_max_ua, + }, + }; + struct v4l2_flash_config cfgind = { + .intensity = { + .min = AS_INDICATOR_INTENSITY_MIN, + .max = flash->cfg.indicator_max_ua, + .step = AS_INDICATOR_INTENSITY_STEP, + .val = flash->cfg.indicator_max_ua, + }, + }; + + strlcpy(cfg.dev_name, led->name, sizeof(cfg.dev_name)); + strlcpy(cfgind.dev_name, flash->iled_cdev.name, sizeof(cfg.dev_name)); + + flash->vf = v4l2_flash_init( + &flash->client->dev, of_fwnode_handle(flash->flash_node), + &flash->fled, NULL, &cfg); + if (IS_ERR(flash->vf)) + return PTR_ERR(flash->vf); + + flash->vfind = v4l2_flash_indicator_init( + &flash->client->dev, of_fwnode_handle(flash->indicator_node), + &flash->iled_cdev, &cfgind); + if (IS_ERR(flash->vfind)) { + v4l2_flash_release(flash->vf); + return PTR_ERR(flash->vfind); + } + + return 0; +} + +static int as3645a_probe(struct i2c_client *client) +{ + struct as3645a_names names; + struct as3645a *flash; + int rval; + + if (client->dev.of_node == NULL) + return -ENODEV; + + flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); + if (flash == NULL) + return -ENOMEM; + + flash->client = client; + + rval = as3645a_parse_node(flash, &names, client->dev.of_node); + if (rval < 0) + return rval; + + rval = as3645a_detect(flash); + if (rval < 0) + goto out_put_nodes; + + mutex_init(&flash->mutex); + i2c_set_clientdata(client, flash); + + rval = as3645a_setup(flash); + if (rval) + goto out_mutex_destroy; + + rval = as3645a_led_class_setup(flash, &names); + if (rval) + goto out_mutex_destroy; + + rval = as3645a_v4l2_setup(flash); + if (rval) + goto out_led_classdev_flash_unregister; + + return 0; + +out_led_classdev_flash_unregister: + led_classdev_flash_unregister(&flash->fled); + +out_mutex_destroy: + mutex_destroy(&flash->mutex); + +out_put_nodes: + of_node_put(flash->flash_node); + of_node_put(flash->indicator_node); + + return rval; +} + +static int as3645a_remove(struct i2c_client *client) +{ + struct as3645a *flash = i2c_get_clientdata(client); + + as3645a_set_control(flash, AS_MODE_EXT_TORCH, false); + + v4l2_flash_release(flash->vf); + + led_classdev_flash_unregister(&flash->fled); + led_classdev_unregister(&flash->iled_cdev); + + mutex_destroy(&flash->mutex); + + of_node_put(flash->flash_node); + of_node_put(flash->indicator_node); + + return 0; +} + +static const struct i2c_device_id as3645a_id_table[] = { + { AS_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, as3645a_id_table); + +static const struct of_device_id as3645a_of_table[] = { + { .compatible = "ams,as3645a" }, + { }, +}; +MODULE_DEVICE_TABLE(of, as3645a_of_table); + +static struct i2c_driver as3645a_i2c_driver = { + .driver = { + .of_match_table = as3645a_of_table, + .name = AS_NAME, + }, + .probe_new = as3645a_probe, + .remove = as3645a_remove, + .id_table = as3645a_id_table, +}; + +module_i2c_driver(as3645a_i2c_driver); + +MODULE_AUTHOR("Laurent Pinchart "); +MODULE_AUTHOR("Sakari Ailus "); +MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 4a3039e26eba2f25cf66cb0f4b30e17a6ab13511 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 7 Aug 2017 06:51:47 -0400 Subject: media: staging: atomisp: imx: remove dead code Making some functions 'static' has uncovered a few functions that have no caller, through the gcc warnings: atomisp/i2c/imx/imx.c:1111:12: error: 'imx_t_focus_vcm' defined but not used [-Werror=unused-function] atomisp/i2c/imx/imx.c:1103:12: error: 'imx_vcm_init' defined but not used [-Werror=unused-function] atomisp/i2c/imx/imx.c:1095:12: error: 'imx_vcm_power_down' defined but not used [-Werror=unused-function] atomisp/i2c/imx/imx.c:1087:12: error: 'imx_vcm_power_up' defined but not used [-Werror=unused-function] All four of these can be removed. Since they call indirect functions, I also looked at how those are used in turn: - The power_up/power_down callbacks are called from other functions and are still needed. - The t_focus_vcm callbacks pointers are completely unused and can be removed in both imx and ov8858. Some of the handlers are called directly and can now be marked static, the others are dummy implemntations that we can remove. - vcm_init is unused in imx, but dw9718_vcm_init is used in ov8858, but is not used in imx, so that one needs to stay around. The callback pointers in imx can be removed. Fixes: 9a5a6911aa3f ("staging: imx: fix non-static declarations") Signed-off-by: Arnd Bergmann Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/imx/ad5816g.c | 11 +------- drivers/staging/media/atomisp/i2c/imx/drv201.c | 11 +------- drivers/staging/media/atomisp/i2c/imx/dw9714.c | 14 +--------- drivers/staging/media/atomisp/i2c/imx/dw9718.c | 5 ---- drivers/staging/media/atomisp/i2c/imx/dw9719.c | 11 -------- drivers/staging/media/atomisp/i2c/imx/imx.c | 32 ----------------------- drivers/staging/media/atomisp/i2c/imx/imx.h | 29 -------------------- drivers/staging/media/atomisp/i2c/ov5693/ov5693.c | 2 +- drivers/staging/media/atomisp/i2c/ov8858.h | 3 --- drivers/staging/media/atomisp/i2c/ov8858_btns.h | 3 --- 10 files changed, 4 insertions(+), 117 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/imx/ad5816g.c b/drivers/staging/media/atomisp/i2c/imx/ad5816g.c index d68ebb49f002..558dcdf135d9 100644 --- a/drivers/staging/media/atomisp/i2c/imx/ad5816g.c +++ b/drivers/staging/media/atomisp/i2c/imx/ad5816g.c @@ -136,7 +136,7 @@ int ad5816g_vcm_power_down(struct v4l2_subdev *sd) } -int ad5816g_t_focus_vcm(struct v4l2_subdev *sd, u16 val) +static int ad5816g_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); u16 data = val & VCM_CODE_MASK; @@ -214,12 +214,3 @@ int ad5816g_t_vcm_timing(struct v4l2_subdev *sd, s32 value) { return 0; } - -int ad5816g_vcm_init(struct v4l2_subdev *sd) -{ - ad5816g_dev.platform_data = camera_get_af_platform_data(); - return (NULL == ad5816g_dev.platform_data) ? -ENODEV : 0; - -} - - diff --git a/drivers/staging/media/atomisp/i2c/imx/drv201.c b/drivers/staging/media/atomisp/i2c/imx/drv201.c index 915e4019cfeb..6d9d4c968722 100644 --- a/drivers/staging/media/atomisp/i2c/imx/drv201.c +++ b/drivers/staging/media/atomisp/i2c/imx/drv201.c @@ -128,7 +128,7 @@ int drv201_vcm_power_down(struct v4l2_subdev *sd) } -int drv201_t_focus_vcm(struct v4l2_subdev *sd, u16 val) +static int drv201_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); u16 data = val & VCM_CODE_MASK; @@ -207,12 +207,3 @@ int drv201_t_vcm_timing(struct v4l2_subdev *sd, s32 value) { return 0; } - -int drv201_vcm_init(struct v4l2_subdev *sd) -{ - drv201_dev.platform_data = camera_get_af_platform_data(); - return (NULL == drv201_dev.platform_data) ? -ENODEV : 0; -} - - - diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9714.c b/drivers/staging/media/atomisp/i2c/imx/dw9714.c index b7dee1b6bb37..6397a7ee0af6 100644 --- a/drivers/staging/media/atomisp/i2c/imx/dw9714.c +++ b/drivers/staging/media/atomisp/i2c/imx/dw9714.c @@ -56,7 +56,7 @@ int dw9714_vcm_power_down(struct v4l2_subdev *sd) } -int dw9714_t_focus_vcm(struct v4l2_subdev *sd, u16 val) +static int dw9714_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = -EINVAL; @@ -221,15 +221,3 @@ int dw9714_t_vcm_timing(struct v4l2_subdev *sd, s32 value) return 0; } - -int dw9714_vcm_init(struct v4l2_subdev *sd) -{ - - /* set VCM to home position and vcm mode to direct*/ - dw9714_dev.vcm_mode = DW9714_DIRECT; - dw9714_dev.vcm_settings.update = false; - dw9714_dev.platform_data = camera_get_af_platform_data(); - return (NULL == dw9714_dev.platform_data) ? -ENODEV : 0; - -} - diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9718.c b/drivers/staging/media/atomisp/i2c/imx/dw9718.c index 65a1fcf187d5..c02b9f0a2440 100644 --- a/drivers/staging/media/atomisp/i2c/imx/dw9718.c +++ b/drivers/staging/media/atomisp/i2c/imx/dw9718.c @@ -204,11 +204,6 @@ int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value) return 0; } -int dw9718_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - return -EINVAL; -} - int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value) { return dw9718_t_focus_abs(sd, dw9718_dev.focus + value); diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9719.c b/drivers/staging/media/atomisp/i2c/imx/dw9719.c index eca2d7640030..565237796bb4 100644 --- a/drivers/staging/media/atomisp/i2c/imx/dw9719.c +++ b/drivers/staging/media/atomisp/i2c/imx/dw9719.c @@ -161,11 +161,6 @@ int dw9719_q_focus_status(struct v4l2_subdev *sd, s32 *value) return 0; } -int dw9719_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - return -EINVAL; -} - int dw9719_t_focus_abs(struct v4l2_subdev *sd, s32 value) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -201,9 +196,3 @@ int dw9719_t_vcm_timing(struct v4l2_subdev *sd, s32 value) { return 0; } - -int dw9719_vcm_init(struct v4l2_subdev *sd) -{ - dw9719_dev.platform_data = camera_get_af_platform_data(); - return (NULL == dw9719_dev.platform_data) ? -ENODEV : 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.c b/drivers/staging/media/atomisp/i2c/imx/imx.c index fb32cb2f2dd1..49ab0af87096 100644 --- a/drivers/staging/media/atomisp/i2c/imx/imx.c +++ b/drivers/staging/media/atomisp/i2c/imx/imx.c @@ -1084,38 +1084,6 @@ static int imx_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val) return 0; } -static int imx_vcm_power_up(struct v4l2_subdev *sd) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->power_up) - return dev->vcm_driver->power_up(sd); - return 0; -} - -static int imx_vcm_power_down(struct v4l2_subdev *sd) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->power_down) - return dev->vcm_driver->power_down(sd); - return 0; -} - -static int imx_vcm_init(struct v4l2_subdev *sd) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->init) - return dev->vcm_driver->init(sd); - return 0; -} - -static int imx_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->t_focus_vcm) - return dev->vcm_driver->t_focus_vcm(sd, val); - return 0; -} - static int imx_t_focus_abs(struct v4l2_subdev *sd, s32 value) { struct imx_device *dev = to_imx_sensor(sd); diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.h b/drivers/staging/media/atomisp/i2c/imx/imx.h index 41b4133ca995..30beb2a0ed93 100644 --- a/drivers/staging/media/atomisp/i2c/imx/imx.h +++ b/drivers/staging/media/atomisp/i2c/imx/imx.h @@ -222,8 +222,6 @@ struct imx_vcm { int (*power_up)(struct v4l2_subdev *sd); int (*power_down)(struct v4l2_subdev *sd); - int (*init)(struct v4l2_subdev *sd); - int (*t_focus_vcm)(struct v4l2_subdev *sd, u16 val); int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); int (*t_focus_abs_init)(struct v4l2_subdev *sd); int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); @@ -549,9 +547,6 @@ static const struct imx_reg imx219_param_update[] = { extern int ad5816g_vcm_power_up(struct v4l2_subdev *sd); extern int ad5816g_vcm_power_down(struct v4l2_subdev *sd); -extern int ad5816g_vcm_init(struct v4l2_subdev *sd); - -extern int ad5816g_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int ad5816g_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int ad5816g_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int ad5816g_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -561,9 +556,6 @@ extern int ad5816g_t_vcm_timing(struct v4l2_subdev *sd, s32 value); extern int drv201_vcm_power_up(struct v4l2_subdev *sd); extern int drv201_vcm_power_down(struct v4l2_subdev *sd); -extern int drv201_vcm_init(struct v4l2_subdev *sd); - -extern int drv201_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int drv201_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int drv201_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int drv201_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -573,9 +565,6 @@ extern int drv201_t_vcm_timing(struct v4l2_subdev *sd, s32 value); extern int dw9714_vcm_power_up(struct v4l2_subdev *sd); extern int dw9714_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9714_vcm_init(struct v4l2_subdev *sd); - -extern int dw9714_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int dw9714_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int dw9714_t_focus_abs_init(struct v4l2_subdev *sd); extern int dw9714_t_focus_rel(struct v4l2_subdev *sd, s32 value); @@ -586,9 +575,6 @@ extern int dw9714_t_vcm_timing(struct v4l2_subdev *sd, s32 value); extern int dw9719_vcm_power_up(struct v4l2_subdev *sd); extern int dw9719_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9719_vcm_init(struct v4l2_subdev *sd); - -extern int dw9719_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int dw9719_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int dw9719_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int dw9719_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -598,9 +584,6 @@ extern int dw9719_t_vcm_timing(struct v4l2_subdev *sd, s32 value); extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9718_vcm_init(struct v4l2_subdev *sd); - -extern int dw9718_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -615,8 +598,6 @@ struct imx_vcm imx_vcms[] = { [IMX175_MERRFLD] = { .power_up = drv201_vcm_power_up, .power_down = drv201_vcm_power_down, - .init = drv201_vcm_init, - .t_focus_vcm = drv201_t_focus_vcm, .t_focus_abs = drv201_t_focus_abs, .t_focus_abs_init = NULL, .t_focus_rel = drv201_t_focus_rel, @@ -628,8 +609,6 @@ struct imx_vcm imx_vcms[] = { [IMX175_VALLEYVIEW] = { .power_up = dw9714_vcm_power_up, .power_down = dw9714_vcm_power_down, - .init = dw9714_vcm_init, - .t_focus_vcm = dw9714_t_focus_vcm, .t_focus_abs = dw9714_t_focus_abs, .t_focus_abs_init = NULL, .t_focus_rel = dw9714_t_focus_rel, @@ -641,8 +620,6 @@ struct imx_vcm imx_vcms[] = { [IMX135_SALTBAY] = { .power_up = ad5816g_vcm_power_up, .power_down = ad5816g_vcm_power_down, - .init = ad5816g_vcm_init, - .t_focus_vcm = ad5816g_t_focus_vcm, .t_focus_abs = ad5816g_t_focus_abs, .t_focus_abs_init = NULL, .t_focus_rel = ad5816g_t_focus_rel, @@ -654,8 +631,6 @@ struct imx_vcm imx_vcms[] = { [IMX135_VICTORIABAY] = { .power_up = dw9719_vcm_power_up, .power_down = dw9719_vcm_power_down, - .init = dw9719_vcm_init, - .t_focus_vcm = dw9719_t_focus_vcm, .t_focus_abs = dw9719_t_focus_abs, .t_focus_abs_init = NULL, .t_focus_rel = dw9719_t_focus_rel, @@ -667,8 +642,6 @@ struct imx_vcm imx_vcms[] = { [IMX134_VALLEYVIEW] = { .power_up = dw9714_vcm_power_up, .power_down = dw9714_vcm_power_down, - .init = dw9714_vcm_init, - .t_focus_vcm = dw9714_t_focus_vcm, .t_focus_abs = dw9714_t_focus_abs, .t_focus_abs_init = dw9714_t_focus_abs_init, .t_focus_rel = dw9714_t_focus_rel, @@ -680,8 +653,6 @@ struct imx_vcm imx_vcms[] = { [IMX219_MFV0_PRH] = { .power_up = dw9718_vcm_power_up, .power_down = dw9718_vcm_power_down, - .init = dw9718_vcm_init, - .t_focus_vcm = dw9718_t_focus_vcm, .t_focus_abs = dw9718_t_focus_abs, .t_focus_abs_init = NULL, .t_focus_rel = dw9718_t_focus_rel, diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c index d9f278bcf926..123642557aa8 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c @@ -913,7 +913,7 @@ err: return ret; } -int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val) +static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = -EINVAL; diff --git a/drivers/staging/media/atomisp/i2c/ov8858.h b/drivers/staging/media/atomisp/i2c/ov8858.h index d3fde200c013..638d1a803a2b 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858.h +++ b/drivers/staging/media/atomisp/i2c/ov8858.h @@ -164,7 +164,6 @@ struct ov8858_vcm { int (*power_up)(struct v4l2_subdev *sd); int (*power_down)(struct v4l2_subdev *sd); int (*init)(struct v4l2_subdev *sd); - int (*t_focus_vcm)(struct v4l2_subdev *sd, u16 val); int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); int (*q_focus_status)(struct v4l2_subdev *sd, s32 *value); @@ -312,7 +311,6 @@ static const struct ov8858_reg ov8858_param_update[] = { extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); extern int dw9718_vcm_init(struct v4l2_subdev *sd); -extern int dw9718_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -328,7 +326,6 @@ static struct ov8858_vcm ov8858_vcms[] = { .power_up = dw9718_vcm_power_up, .power_down = dw9718_vcm_power_down, .init = dw9718_vcm_init, - .t_focus_vcm = dw9718_t_focus_vcm, .t_focus_abs = dw9718_t_focus_abs, .t_focus_rel = dw9718_t_focus_rel, .q_focus_status = dw9718_q_focus_status, diff --git a/drivers/staging/media/atomisp/i2c/ov8858_btns.h b/drivers/staging/media/atomisp/i2c/ov8858_btns.h index f9a3cf8fbf1a..7d74a8899fae 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858_btns.h +++ b/drivers/staging/media/atomisp/i2c/ov8858_btns.h @@ -164,7 +164,6 @@ struct ov8858_vcm { int (*power_up)(struct v4l2_subdev *sd); int (*power_down)(struct v4l2_subdev *sd); int (*init)(struct v4l2_subdev *sd); - int (*t_focus_vcm)(struct v4l2_subdev *sd, u16 val); int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); int (*q_focus_status)(struct v4l2_subdev *sd, s32 *value); @@ -312,7 +311,6 @@ static const struct ov8858_reg ov8858_param_update[] = { extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); extern int dw9718_vcm_init(struct v4l2_subdev *sd); -extern int dw9718_t_focus_vcm(struct v4l2_subdev *sd, u16 val); extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); @@ -328,7 +326,6 @@ static struct ov8858_vcm ov8858_vcms[] = { .power_up = dw9718_vcm_power_up, .power_down = dw9718_vcm_power_down, .init = dw9718_vcm_init, - .t_focus_vcm = dw9718_t_focus_vcm, .t_focus_abs = dw9718_t_focus_abs, .t_focus_rel = dw9718_t_focus_rel, .q_focus_status = dw9718_q_focus_status, -- cgit v1.2.3 From ceb25b3cf622f439f3c1c8e321fd5c35efe79e97 Mon Sep 17 00:00:00 2001 From: Harold Gomez Date: Thu, 10 Aug 2017 04:28:24 -0400 Subject: media: staging: media: atomisp: ap1302: Remove FSF postal address Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL. remove the unnecessary paragraph Signed-off-by: Harold Gomez Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/ap1302.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/ap1302.c b/drivers/staging/media/atomisp/i2c/ap1302.c index de687c6fae57..2f772a020c8b 100644 --- a/drivers/staging/media/atomisp/i2c/ap1302.c +++ b/drivers/staging/media/atomisp/i2c/ap1302.c @@ -11,11 +11,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * */ #include "../include/linux/atomisp.h" -- cgit v1.2.3 From 0b56d1c8fd8991b0ae5255151c54ed20deb49a28 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Aug 2017 08:23:34 -0400 Subject: media: staging: atomisp: fix bounds checking in mt9m114_s_exposure_selection() These clamp_t() calls are no-ops because we don't save the results. It leads to an array out of bounds bug. Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2") Signed-off-by: Dan Carpenter Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/mt9m114.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.c b/drivers/staging/media/atomisp/i2c/mt9m114.c index 36a0636a532f..3c837cb8859c 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/mt9m114.c @@ -1209,10 +1209,10 @@ static int mt9m114_s_exposure_selection(struct v4l2_subdev *sd, return -EINVAL; } - clamp_t(int, win_left, 0, 4); - clamp_t(int, win_top, 0, 4); - clamp_t(int, win_right, 0, 4); - clamp_t(int, win_bottom, 0, 4); + win_left = clamp_t(int, win_left, 0, 4); + win_top = clamp_t(int, win_top, 0, 4); + win_right = clamp_t(int, win_right, 0, 4); + win_bottom = clamp_t(int, win_bottom, 0, 4); ret = mt9m114_write_reg_array(client, mt9m114_exp_average, NO_POLLING); if (ret) { -- cgit v1.2.3 From 412b16d623cf4fd794713f314db5aad10c46ad87 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Wed, 2 Aug 2017 12:45:59 -0400 Subject: media: cx23885: Fix use-after-free when unregistering the i2c_client for the dvb demod Unregistering the i2c_client of the demod driver destroys the frontend object. Calling vb2_dvb_unregister_bus later accesses the frontend (and with the refcount_t) conversion the refcount_t code complains: kernel: ------------[ cut here ]------------ kernel: WARNING: CPU: 0 PID: 7883 at lib/refcount.c:128 refcount_sub_and_test+0x70/0x80 kernel: refcount_t: underflow; use-after-free. kernel: Modules linked in: bluetooth si2165(O) a8293(O) tda10071(O) tea5767(O) tuner(O) cx23885(O-) tda18271(O) videobuf2_dvb(O) videobuf2_dma_sg(O) m88ds3103(O) tveeprom(O) cx2341x(O) v4l2_common(O) dvb_core(O) rc_core(O) videobuf2_memops(O) videobuf2_v4l2(O) ums_realtek videobuf2_core(O) uas videodev(O) media(O) rtl8192cu i2c_mux usb_storage rtl_usb rtl8192c_common rtlwifi snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core x86_pkg_temp_thermal kvm_intel kvm irqbypass kernel: CPU: 0 PID: 7883 Comm: rmmod Tainted: G W O 4.11.3-gentoo #3 kernel: Hardware name: MEDION E2050 2391/H81H3-EM2, BIOS H81EM2W08.308 08/25/2014 kernel: Call Trace: kernel: dump_stack+0x4d/0x66 kernel: __warn+0xc6/0xe0 kernel: warn_slowpath_fmt+0x46/0x50 kernel: ? kobject_put+0x2f/0x60 kernel: refcount_sub_and_test+0x70/0x80 kernel: refcount_dec_and_test+0x11/0x20 kernel: dvb_unregister_frontend+0x42/0x60 [dvb_core] kernel: vb2_dvb_dealloc_frontends+0x9e/0x100 [videobuf2_dvb] kernel: vb2_dvb_unregister_bus+0xd/0x20 [videobuf2_dvb] kernel: cx23885_dvb_unregister+0xc3/0x110 [cx23885] kernel: cx23885_dev_unregister+0xea/0x150 [cx23885] kernel: cx23885_finidev+0x4f/0x70 [cx23885] kernel: pci_device_remove+0x34/0xb0 kernel: device_release_driver_internal+0x150/0x200 kernel: driver_detach+0x33/0x70 kernel: bus_remove_driver+0x47/0xa0 kernel: driver_unregister+0x27/0x50 kernel: pci_unregister_driver+0x34/0x90 kernel: cx23885_fini+0x10/0x12 [cx23885] kernel: SyS_delete_module+0x166/0x220 kernel: ? exit_to_usermode_loop+0x7b/0x80 kernel: entry_SYSCALL_64_fastpath+0x17/0x98 kernel: RIP: 0033:0x7f5901680b07 kernel: RSP: 002b:00007ffdf6cdb028 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 kernel: RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f5901680b07 kernel: RDX: 000000000000000a RSI: 0000000000000800 RDI: 0000000001500258 kernel: RBP: 00000000015001f0 R08: 0000000000000000 R09: 1999999999999999 kernel: R10: 0000000000000884 R11: 0000000000000206 R12: 00007ffdf6cda010 kernel: R13: 0000000000000000 R14: 00000000015001f0 R15: 00000000014ff010 kernel: ---[ end trace c3a4659b89086061 ]--- Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 979b66627f60..e795ddeb7fe2 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2637,6 +2637,11 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) struct vb2_dvb_frontend *fe0; struct i2c_client *client; + fe0 = vb2_dvb_get_frontend(&port->frontends, 1); + + if (fe0 && fe0->dvb.frontend) + vb2_dvb_unregister_bus(&port->frontends); + /* remove I2C client for CI */ client = port->i2c_client_ci; if (client) { @@ -2665,11 +2670,6 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) i2c_unregister_device(client); } - fe0 = vb2_dvb_get_frontend(&port->frontends, 1); - - if (fe0 && fe0->dvb.frontend) - vb2_dvb_unregister_bus(&port->frontends); - switch (port->dev->board) { case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: netup_ci_exit(port); -- cgit v1.2.3 From e59eb4adf0d79fe7692c08c07445ec9efc8ddc1c Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Wed, 2 Aug 2017 12:46:00 -0400 Subject: media: cx231xx: fix use-after-free when unregistering the i2c_client for the dvb demod Calling i2c_unregister_device for a demod driver destroys the frontend object. Later it is accessed by calling dvb_unregister_frontend and dvb_frontend_detach. In some cases this leads to a general protection fault with this callstack: dvb_unregister_frontend+0x25/0x50 [dvb_core] dvb_fini+0xdb/0x160 [cx231xx_dvb] cx231xx_unregister_extension+0x3d/0xb0 [cx231xx] cx231xx_dvb_unregister+0x10/0x809 [cx231xx_dvb] SyS_delete_module+0x18a/0x240 ? exit_to_usermode_loop+0x7b/0x80 entry_SYSCALL_64_fastpath+0x17/0x98 Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cx231xx/cx231xx-dvb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index ee3eeeb600f8..c18bb33e060e 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -585,6 +585,9 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); dvb_dmxdev_release(&dvb->dmxdev); dvb_dmx_release(&dvb->demux); + dvb_unregister_frontend(dvb->frontend); + dvb_frontend_detach(dvb->frontend); + dvb_unregister_adapter(&dvb->adapter); /* remove I2C tuner */ client = dvb->i2c_client_tuner; if (client) { @@ -597,9 +600,6 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) module_put(client->dev.driver->owner); i2c_unregister_device(client); } - dvb_unregister_frontend(dvb->frontend); - dvb_frontend_detach(dvb->frontend); - dvb_unregister_adapter(&dvb->adapter); } static int dvb_init(struct cx231xx *dev) -- cgit v1.2.3 From 6b852620fa75d3137929538b4a9aec2f953ff03c Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Wed, 23 Aug 2017 12:09:58 -0400 Subject: media: dvb-frontends/stv0910: release lock on gate_ctrl() failure Whenever write_reg() fails to open/close the demod's I2C gate, release the lock to avoid deadlocking situations. If I2c gate open failed, there's no need to hold a lock, and if close fails, the mutex_unlock() at the end of the function is never reached, leaving the mutex_lock in locked state, which in turn will cause potential for deadlocks. Thus, release the lock on failure. While we're touching gate_ctrl(), add some explanation about the need for locking and the shared I2C bus/gate. Cc: Julia Lawall Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index d1ae9553f74c..0d4a6a115159 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1221,17 +1221,32 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable) struct stv *state = fe->demodulator_priv; u8 i2crpt = state->i2crpt & ~0x86; - if (enable) - mutex_lock(&state->base->i2c_lock); + /* + * mutex_lock note: Concurrent I2C gate bus accesses must be + * prevented (STV0910 = dual demod on a single IC with a single I2C + * gate/bus, and two tuners attached), similar to most (if not all) + * other I2C host interfaces/busses. + * + * enable=1 (open I2C gate) will grab the lock + * enable=0 (close I2C gate) releases the lock + */ - if (enable) + if (enable) { + mutex_lock(&state->base->i2c_lock); i2crpt |= 0x80; - else + } else { i2crpt |= 0x02; + } if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT : - RSTV0910_P1_I2CRPT, i2crpt) < 0) + RSTV0910_P1_I2CRPT, i2crpt) < 0) { + /* don't hold the I2C bus lock on failure */ + mutex_unlock(&state->base->i2c_lock); + dev_err(&state->base->i2c->dev, + "%s() write_reg failure (enable=%d)\n", + __func__, enable); return -EIO; + } state->i2crpt = i2crpt; -- cgit v1.2.3 From 1502efd2d5960c11593c5f002278cdc1e14c4520 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Wed, 23 Aug 2017 12:09:59 -0400 Subject: media: ddbridge: fix teardown/deregistration order in ddb_input_detach() Brought to attention by Matthias Schwarzott by fixing possible use-after-free faults in some demod drivers: In ddb_input_detach(), the i2c_client is unregistered and removed before dvb frontends are unregistered and detached. While no use-after-free issue was observed so far, there is another issue with this: dvb->attached keeps track of the state of the input/output registration, and the i2c_client unregistration takes place only if everything was successful (dvb->attached == 0x31). If for some reason an error occurred during the frontend setup, that value stays at 0x20. In the following error handling and cleanup, ddb_input_detach() will skip down to that state, leaving the i2c_client registered, causing refcount issues. Fix this by moving the i2c_client deregistration down to case 0x20. Cc: Matthias Schwarzott Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 2464bde1c432..281b6739b0c1 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1255,11 +1255,6 @@ static void dvb_input_detach(struct ddb_input *input) switch (dvb->attached) { case 0x31: - client = dvb->i2c_client[0]; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } if (dvb->fe2) dvb_unregister_frontend(dvb->fe2); if (dvb->fe) @@ -1273,6 +1268,12 @@ static void dvb_input_detach(struct ddb_input *input) dvb->fe = dvb->fe2 = NULL; /* fallthrough */ case 0x20: + client = dvb->i2c_client[0]; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + dvb_net_release(&dvb->dvbnet); /* fallthrough */ case 0x12: -- cgit v1.2.3 From b5967860c6dae3fd64dd87371eef97e2f2e25490 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Wed, 23 Aug 2017 12:10:00 -0400 Subject: media: ddbridge: fix sparse warnings Fix several drivers/media/pci/ddbridge/ddbridge-core.c: warning: symbol ... was not declared. Should it be static? drivers/media/pci/ddbridge/ddbridge-core.c: warning: Using plain integer as NULL pointer drivers/media/pci/ddbridge/ddbridge-io.h: warning: cast removes address space of expression drivers/media/pci/ddbridge/ddbridge-io.h: warning: incorrect type in argument 1 (different address spaces) at multiple places. Cc: Ralph Metzler Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ddbridge/ddbridge-core.c | 26 +++++++++++++------------- drivers/media/pci/ddbridge/ddbridge-io.h | 12 ++++++------ 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 281b6739b0c1..f4bd4908acdd 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -69,7 +69,7 @@ MODULE_PARM_DESC(adapter_alloc, /****************************************************************************/ -DEFINE_MUTEX(redirect_lock); +static DEFINE_MUTEX(redirect_lock); struct workqueue_struct *ddb_wq; @@ -135,8 +135,8 @@ static void ddb_redirect_dma(struct ddb *dev, static int ddb_unredirect(struct ddb_port *port) { - struct ddb_input *oredi, *iredi = 0; - struct ddb_output *iredo = 0; + struct ddb_input *oredi, *iredi = NULL; + struct ddb_output *iredo = NULL; /* dev_info(port->dev->dev, * "unredirect %d.%d\n", port->dev->nr, port->nr); @@ -160,14 +160,14 @@ static int ddb_unredirect(struct ddb_port *port) ddb_redirect_dma(oredi->port->dev, oredi->dma, iredo->dma); } - port->input[0]->redo = 0; + port->input[0]->redo = NULL; ddb_set_dma_table(port->input[0]); } oredi->redi = iredi; - port->input[0]->redi = 0; + port->input[0]->redi = NULL; } - oredi->redo = 0; - port->output->redi = 0; + oredi->redo = NULL; + port->output->redi = NULL; ddb_set_dma_table(oredi); done: @@ -209,7 +209,7 @@ static int ddb_redirect(u32 i, u32 p) if (input2) { if (input->redi) { input2->redi = input->redi; - input->redi = 0; + input->redi = NULL; } else input2->redi = input; } @@ -811,11 +811,11 @@ static const struct file_operations ci_fops = { .open = ts_open, .release = ts_release, .poll = ts_poll, - .mmap = 0, + .mmap = NULL, }; static struct dvb_device dvbdev_ci = { - .priv = 0, + .priv = NULL, .readers = 1, .writers = 1, .users = 2, @@ -2053,7 +2053,7 @@ static struct dvb_ca_en50221 en_templ = { static void ci_attach(struct ddb_port *port) { - struct ddb_ci *ci = 0; + struct ddb_ci *ci = NULL; ci = kzalloc(sizeof(*ci), GFP_KERNEL); if (!ci) @@ -2206,7 +2206,7 @@ static void ci_xo2_attach(struct ddb_port *port) /****************************************************************************/ /****************************************************************************/ -struct cxd2099_cfg cxd_cfg = { +static struct cxd2099_cfg cxd_cfg = { .bitrate = 72000, .adr = 0x40, .polarity = 1, @@ -3445,7 +3445,7 @@ int ddb_device_create(struct ddb *dev) if (res) { ddb_device_attrs_del(dev); device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr)); - ddbs[dev->nr] = 0; + ddbs[dev->nr] = NULL; dev->ddb_dev = ERR_PTR(-ENODEV); } else ddb_num++; diff --git a/drivers/media/pci/ddbridge/ddbridge-io.h b/drivers/media/pci/ddbridge/ddbridge-io.h index ce92e9484075..a4c6bbe09168 100644 --- a/drivers/media/pci/ddbridge/ddbridge-io.h +++ b/drivers/media/pci/ddbridge/ddbridge-io.h @@ -27,32 +27,32 @@ static inline u32 ddblreadl(struct ddb_link *link, u32 adr) { - return readl((char *) (link->dev->regs + (adr))); + return readl(link->dev->regs + adr); } static inline void ddblwritel(struct ddb_link *link, u32 val, u32 adr) { - writel(val, (char *) (link->dev->regs + (adr))); + writel(val, link->dev->regs + adr); } static inline u32 ddbreadl(struct ddb *dev, u32 adr) { - return readl((char *) (dev->regs + (adr))); + return readl(dev->regs + adr); } static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) { - writel(val, (char *) (dev->regs + (adr))); + writel(val, dev->regs + adr); } static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) { - return memcpy_toio((char *) (dev->regs + adr), src, count); + return memcpy_toio(dev->regs + adr, src, count); } static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) { - return memcpy_fromio(dst, (char *) (dev->regs + adr), count); + return memcpy_fromio(dst, dev->regs + adr, count); } static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) -- cgit v1.2.3 From 2b64e4de39c791fa12cd7ec0307f01609d4b7f1b Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Wed, 23 Aug 2017 12:10:01 -0400 Subject: media: staging/cxd2099: Add module parameter for buffer mode The buffer mode of the cxd2099 driver requires more work regarding error handling and thus can cause issues in some cases, so disable it by default and make that mode of operation controllable by users via a module parameter (ie. 'modprobe cxd2099 buffermode=1' enables current behaviour). The upstream codebase also has the buffer mode disabled by default, so we should match this (but users still can test things out using the modparm). Signed-off-by: Daniel Scheller Signed-off-by: Jasmin Jessich Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/cxd2099/cxd2099.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c index f28916ea69f1..3e30f4864e2b 100644 --- a/drivers/staging/media/cxd2099/cxd2099.c +++ b/drivers/staging/media/cxd2099/cxd2099.c @@ -33,8 +33,9 @@ #include "cxd2099.h" -/* comment this line to deactivate the cxd2099ar buffer mode */ -#define BUFFER_MODE 1 +static int buffermode; +module_param(buffermode, int, 0444); +MODULE_PARM_DESC(buffermode, "Enable use of the CXD2099AR buffer mode (default: disabled)"); static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount); @@ -221,7 +222,6 @@ static int write_reg(struct cxd *ci, u8 reg, u8 val) return write_regm(ci, reg, val, 0xff); } -#ifdef BUFFER_MODE static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n) { int status = 0; @@ -248,7 +248,6 @@ static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n) } return status; } -#endif static void set_mode(struct cxd *ci, int mode) { @@ -642,8 +641,6 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) return len; } -#ifdef BUFFER_MODE - static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) { struct cxd *ci = ca->data; @@ -658,7 +655,6 @@ static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) mutex_unlock(&ci->lock); return ecount; } -#endif static struct dvb_ca_en50221 en_templ = { .read_attribute_mem = read_attribute_mem, @@ -669,11 +665,8 @@ static struct dvb_ca_en50221 en_templ = { .slot_shutdown = slot_shutdown, .slot_ts_enable = slot_ts_enable, .poll_slot_status = poll_slot_status, -#ifdef BUFFER_MODE .read_data = read_data, .write_data = write_data, -#endif - }; struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, @@ -703,6 +696,14 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, ci->en.data = ci; init(ci); dev_info(&i2c->dev, "Attached CXD2099AR at %02x\n", ci->cfg.adr); + + if (!buffermode) { + ci->en.read_data = NULL; + ci->en.write_data = NULL; + } else { + dev_info(&i2c->dev, "Using CXD2099AR buffer mode"); + } + return &ci->en; } EXPORT_SYMBOL(cxd2099_attach); -- cgit v1.2.3 From e5d9ce4ddea934d1243747bfc142749ba6ff0c5a Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Wed, 23 Aug 2017 12:10:02 -0400 Subject: media: dvb-frontends/stv0910: change minsymrate to 100Ksyms/s The demodulator supports symbol rates as low as 100Ksyms/s - the demod setup in start() already handles such low symbol rates and reviewers of stv0910 equipped cards even found and tested transponders with SRs in that range. So, announce this in the fe_ops. Cc: Ralph Metzler Cc: Richard Scobie Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 0d4a6a115159..8bf855c301f5 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1698,7 +1698,7 @@ static const struct dvb_frontend_ops stv0910_ops = { .frequency_max = 2150000, .frequency_stepsize = 0, .frequency_tolerance = 0, - .symbol_rate_min = 1000000, + .symbol_rate_min = 100000, .symbol_rate_max = 70000000, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | -- cgit v1.2.3 From be90cc8e4ac08bcb4ca517cd4ae25aa8441e2d88 Mon Sep 17 00:00:00 2001 From: Anton Vasilyev Date: Thu, 10 Aug 2017 11:27:44 -0400 Subject: media: dvb-usb: Add memory free on error path in dw2102_probe() If dw2102_probe() fails on dvb_usb_device_init(), then memleak occurs. The patch adds deallocation to the error path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev Reviewed-by: Enrico Mioso Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 39 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 11109b1e641f..46c60f90e651 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -2335,10 +2335,12 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { + int retval = -ENOMEM; p1100 = kmemdup(&s6x0_properties, sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p1100) - return -ENOMEM; + goto err0; + /* copy default structure */ /* fill only different fields */ p1100->firmware = P1100_FIRMWARE; @@ -2349,10 +2351,9 @@ static int dw2102_probe(struct usb_interface *intf, s660 = kmemdup(&s6x0_properties, sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!s660) { - kfree(p1100); - return -ENOMEM; - } + if (!s660) + goto err1; + s660->firmware = S660_FIRMWARE; s660->num_device_descs = 3; s660->devices[0] = d660; @@ -2362,11 +2363,9 @@ static int dw2102_probe(struct usb_interface *intf, p7500 = kmemdup(&s6x0_properties, sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!p7500) { - kfree(p1100); - kfree(s660); - return -ENOMEM; - } + if (!p7500) + goto err2; + p7500->firmware = P7500_FIRMWARE; p7500->devices[0] = d7500; p7500->rc.core.rc_query = prof_rc_query; @@ -2376,12 +2375,9 @@ static int dw2102_probe(struct usb_interface *intf, s421 = kmemdup(&su3000_properties, sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!s421) { - kfree(p1100); - kfree(s660); - kfree(p7500); - return -ENOMEM; - } + if (!s421) + goto err3; + s421->num_device_descs = 2; s421->devices[0] = d421; s421->devices[1] = d632; @@ -2411,7 +2407,16 @@ static int dw2102_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr)) return 0; - return -ENODEV; + retval = -ENODEV; + kfree(s421); +err3: + kfree(p7500); +err2: + kfree(s660); +err1: + kfree(p1100); +err0: + return retval; } static void dw2102_disconnect(struct usb_interface *intf) -- cgit v1.2.3 From 9793e1d214dc62a2685fa33dd0dc59b7f5e838b6 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sat, 12 Aug 2017 13:30:59 -0400 Subject: media: au0828: fix unbalanced lock/unlock in au0828_usb_probe Call mutex_unlock and free dev on failure. Reported-by: Julia Lawall Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/au0828-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 739df61cec4f..cd363a2100d4 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -628,6 +628,8 @@ static int au0828_usb_probe(struct usb_interface *interface, if (retval) { pr_err("%s() au0282_dev_register failed to register on V4L2\n", __func__); + mutex_unlock(&dev->lock); + kfree(dev); goto done; } -- cgit v1.2.3 From 87e9201108b7d63cc4a50faca3baad48c4ec99f8 Mon Sep 17 00:00:00 2001 From: Eugeniu Rosca Date: Sun, 13 Aug 2017 06:06:29 -0400 Subject: media: mxl111sf: Fix potential null pointer dereference Reviewing the delta between cppcheck output of v4.9.39 and v4.9.40 stable updates, I stumbled on the new warning: mxl111sf.c:80: (warning) Possible null pointer dereference: rbuf Since copying state->rcvbuf into rbuf is not needed in the 'write-only' scenario (i.e. calling mxl111sf_ctrl_msg() from mxl111sf_i2c_send_data() or from mxl111sf_write_reg()), bypass memcpy() in this case. Fixes: d90b336f3f65 ("[media] mxl111sf: Fix driver to use heap allocate buffers for USB messages") Signed-off-by: Eugeniu Rosca Reviewed-by: Michael Ira Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/mxl111sf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index b0d5904a4ea6..67953360fda5 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c @@ -77,7 +77,9 @@ int mxl111sf_ctrl_msg(struct mxl111sf_state *state, dvb_usbv2_generic_rw(d, state->sndbuf, 1+wlen, state->rcvbuf, rlen); - memcpy(rbuf, state->rcvbuf, rlen); + if (rbuf) + memcpy(rbuf, state->rcvbuf, rlen); + mutex_unlock(&state->msg_lock); mxl_fail(ret); -- cgit v1.2.3 From d60908759c459774b0c0f637bdf19ddf1d137e3a Mon Sep 17 00:00:00 2001 From: Cihangir Akturk Date: Sun, 13 Aug 2017 14:39:38 -0400 Subject: media: imx: use setup_timer Use setup_timer function instead of initializing timer with the function and data fields. Generated by: scripts/coccinelle/api/setup_timer.cocci. Signed-off-by: Cihangir Akturk Reviewed-by: Philipp Zabel Reviewed-by: Steve Longerbeam Tested-by: Steve Longerbeam Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-ic-prpencvf.c | 5 ++--- drivers/staging/media/imx/imx-media-csi.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index fa2c120168b6..0790b3d9e255 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -1292,9 +1292,8 @@ static int prp_init(struct imx_ic_priv *ic_priv) priv->ic_priv = ic_priv; spin_lock_init(&priv->irqlock); - init_timer(&priv->eof_timeout_timer); - priv->eof_timeout_timer.data = (unsigned long)priv; - priv->eof_timeout_timer.function = prp_eof_timeout; + setup_timer(&priv->eof_timeout_timer, prp_eof_timeout, + (unsigned long)priv); priv->vdev = imx_media_capture_device_init(&ic_priv->sd, PRPENCVF_SRC_PAD); diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 552a030f3232..6d856118c223 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1739,9 +1739,8 @@ static int imx_csi_probe(struct platform_device *pdev) priv->csi_id = pdata->csi; priv->smfc_id = (priv->csi_id == 0) ? 0 : 2; - init_timer(&priv->eof_timeout_timer); - priv->eof_timeout_timer.data = (unsigned long)priv; - priv->eof_timeout_timer.function = csi_idmac_eof_timeout; + setup_timer(&priv->eof_timeout_timer, csi_idmac_eof_timeout, + (unsigned long)priv); spin_lock_init(&priv->irqlock); v4l2_subdev_init(&priv->sd, &csi_subdev_ops); -- cgit v1.2.3 From c67215263e0b41d35067c77f9ac6cb2873317912 Mon Sep 17 00:00:00 2001 From: Daniel Scheller Date: Mon, 14 Aug 2017 13:39:37 -0400 Subject: media: dvb-frontends/stv0367: remove QAM_AUTO from ddb_fe_ops Since the cab_* codepath doesn't recognize QAM_AUTO, don't announce that it is supported when it really isn't. Fixes ie. w_scan from unconditionally using QAM_AUTO on DVB-C scans. Signed-off-by: Daniel Scheller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0367.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index bc6eb0ab733e..f3529df8211d 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -3283,7 +3283,7 @@ static const struct dvb_frontend_ops stv0367ddb_ops = { 0x400 |/* FE_CAN_QAM_4 */ FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | - FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | + FE_CAN_QAM_256 | /* DVB-T */ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | -- cgit v1.2.3 From d4e192cc44914787cfe1231e2f1f9d0e8855f77b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 17 Aug 2017 17:12:05 -0400 Subject: media: mx2_emmaprp: Check for platform_get_irq() error platform_get_irq() may fail, so we should better check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mx2_emmaprp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 7fd209e51140..92124ffc4d8b 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -942,6 +942,8 @@ static int emmaprp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pcdev); irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; ret = devm_request_irq(&pdev->dev, irq, emmaprp_irq, 0, dev_name(&pdev->dev), pcdev); if (ret) -- cgit v1.2.3 From 87c014867181c3ec6e20bf3e71db37939d1782c7 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 17 Aug 2017 21:23:44 -0400 Subject: media: dib0090: fix duplicated code for different branches Refactor code in order to avoid identical code for different branches. This issue was detected with the help of Coccinelle. Addresses-Coverity-ID: 1226795 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib0090.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index ae53a199b7af..d9d730dfe0b1 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -2435,14 +2435,7 @@ static int dib0090_tune(struct dvb_frontend *fe) Den = 1; if (Rest > 0) { - if (state->config->analog_output) - lo6 |= (1 << 2) | 2; - else { - if (state->identity.in_soc) - lo6 |= (1 << 2) | 2; - else - lo6 |= (1 << 2) | 2; - } + lo6 |= (1 << 2) | 2; Den = 255; } dib0090_write_reg(state, 0x15, (u16) FBDiv); -- cgit v1.2.3 From 3db4b68e4693bc2421a0cbb7777bd7e60e412549 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 24 Aug 2017 18:22:28 -0400 Subject: media: au0828: fix RC_CORE dependency When RC_CORE is a loadable module, and au0828 is built-in including the RC support, we get a link error: drivers/media/usb/au0828/au0828-input.o: In function `au0828_get_key_au8522': au0828-input.c:(.text+0x474): undefined reference to `ir_raw_event_store' drivers/media/usb/au0828/au0828-input.o: In function `au0828_rc_register': au0828-input.c:(.text+0x7c8): undefined reference to `rc_allocate_device' au0828-input.c:(.text+0x8f8): undefined reference to `rc_register_device' This adds an additional dependency, similar to the one for em28xx, to ensure the broken configuration is never used. Fixes: 2fcfd317f66c ("[media] au0828: add support for IR on HVR-950Q") Signed-off-by: Arnd Bergmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/au0828/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index 78b797e0b434..70521e0b4c53 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig @@ -31,6 +31,7 @@ config VIDEO_AU0828_V4L2 config VIDEO_AU0828_RC bool "AU0828 Remote Controller support" depends on RC_CORE + depends on !(RC_CORE=m && VIDEO_AU0828=y) depends on VIDEO_AU0828 ---help--- Enables Remote Controller support on au0828 driver. -- cgit v1.2.3 From 5303135c178c2f51044ddbc30037af9f030e6017 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 08:57:26 -0400 Subject: media: platform: make video_device const Make these const as they are only used during a copy operation. Done using Coccinelle: @match disable optional_qualifier@ identifier s; @@ static struct video_device s = {...}; @ref@ position p; identifier match.s; @@ s@p @good1@ identifier match.s; expression list[3] es; position ref.p; @@ cx88_vdev_init(es,&s@p,...) @good2@ position ref.p; identifier match.s,f,c; expression e; @@ ( e = s@p | e = s@p.f | c(...,s@p.f,...) | c(...,s@p,...) ) @bad depends on !good1 && !good2@ position ref.p; identifier match.s; @@ s@p @depends on forall !bad disable optional_qualifier@ identifier match.s; @@ static + const struct video_device s; Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 2 +- drivers/media/platform/m2m-deinterlace.c | 2 +- drivers/media/platform/marvell-ccic/mcam-core.c | 2 +- drivers/media/platform/mx2_emmaprp.c | 2 +- drivers/media/platform/s5p-g2d/g2d.c | 2 +- drivers/media/platform/ti-vpe/cal.c | 2 +- drivers/media/platform/ti-vpe/vpe.c | 2 +- drivers/media/platform/via-camera.c | 2 +- drivers/media/platform/vim2m.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 2e06dd564442..fb43025df573 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -1380,7 +1380,7 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device viu_template = { +static const struct video_device viu_template = { .name = "FSL viu", .fops = &viu_fops, .minor = -1, diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index 98f6db27b97e..c8a12493f395 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -979,7 +979,7 @@ static const struct v4l2_file_operations deinterlace_fops = { .mmap = deinterlace_mmap, }; -static struct video_device deinterlace_videodev = { +static const struct video_device deinterlace_videodev = { .name = MEM2MEM_NAME, .fops = &deinterlace_fops, .ioctl_ops = &deinterlace_ioctl_ops, diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 8cac2f202099..b07a251e8857 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1639,7 +1639,7 @@ static const struct v4l2_file_operations mcam_v4l_fops = { * This template device holds all of those v4l2 methods; we * clone it for specific real devices. */ -static struct video_device mcam_v4l_template = { +static const struct video_device mcam_v4l_template = { .name = "mcam", .fops = &mcam_v4l_fops, .ioctl_ops = &mcam_v4l_ioctl_ops, diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 92124ffc4d8b..4a2b1afa19c4 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -873,7 +873,7 @@ static const struct v4l2_file_operations emmaprp_fops = { .mmap = emmaprp_mmap, }; -static struct video_device emmaprp_videodev = { +static const struct video_device emmaprp_videodev = { .name = MEM2MEM_NAME, .fops = &emmaprp_fops, .ioctl_ops = &emmaprp_ioctl_ops, diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index bd655b564f54..66aa8cf1d048 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -602,7 +602,7 @@ static const struct v4l2_ioctl_ops g2d_ioctl_ops = { .vidioc_cropcap = vidioc_cropcap, }; -static struct video_device g2d_videodev = { +static const struct video_device g2d_videodev = { .name = G2D_NAME, .fops = &g2d_fops, .ioctl_ops = &g2d_ioctl_ops, diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 0c7ddf894a69..42e383a48ffe 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1420,7 +1420,7 @@ static const struct v4l2_ioctl_ops cal_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device cal_videodev = { +static const struct video_device cal_videodev = { .name = CAL_MODULE_NAME, .fops = &cal_fops, .ioctl_ops = &cal_ioctl_ops, diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 2873c225e5d6..45bd10544189 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2421,7 +2421,7 @@ static const struct v4l2_file_operations vpe_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct video_device vpe_videodev = { +static const struct video_device vpe_videodev = { .name = VPE_MODULE_NAME, .fops = &vpe_fops, .ioctl_ops = &vpe_ioctl_ops, diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index e16f70a5df1d..805d4a8fc17e 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -1259,7 +1259,7 @@ static struct viafb_pm_hooks viacam_pm_hooks = { * Setup stuff. */ -static struct video_device viacam_v4l_template = { +static const struct video_device viacam_v4l_template = { .name = "via-camera", .minor = -1, .tvnorms = V4L2_STD_NTSC_M, diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index afbaa35ab205..b01fba020d5f 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c @@ -974,7 +974,7 @@ static const struct v4l2_file_operations vim2m_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct video_device vim2m_videodev = { +static const struct video_device vim2m_videodev = { .name = MEM2MEM_NAME, .vfl_dir = VFL_DIR_M2M, .fops = &vim2m_fops, -- cgit v1.2.3 From 507e190946297c34a27d9366b0661d5e506fdd03 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 09:08:11 -0400 Subject: media: pci: make video_device const Make these const as they are either used during a copy operation or passed to a const argument of the function cx88_vdev_init. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-blackbird.c | 2 +- drivers/media/pci/dt3155/dt3155.c | 2 +- drivers/media/pci/meye/meye.c | 2 +- drivers/media/pci/saa7134/saa7134-empress.c | 2 +- drivers/media/pci/solo6x10/solo6x10-v4l2.c | 2 +- drivers/media/pci/sta2x11/sta2x11_vip.c | 2 +- drivers/media/pci/tw68/tw68-video.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index aa49c9597d9c..e3101f04941c 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -1075,7 +1075,7 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device cx8802_mpeg_template = { +static const struct video_device cx8802_mpeg_template = { .name = "cx8802", .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c index 6a219694b225..1775c36891ae 100644 --- a/drivers/media/pci/dt3155/dt3155.c +++ b/drivers/media/pci/dt3155/dt3155.c @@ -499,7 +499,7 @@ static int dt3155_init_board(struct dt3155_priv *pd) return 0; } -static struct video_device dt3155_vdev = { +static const struct video_device dt3155_vdev = { .name = DT3155_NAME, .fops = &dt3155_fops, .ioctl_ops = &dt3155_ioctl_ops, diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 0fe76bea2393..49e047e4a81e 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1533,7 +1533,7 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { .vidioc_default = vidioc_default, }; -static struct video_device meye_template = { +static const struct video_device meye_template = { .name = "meye", .fops = &meye_fops, .ioctl_ops = &meye_ioctl_ops, diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index b1d3648dcba1..66acfd35ffc6 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -205,7 +205,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { /* ----------------------------------------------------------- */ -static struct video_device saa7134_empress_template = { +static const struct video_device saa7134_empress_template = { .name = "saa7134-empress", .fops = &ts_fops, .ioctl_ops = &ts_ioctl_ops, diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c index 3266fc21825f..99ffd1ed4a73 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c @@ -630,7 +630,7 @@ static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device solo_v4l2_template = { +static const struct video_device solo_v4l2_template = { .name = SOLO6X10_NAME, .fops = &solo_v4l2_fops, .ioctl_ops = &solo_v4l2_ioctl_ops, diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 6343d24eb1d5..eb5a9eae7c8e 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -754,7 +754,7 @@ static const struct v4l2_ioctl_ops vip_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device video_dev_template = { +static const struct video_device video_dev_template = { .name = KBUILD_MODNAME, .release = video_device_release_empty, .fops = &vip_fops, diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c index 58c4dd75bfa1..8c1f4a049764 100644 --- a/drivers/media/pci/tw68/tw68-video.c +++ b/drivers/media/pci/tw68/tw68-video.c @@ -916,7 +916,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { #endif }; -static struct video_device tw68_video_template = { +static const struct video_device tw68_video_template = { .name = "tw68_video", .fops = &video_fops, .ioctl_ops = &video_ioctl_ops, -- cgit v1.2.3 From 868449422081f8f4b5d2969709c0aa9021184167 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 09:11:30 -0400 Subject: media: usb: make video_device const Make these const as they are only used during a copy operation. Signed-off-by: Bhumika Goyal Acked-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/airspy/airspy.c | 2 +- drivers/media/usb/cpia2/cpia2_v4l.c | 2 +- drivers/media/usb/go7007/go7007-v4l2.c | 2 +- drivers/media/usb/hackrf/hackrf.c | 2 +- drivers/media/usb/msi2500/msi2500.c | 2 +- drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 2 +- drivers/media/usb/pwc/pwc-if.c | 2 +- drivers/media/usb/s2255/s2255drv.c | 2 +- drivers/media/usb/stk1160/stk1160-v4l.c | 2 +- drivers/media/usb/stkwebcam/stk-webcam.c | 2 +- drivers/media/usb/zr364xx/zr364xx.c | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index 07f3f4e7144a..e70c9e2f3798 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -859,7 +859,7 @@ static const struct v4l2_file_operations airspy_fops = { .unlocked_ioctl = video_ioctl2, }; -static struct video_device airspy_template = { +static const struct video_device airspy_template = { .name = "AirSpy SDR", .release = video_device_release_empty, .fops = &airspy_fops, diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c index 7122023e7004..3dedd83f0b19 100644 --- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c @@ -1075,7 +1075,7 @@ static const struct v4l2_file_operations cpia2_fops = { .mmap = cpia2_mmap, }; -static struct video_device cpia2_template = { +static const struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name = "CPiA2 Camera", .fops = &cpia2_fops, diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index 445f17b850c5..98cd57eaf36a 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -901,7 +901,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device go7007_template = { +static const struct video_device go7007_template = { .name = "go7007", .fops = &go7007_fops, .release = video_device_release_empty, diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index a41b305c55d4..7eb53517a82f 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c @@ -1263,7 +1263,7 @@ static const struct v4l2_file_operations hackrf_fops = { .unlocked_ioctl = video_ioctl2, }; -static struct video_device hackrf_template = { +static const struct video_device hackrf_template = { .name = "HackRF One", .release = video_device_release_empty, .fops = &hackrf_fops, diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index 79bfd2dbe649..a097d3dbc141 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -1143,7 +1143,7 @@ static const struct v4l2_file_operations msi2500_fops = { .unlocked_ioctl = video_ioctl2, }; -static struct video_device msi2500_template = { +static const struct video_device msi2500_template = { .name = "Mirics MSi3101 SDR Dongle", .release = video_device_release_empty, .fops = &msi2500_fops, diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 8f13c60198ed..4320bda9352d 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -1226,7 +1226,7 @@ static const struct v4l2_file_operations vdev_fops = { }; -static struct video_device vdev_template = { +static const struct video_device vdev_template = { .fops = &vdev_fops, }; diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index 22420c14ac98..eb6921d2743e 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c @@ -146,7 +146,7 @@ static const struct v4l2_file_operations pwc_fops = { .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; -static struct video_device pwc_template = { +static const struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ .release = video_device_release_empty, .fops = &pwc_fops, diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 23f606e7cd73..b2f239c4ba42 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -1590,7 +1590,7 @@ static void s2255_video_device_release(struct video_device *vdev) return; } -static struct video_device template = { +static const struct video_device template = { .name = "s2255v", .fops = &s2255_fops_v4l, .ioctl_ops = &s2255_ioctl_ops, diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index a132faa590df..77b759a0bcd9 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -751,7 +751,7 @@ static const struct vb2_ops stk1160_video_qops = { .wait_finish = vb2_ops_wait_finish, }; -static struct video_device v4l_template = { +static const struct video_device v4l_template = { .name = "stk1160", .tvnorms = V4L2_STD_525_60 | V4L2_STD_625_50, .fops = &stk1160_fops, diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 39abb58c65dd..c0bba773db25 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1244,7 +1244,7 @@ static void stk_v4l_dev_release(struct video_device *vd) kfree(dev); } -static struct video_device stk_v4l_data = { +static const struct video_device stk_v4l_data = { .name = "stkwebcam", .fops = &v4l_stk_fops, .ioctl_ops = &v4l_stk_ioctl_ops, diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index d4bb56baad9b..4ff8d0aed015 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1335,7 +1335,7 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static struct video_device zr364xx_template = { +static const struct video_device zr364xx_template = { .name = DRIVER_DESC, .fops = &zr364xx_fops, .ioctl_ops = &zr364xx_ioctl_ops, -- cgit v1.2.3 From e66fb184e749d70358df0e849e5f6ca2b5dabfc9 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 02:02:08 -0400 Subject: media: cx18: make v4l2_file_operations const Make this const as it is only stored in a const field of a video_device structure. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx18/cx18-streams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 81d06c1a7796..8385411af641 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -31,7 +31,7 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C -static struct v4l2_file_operations cx18_v4l2_enc_fops = { +static const struct v4l2_file_operations cx18_v4l2_enc_fops = { .owner = THIS_MODULE, .read = cx18_v4l2_read, .open = cx18_v4l2_open, -- cgit v1.2.3 From fe9619a7b583b5d5d9d7fc64c83e498e8f814696 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 02:13:46 -0400 Subject: media: usbtv: make v4l2_file_operations const Make this const as it is only stored in a const field of a video_device structure. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbtv/usbtv-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 8135614f395a..95b5f4319ec2 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -629,7 +629,7 @@ static struct v4l2_ioctl_ops usbtv_ioctl_ops = { .vidioc_streamoff = vb2_ioctl_streamoff, }; -static struct v4l2_file_operations usbtv_fops = { +static const struct v4l2_file_operations usbtv_fops = { .owner = THIS_MODULE, .unlocked_ioctl = video_ioctl2, .mmap = vb2_fop_mmap, -- cgit v1.2.3 From cd3bef00c2528666c30a71c0cc9175721db9f9d1 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 02:15:53 -0400 Subject: media: staging: omap4iss: make v4l2_file_operations const Make this const as it is only stored in a const field of a video_device structure. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 0bac58241a22..9e2f0421a01e 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -1199,7 +1199,7 @@ static int iss_video_mmap(struct file *file, struct vm_area_struct *vma) return vb2_mmap(&vfh->queue, vma); } -static struct v4l2_file_operations iss_video_fops = { +static const struct v4l2_file_operations iss_video_fops = { .owner = THIS_MODULE, .unlocked_ioctl = video_ioctl2, .open = iss_video_open, -- cgit v1.2.3 From 5af478341fa3b2c35a7062ad80581751bf388977 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Aug 2017 02:18:16 -0400 Subject: media: dib9000: delete some unused broken code The dib9000_remove_slave_frontend() function isn't used. I was reviewing it because my static checker claims it writes one element beyond the end of the array. That's a false positive. What it actually does is, if there are two or more front ends, then it prints a debug message to say that it removed the first one, stored in state->fe[1], and then it "removes" (scare quotes on purpose) the second one, stored in state->fe[2]. Deleting a front end from the middle is not really supported and breaks code like dib9000_release() which assumes the first NULL front end marks the end of the list. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib9000.c | 18 ------------------ drivers/media/dvb-frontends/dib9000.h | 7 ------- 2 files changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 17c6f15c7e68..1b7a4331af05 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -2462,24 +2462,6 @@ int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_ } EXPORT_SYMBOL(dib9000_set_slave_frontend); -int dib9000_remove_slave_frontend(struct dvb_frontend *fe) -{ - struct dib9000_state *state = fe->demodulator_priv; - u8 index_frontend = 1; - - while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) - index_frontend++; - if (index_frontend != 1) { - dprintk("remove slave fe %p (index %i)\n", state->fe[index_frontend - 1], index_frontend - 1); - state->fe[index_frontend] = NULL; - return 0; - } - - dprintk("no frontend to be removed\n"); - return -ENODEV; -} -EXPORT_SYMBOL(dib9000_remove_slave_frontend); - struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { struct dib9000_state *state = fe->demodulator_priv; diff --git a/drivers/media/dvb-frontends/dib9000.h b/drivers/media/dvb-frontends/dib9000.h index b10a70aa7c9f..40883b41e66b 100644 --- a/drivers/media/dvb-frontends/dib9000.h +++ b/drivers/media/dvb-frontends/dib9000.h @@ -37,7 +37,6 @@ extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff); extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe); extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); -extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe); extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe); extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c); @@ -97,12 +96,6 @@ static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb return -ENODEV; } -static inline int dib9000_remove_slave_frontend(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -- cgit v1.2.3 From 47bdf7c6d607335f79deead3aba481c3baf04971 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Aug 2017 02:18:41 -0400 Subject: media: dib8000: remove some bogus dead code This function is broken. It sets the wrong front_end to NULL. But it's not used, so let's just delete it. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dib8000.c | 18 ------------------ drivers/media/dvb-frontends/dib8000.h | 1 - 2 files changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index a179a3f6563d..5d9381509b07 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -4255,23 +4255,6 @@ static int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_fronte return -ENOMEM; } -static int dib8000_remove_slave_frontend(struct dvb_frontend *fe) -{ - struct dib8000_state *state = fe->demodulator_priv; - u8 index_frontend = 1; - - while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) - index_frontend++; - if (index_frontend != 1) { - dprintk("remove slave fe %p (index %i)\n", state->fe[index_frontend-1], index_frontend-1); - state->fe[index_frontend] = NULL; - return 0; - } - - dprintk("no frontend to be removed\n"); - return -ENODEV; -} - static struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { struct dib8000_state *state = fe->demodulator_priv; @@ -4506,7 +4489,6 @@ void *dib8000_attach(struct dib8000_ops *ops) ops->get_slave_frontend = dib8000_get_slave_frontend; ops->set_tune_state = dib8000_set_tune_state; ops->pid_filter_ctrl = dib8000_pid_filter_ctrl; - ops->remove_slave_frontend = dib8000_remove_slave_frontend; ops->get_adc_power = dib8000_get_adc_power; ops->update_pll = dib8000_update_pll; ops->tuner_sleep = dib8096p_tuner_sleep; diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h index 2b8b4b1656a2..75cc8e47ec8f 100644 --- a/drivers/media/dvb-frontends/dib8000.h +++ b/drivers/media/dvb-frontends/dib8000.h @@ -53,7 +53,6 @@ struct dib8000_ops { enum frontend_tune_state (*get_tune_state)(struct dvb_frontend *fe); int (*set_tune_state)(struct dvb_frontend *fe, enum frontend_tune_state tune_state); int (*set_slave_frontend)(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); - int (*remove_slave_frontend)(struct dvb_frontend *fe); struct dvb_frontend *(*get_slave_frontend)(struct dvb_frontend *fe, int slave_index); int (*i2c_enumeration)(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr, u8 is_dib8096p); -- cgit v1.2.3 From 96cc6956c6f097bae8f143f700a2795959b20a44 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 04:43:43 -0400 Subject: media: radio: make video_device const Make these const as they are only used in a copy operation. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-tea5764.c | 2 +- drivers/media/radio/radio-wl1273.c | 2 +- drivers/media/radio/si4713/radio-platform-si4713.c | 2 +- drivers/media/radio/wl128x/fmdrv_v4l2.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 9db8331a0c75..bc7e69e7e32e 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -414,7 +414,7 @@ static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { }; /* V4L2 interface */ -static struct video_device tea5764_radio_template = { +static const struct video_device tea5764_radio_template = { .name = "TEA5764 FM-Radio", .fops = &tea5764_fops, .ioctl_ops = &tea5764_ioctl_ops, diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index 17e82a9a0109..903fcd5e99c0 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -1982,7 +1982,7 @@ static const struct v4l2_ioctl_ops wl1273_ioctl_ops = { .vidioc_log_status = wl1273_fm_vidioc_log_status, }; -static struct video_device wl1273_viddev_template = { +static const struct video_device wl1273_viddev_template = { .fops = &wl1273_fops, .ioctl_ops = &wl1273_ioctl_ops, .name = WL1273_FM_DRIVER_NAME, diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c index 6f93ef1249a6..27339ec495f6 100644 --- a/drivers/media/radio/si4713/radio-platform-si4713.c +++ b/drivers/media/radio/si4713/radio-platform-si4713.c @@ -135,7 +135,7 @@ static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = { }; /* radio_si4713_vdev_template - video device interface */ -static struct video_device radio_si4713_vdev_template = { +static const struct video_device radio_si4713_vdev_template = { .fops = &radio_si4713_fops, .name = "radio-si4713", .release = video_device_release_empty, diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index 71423f45c05c..fc5a7abc83d2 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c @@ -509,7 +509,7 @@ static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = { }; /* V4L2 RADIO device parent structure */ -static struct video_device fm_viddev_template = { +static const struct video_device fm_viddev_template = { .fops = &fm_drv_fops, .ioctl_ops = &fm_drv_ioctl_ops, .name = FM_DRV_NAME, -- cgit v1.2.3 From b104729e12aeecc818144d95e3d600c5f276a0c2 Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 26 Aug 2017 07:32:53 -0400 Subject: media: Staging: media: radio-bcm2048: make video_device const Make this const as it is only used in a copy operation. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/bcm2048/radio-bcm2048.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index 86d7fc20f237..58adaea44eb5 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2564,7 +2564,7 @@ static const struct v4l2_ioctl_ops bcm2048_ioctl_ops = { /* * bcm2048_viddev_template - video device interface */ -static struct video_device bcm2048_viddev_template = { +static const struct video_device bcm2048_viddev_template = { .fops = &bcm2048_fops, .name = BCM2048_DRIVER_NAME, .release = video_device_release_empty, -- cgit v1.2.3 From 3e7e9755c956d7d1dbe763cc62145e67d5ca32a9 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 26 Aug 2017 16:06:05 -0400 Subject: media: usbvision: Delete an error message for a failed memory allocation in usbvision_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-video.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 756322c4ac05..b74fb2dcb6f5 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1495,7 +1495,6 @@ static int usbvision_probe(struct usb_interface *intf, PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt); usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); if (usbvision->alt_max_pkt_size == NULL) { - dev_err(&intf->dev, "usbvision: out of memory!\n"); ret = -ENOMEM; goto err_pkt; } -- cgit v1.2.3 From c4cdcf9f1ef06033050bce86f4bdebddf1a05461 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 26 Aug 2017 16:16:52 -0400 Subject: media: usbvision: Adjust eight checks for null pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script “checkpatch.pl” pointed information out like the following. Comparison to NULL could be written !… Thus fix the affected source code places. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-video.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index b74fb2dcb6f5..e6807bad9792 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -904,7 +904,7 @@ static ssize_t usbvision_read(struct file *file, char __user *buf, PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __func__, (unsigned long)count, noblock); - if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) + if (!USBVISION_IS_OPERATIONAL(usbvision) || !buf) return -EFAULT; /* This entry point is compatible with the mmap routines @@ -1234,7 +1234,7 @@ static void usbvision_vdev_init(struct usb_usbvision *usbvision, { struct usb_device *usb_dev = usbvision->dev; - if (usb_dev == NULL) { + if (!usb_dev) { dev_err(&usbvision->dev->dev, "%s: usbvision->dev is not set\n", __func__); return; @@ -1320,7 +1320,7 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev, struct usb_usbvision *usbvision; usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL); - if (usbvision == NULL) + if (!usbvision) return NULL; usbvision->dev = dev; @@ -1334,7 +1334,7 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev, /* prepare control urb for control messages during interrupts */ usbvision->ctrl_urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL); - if (usbvision->ctrl_urb == NULL) + if (!usbvision->ctrl_urb) goto err_unreg; return usbvision; @@ -1380,7 +1380,7 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision) { int model; - if (usbvision == NULL) + if (!usbvision) return; model = usbvision->dev_model; @@ -1474,7 +1474,7 @@ static int usbvision_probe(struct usb_interface *intf, } usbvision = usbvision_alloc(dev, intf); - if (usbvision == NULL) { + if (!usbvision) { dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__); ret = -ENOMEM; goto err_usb; @@ -1494,7 +1494,7 @@ static int usbvision_probe(struct usb_interface *intf, usbvision->num_alt = uif->num_altsetting; PDEBUG(DBG_PROBE, "Alternate settings: %i", usbvision->num_alt); usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); - if (usbvision->alt_max_pkt_size == NULL) { + if (!usbvision->alt_max_pkt_size) { ret = -ENOMEM; goto err_pkt; } @@ -1565,7 +1565,7 @@ static void usbvision_disconnect(struct usb_interface *intf) PDEBUG(DBG_PROBE, ""); - if (usbvision == NULL) { + if (!usbvision) { pr_err("%s: usb_get_intfdata() failed\n", __func__); return; } -- cgit v1.2.3 From 1fbfd8c13a5706be7f082c6a6ad2efe6eb870ba7 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sat, 26 Aug 2017 16:22:13 -0400 Subject: media: usbvision: Improve a size determination in usbvision_alloc() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/usbvision/usbvision-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index e6807bad9792..960272d3c924 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1319,7 +1319,7 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev, { struct usb_usbvision *usbvision; - usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL); + usbvision = kzalloc(sizeof(*usbvision), GFP_KERNEL); if (!usbvision) return NULL; -- cgit v1.2.3 From a9e4998073d49a762a154a6b48a332ec6cb8e6b1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 20 Jul 2017 18:12:07 -0400 Subject: media: dvb_frontend: ensure that inital front end status initialized The fe_status variable s is not initialized meaning it can have any random garbage status. This could be problematic if fe->ops.tune is false as s is not updated by the call to fe->ops.tune() and a subsequent check on the change status will using a garbage value. Fix this by adding FE_NONE to the enum fe_status and initializing s to this. Detected by CoverityScan, CID#112887 ("Uninitialized scalar variable") Signed-off-by: Colin Ian King Reviewed-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 2 +- include/uapi/linux/dvb/frontend.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index e3fff8f64d37..18cc3bbc699c 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -631,7 +631,7 @@ static int dvb_frontend_thread(void *data) struct dvb_frontend *fe = data; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_frontend_private *fepriv = fe->frontend_priv; - enum fe_status s; + enum fe_status s = FE_NONE; enum dvbfe_algo algo; bool re_tune = false; bool semheld = false; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 00a20cd21ee2..afc3972b0879 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -127,6 +127,7 @@ enum fe_sec_mini_cmd { * to reset DiSEqC, tone and parameters */ enum fe_status { + FE_NONE = 0x00, FE_HAS_SIGNAL = 0x01, FE_HAS_CARRIER = 0x02, FE_HAS_VITERBI = 0x04, -- cgit v1.2.3 From 450694c3b9f47b826a002089c463b9454b4bbe42 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 21 Jul 2017 12:01:00 -0400 Subject: media: dvb_frontend: initialize variable s with FE_NONE instead of 0 GIT_AUTHOR_NAME=Colin King GIT_AUTHOR_EMAIL=colin.king@canonical.com In a previous commit, we added FE_NONE as an unknown fe_status. Initialize variable s to FE_NONE instead of the more opaque value 0. Signed-off-by: Colin Ian King Reviewed-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 18cc3bbc699c..114994ca0929 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -460,7 +460,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra static void dvb_frontend_swzigzag(struct dvb_frontend *fe) { - enum fe_status s = 0; + enum fe_status s = FE_NONE; int retval = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp; -- cgit v1.2.3 From 07d45a42fa21b54d83e563565699d25bde9f8cbe Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 30 Jul 2017 08:34:48 -0400 Subject: media: mn88472: reset stream ID reg if no PLP given If the PLP given is NO_STREAM_ID_FILTER (~0u) don't try to set that into the PLP register. Set PLP to 0 instead. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88472.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index f6938f9607ac..5e8fd63832e9 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -377,7 +377,9 @@ static int mn88472_set_frontend(struct dvb_frontend *fe) ret = regmap_write(dev->regmap[1], 0xf6, 0x05); if (ret) goto err; - ret = regmap_write(dev->regmap[2], 0x32, c->stream_id); + ret = regmap_write(dev->regmap[2], 0x32, + (c->stream_id == NO_STREAM_ID_FILTER) ? 0 : + c->stream_id ); if (ret) goto err; break; -- cgit v1.2.3 From 2fb0e047f98f4dc9320857e86076191188829bcd Mon Sep 17 00:00:00 2001 From: Olli Salonen Date: Sun, 30 Jul 2017 08:34:49 -0400 Subject: media: mn88473: reset stream ID reg if no PLP given If the PLP given is NO_STREAM_ID_FILTER (~0u) don't try to set that into the PLP register. Set PLP to 0 instead. Signed-off-by: Olli Salonen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mn88473.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index 15874244fd8b..58247432a628 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -225,7 +225,9 @@ static int mn88473_set_frontend(struct dvb_frontend *fe) /* PLP */ if (c->delivery_system == SYS_DVBT2) { - ret = regmap_write(dev->regmap[2], 0x36, c->stream_id); + ret = regmap_write(dev->regmap[2], 0x36, + (c->stream_id == NO_STREAM_ID_FILTER) ? 0 : + c->stream_id ); if (ret) goto err; } -- cgit v1.2.3 From 651ac1290f49b46fbd4277dcba8b4f27f941152f Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 3 Aug 2017 06:00:32 -0400 Subject: media: dw2102: make dvb_usb_device_description structures const dvb_usb_device_description structures are only used during a copy operation. Therefore, declare them as const. Signed-off-by: Bhumika Goyal Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dw2102.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 46c60f90e651..b421329b21fa 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -2104,46 +2104,46 @@ static struct dvb_usb_device_properties s6x0_properties = { }; static struct dvb_usb_device_properties *p1100; -static struct dvb_usb_device_description d1100 = { +static const struct dvb_usb_device_description d1100 = { "Prof 1100 USB ", {&dw2102_table[PROF_1100], NULL}, {NULL}, }; static struct dvb_usb_device_properties *s660; -static struct dvb_usb_device_description d660 = { +static const struct dvb_usb_device_description d660 = { "TeVii S660 USB", {&dw2102_table[TEVII_S660], NULL}, {NULL}, }; -static struct dvb_usb_device_description d480_1 = { +static const struct dvb_usb_device_description d480_1 = { "TeVii S480.1 USB", {&dw2102_table[TEVII_S480_1], NULL}, {NULL}, }; -static struct dvb_usb_device_description d480_2 = { +static const struct dvb_usb_device_description d480_2 = { "TeVii S480.2 USB", {&dw2102_table[TEVII_S480_2], NULL}, {NULL}, }; static struct dvb_usb_device_properties *p7500; -static struct dvb_usb_device_description d7500 = { +static const struct dvb_usb_device_description d7500 = { "Prof 7500 USB DVB-S2", {&dw2102_table[PROF_7500], NULL}, {NULL}, }; static struct dvb_usb_device_properties *s421; -static struct dvb_usb_device_description d421 = { +static const struct dvb_usb_device_description d421 = { "TeVii S421 PCI", {&dw2102_table[TEVII_S421], NULL}, {NULL}, }; -static struct dvb_usb_device_description d632 = { +static const struct dvb_usb_device_description d632 = { "TeVii S632 USB", {&dw2102_table[TEVII_S632], NULL}, {NULL}, -- cgit v1.2.3 From 537b5c840c2f53991fcb00164ee09dfd8cfc2099 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 7 Aug 2017 06:49:18 -0400 Subject: media: staging/imx: always select VIDEOBUF2_DMA_CONTIG I ran into a rare build error during randconfig testing: drivers/staging/media/imx/imx-media-capture.o: In function `capture_stop_streaming': imx-media-capture.c:(.text+0x224): undefined reference to `vb2_buffer_done' drivers/staging/media/imx/imx-media-capture.o: In function `imx_media_capture_device_register': imx-media-capture.c:(.text+0xe60): undefined reference to `vb2_queue_init' imx-media-capture.c:(.text+0xfa0): undefined reference to `vb2_dma_contig_memops' While VIDEOBUF2_DMA_CONTIG was already selected by the camera driver, it wasn't necessarily there with just the base driver enabled. This moves the 'select' statement to the top-level option to make sure it's always available. Fixes: 64b5a49df486 ("[media] media: imx: Add Capture Device Interface") Signed-off-by: Arnd Bergmann Reviewed-by: Steve Longerbeam Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index 719508fcb0e9..2be921cd0d55 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig @@ -2,6 +2,7 @@ config VIDEO_IMX_MEDIA tristate "i.MX5/6 V4L2 media core driver" depends on MEDIA_CONTROLLER && VIDEO_V4L2 && ARCH_MXC && IMX_IPUV3_CORE depends on VIDEO_V4L2_SUBDEV_API + select VIDEOBUF2_DMA_CONTIG select V4L2_FWNODE ---help--- Say yes here to enable support for video4linux media controller @@ -13,7 +14,6 @@ menu "i.MX5/6 Media Sub devices" config VIDEO_IMX_CSI tristate "i.MX5/6 Camera Sensor Interface driver" depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C - select VIDEOBUF2_DMA_CONTIG default y ---help--- A video4linux camera sensor interface driver for i.MX5/6. -- cgit v1.2.3 From 61e220adf68553b6e5f61b9339ce9d3e92df27cb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 9 Aug 2017 05:37:30 -0400 Subject: media: i2c: adv748x: Export I2C device table entries as module aliases The I2C core always reports a MODALIAS of the form i2c: even if the device was registered via OF, and the driver is only exporting the OF ID table entries as module aliases. So if the driver is built as module, autoload won't work since udev/kmod won't be able to match the registered OF device with its driver module. Before this patch: $ modinfo drivers/media/i2c/adv748x/adv748x.ko | grep alias alias: of:N*T*Cadi,adv7482C* alias: of:N*T*Cadi,adv7482 alias: of:N*T*Cadi,adv7481C* alias: of:N*T*Cadi,adv7481 After this patch: modinfo drivers/media/i2c/adv748x/adv748x.ko | grep alias alias: of:N*T*Cadi,adv7482C* alias: of:N*T*Cadi,adv7482 alias: of:N*T*Cadi,adv7481C* alias: of:N*T*Cadi,adv7481 alias: i2c:adv7482 alias: i2c:adv7481 Signed-off-by: Javier Martinez Canillas Reviewed-by: Kieran Bingham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv748x/adv748x-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index aeb6ae80cb18..5ee14f2c2747 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -807,6 +807,7 @@ static const struct i2c_device_id adv748x_id[] = { { "adv7482", 0 }, { }, }; +MODULE_DEVICE_TABLE(i2c, adv748x_id); static const struct of_device_id adv748x_of_table[] = { { .compatible = "adi,adv7481", }, -- cgit v1.2.3 From 82cf5f4f6b08975bffddaa60e1d8ddcf46776494 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Sun, 27 Aug 2017 08:26:07 -0400 Subject: media: cx23885: Explicitly list Hauppauge model numbers of HVR-4400 and HVR-5500 Add two new model numbers to suppress this message in kernel log: cx23885: cx23885[0]: warning: unknown hauppauge model #121029 Add these model numbers: * Model 121019 - WinTV-HVR4400 * Model 121029 - WinTV-HVR5500 For WinTV-HVR4400 the documentation and my hardware differ: Documentation says it supports DVB-S/S2 and DVB-T, but my hardware also supports DVB-C. Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-cards.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index c48fa8e25a70..78a8836d03e4 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -1278,6 +1278,12 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) case 85721: /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR, Dual channel ATSC and Basic analog */ + case 121019: + /* WinTV-HVR4400 (PCIe, DVB-S2, DVB-C/T) */ + break; + case 121029: + /* WinTV-HVR5500 (PCIe, DVB-S2, DVB-C/T) */ + break; case 150329: /* WinTV-HVR5525 (PCIe, DVB-S/S2, DVB-T/T2/C) */ break; -- cgit v1.2.3 From 9a45bf28bc39ff6ed45a008f7201289c8e9e60a6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 27 Aug 2017 12:30:35 -0400 Subject: media: max2175: Propagate the real error on devm_clk_get() failure When devm_clk_get() fails we should return the real error code instead of always returning -ENODEV. This allows defer probe to happen in the case the clock provider has not been enabled by the time max2175 driver gets probed. Signed-off-by: Fabio Estevam Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max2175.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index a4736a8a7792..bf0e821a2b93 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c @@ -1319,7 +1319,7 @@ static int max2175_probe(struct i2c_client *client, if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&client->dev, "cannot get clock %d\n", ret); - return -ENODEV; + return ret; } regmap = devm_regmap_init_i2c(client, &max2175_regmap_config); -- cgit v1.2.3 From 800846c4d92f538c6640f83d9f9c0f44dac8ada7 Mon Sep 17 00:00:00 2001 From: Jasmin Jessich Date: Fri, 25 Aug 2017 05:59:41 -0400 Subject: media: rc: use ktime accessor functions Prefer using accessor functions so we are not dependent on the ktime_t type. Signed-off-by: Jasmin Jessich Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-ir-raw.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index f495709e28fb..503bc425a187 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -106,7 +106,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) return -EINVAL; now = ktime_get(); - ev.duration = ktime_sub(now, dev->raw->last_event); + ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); ev.pulse = !pulse; rc = ir_raw_event_store(dev, &ev); @@ -474,18 +474,19 @@ EXPORT_SYMBOL(ir_raw_encode_scancode); static void edge_handle(unsigned long arg) { struct rc_dev *dev = (struct rc_dev *)arg; - ktime_t interval = ktime_get() - dev->raw->last_event; + ktime_t interval = ktime_sub(ktime_get(), dev->raw->last_event); - if (interval >= dev->timeout) { + if (ktime_to_ns(interval) >= dev->timeout) { DEFINE_IR_RAW_EVENT(ev); ev.timeout = true; - ev.duration = interval; + ev.duration = ktime_to_ns(interval); ir_raw_event_store(dev, &ev); } else { mod_timer(&dev->raw->edge_handle, - jiffies + nsecs_to_jiffies(dev->timeout - interval)); + jiffies + nsecs_to_jiffies(dev->timeout - + ktime_to_ns(interval))); } ir_raw_event_handle(dev); -- cgit v1.2.3 From 766cbb31893108850f898fa3616d57c59b584354 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 25 Aug 2017 10:45:47 -0400 Subject: media: rc: gpio-ir-tx: use ktime accessor functions Prefer using accessor functions so we are not dependent on the ktime_t type. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/gpio-ir-tx.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/gpio-ir-tx.c b/drivers/media/rc/gpio-ir-tx.c index 0b83408a2e18..cd476cab9782 100644 --- a/drivers/media/rc/gpio-ir-tx.c +++ b/drivers/media/rc/gpio-ir-tx.c @@ -98,15 +98,17 @@ static int gpio_ir_tx(struct rc_dev *dev, unsigned int *txbuf, // pulse ktime_t last = ktime_add_us(edge, txbuf[i]); - while (ktime_get() < last) { + while (ktime_before(ktime_get(), last)) { gpiod_set_value(gpio_ir->gpio, 1); - edge += pulse; - delta = edge - ktime_get(); + edge = ktime_add_ns(edge, pulse); + delta = ktime_to_ns(ktime_sub(edge, + ktime_get())); if (delta > 0) ndelay(delta); gpiod_set_value(gpio_ir->gpio, 0); - edge += space; - delta = edge - ktime_get(); + edge = ktime_add_ns(edge, space); + delta = ktime_to_ns(ktime_sub(edge, + ktime_get())); if (delta > 0) ndelay(delta); } -- cgit v1.2.3 From fce4b371fe5c99a9c05db8493d72f0d1a474ab26 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 23 Aug 2017 11:06:04 -0400 Subject: media: serial_ir: fix tx timing calculation on 32-bit Move the calculation to where it is needed, so the result doesn't need to be stored in the device struct. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/serial_ir.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 4b8d5f38baf6..8b66926bc16a 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -139,10 +139,8 @@ struct serial_ir { struct platform_device *pdev; struct timer_list timeout_timer; - unsigned int freq; + unsigned int carrier; unsigned int duty_cycle; - - unsigned int pulse_width, space_width; }; static struct serial_ir serial_ir; @@ -183,18 +181,6 @@ static void off(void) soutp(UART_MCR, hardware[type].off); } -static void init_timing_params(unsigned int new_duty_cycle, - unsigned int new_freq) -{ - serial_ir.duty_cycle = new_duty_cycle; - serial_ir.freq = new_freq; - - serial_ir.pulse_width = DIV_ROUND_CLOSEST( - new_duty_cycle * NSEC_PER_SEC, new_freq * 100l); - serial_ir.space_width = DIV_ROUND_CLOSEST( - (100l - new_duty_cycle) * NSEC_PER_SEC, new_freq * 100l); -} - static void send_pulse_irdeo(unsigned int length, ktime_t target) { long rawbits; @@ -241,13 +227,20 @@ static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge) * ndelay(s64) does not compile; so use s32 rather than s64. */ s32 delta; + unsigned int pulse, space; + + /* Ensure the dividend fits into 32 bit */ + pulse = DIV_ROUND_CLOSEST(serial_ir.duty_cycle * (NSEC_PER_SEC / 100), + serial_ir.carrier); + space = DIV_ROUND_CLOSEST((100 - serial_ir.duty_cycle) * + (NSEC_PER_SEC / 100), serial_ir.carrier); for (;;) { now = ktime_get(); if (ktime_compare(now, target) >= 0) break; on(); - edge = ktime_add_ns(edge, serial_ir.pulse_width); + edge = ktime_add_ns(edge, pulse); delta = ktime_to_ns(ktime_sub(edge, now)); if (delta > 0) ndelay(delta); @@ -255,7 +248,7 @@ static void send_pulse_homebrew_softcarrier(unsigned int length, ktime_t edge) off(); if (ktime_compare(now, target) >= 0) break; - edge = ktime_add_ns(edge, serial_ir.space_width); + edge = ktime_add_ns(edge, space); delta = ktime_to_ns(ktime_sub(edge, now)); if (delta > 0) ndelay(delta); @@ -580,7 +573,8 @@ static int serial_ir_probe(struct platform_device *dev) return result; /* Initialize pulse/space widths */ - init_timing_params(50, 38000); + serial_ir.duty_cycle = 50; + serial_ir.carrier = 38000; /* If pin is high, then this must be an active low receiver. */ if (sense == -1) { @@ -684,7 +678,7 @@ static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle) { - init_timing_params(cycle, serial_ir.freq); + serial_ir.duty_cycle = cycle; return 0; } @@ -693,7 +687,7 @@ static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier) if (carrier > 500000 || carrier < 20000) return -EINVAL; - init_timing_params(serial_ir.duty_cycle, carrier); + serial_ir.carrier = carrier; return 0; } -- cgit v1.2.3 From c93022a72f01f8e53d6e1bc2a8d2c2824c2f36bc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Sep 2017 05:43:39 -0400 Subject: media: ca.h: split typedefs from structs Using typedefs inside the Kernel is against CodingStyle, and there's no good usage here. Just like we did at frontend.h, at commit 0df289a209e0 ("[media] dvb: Get rid of typedev usage for enums"), let's keep those typedefs only to provide userspace backward compatibility. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/av7110.h | 2 +- drivers/media/pci/ttpci/av7110_ca.c | 12 ++++----- include/uapi/linux/dvb/ca.h | 51 +++++++++++++++++++++++-------------- 3 files changed, 39 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index 824c1e262fbb..347827925c14 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h @@ -177,7 +177,7 @@ struct av7110 { /* CA */ - ca_slot_info_t ci_slot[2]; + struct ca_slot_info ci_slot[2]; enum av7110_video_mode vidmode; struct dmxdev dmxdev; diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c index f64723aea56b..1fe49171d823 100644 --- a/drivers/media/pci/ttpci/av7110_ca.c +++ b/drivers/media/pci/ttpci/av7110_ca.c @@ -119,7 +119,7 @@ static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer * } static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, - int slots, ca_slot_info_t *slot) + int slots, struct ca_slot_info *slot) { int i; int len = 0; @@ -264,7 +264,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) break; case CA_GET_CAP: { - ca_caps_t cap; + struct ca_caps cap; cap.slot_num = 2; cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ? @@ -277,7 +277,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) case CA_GET_SLOT_INFO: { - ca_slot_info_t *info=(ca_slot_info_t *)parg; + struct ca_slot_info *info=(struct ca_slot_info *)parg; if (info->num < 0 || info->num > 1) { mutex_unlock(&av7110->ioctl_mutex); @@ -286,7 +286,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) av7110->ci_slot[info->num].num = info->num; av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI; - memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); + memcpy(info, &av7110->ci_slot[info->num], sizeof(struct ca_slot_info)); break; } @@ -298,7 +298,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) case CA_GET_DESCR_INFO: { - ca_descr_info_t info; + struct ca_descr_info info; info.num = 16; info.type = CA_ECD; @@ -308,7 +308,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) case CA_SET_DESCR: { - ca_descr_t *descr = (ca_descr_t*) parg; + struct ca_descr *descr = (struct ca_descr*) parg; if (descr->index >= 16 || descr->parity > 1) { mutex_unlock(&av7110->ioctl_mutex); diff --git a/include/uapi/linux/dvb/ca.h b/include/uapi/linux/dvb/ca.h index c18537f3e449..00cf24587bea 100644 --- a/include/uapi/linux/dvb/ca.h +++ b/include/uapi/linux/dvb/ca.h @@ -26,7 +26,7 @@ /* slot interface types and info */ -typedef struct ca_slot_info { +struct ca_slot_info { int num; /* slot number */ int type; /* CA interface this slot supports */ @@ -39,52 +39,65 @@ typedef struct ca_slot_info { unsigned int flags; #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ #define CA_CI_MODULE_READY 2 -} ca_slot_info_t; +}; /* descrambler types and info */ -typedef struct ca_descr_info { +struct ca_descr_info { unsigned int num; /* number of available descramblers (keys) */ unsigned int type; /* type of supported scrambling system */ #define CA_ECD 1 #define CA_NDS 2 #define CA_DSS 4 -} ca_descr_info_t; +}; -typedef struct ca_caps { +struct ca_caps { unsigned int slot_num; /* total number of CA card and module slots */ unsigned int slot_type; /* OR of all supported types */ unsigned int descr_num; /* total number of descrambler slots (keys) */ unsigned int descr_type; /* OR of all supported types */ -} ca_caps_t; +}; /* a message to/from a CI-CAM */ -typedef struct ca_msg { +struct ca_msg { unsigned int index; unsigned int type; unsigned int length; unsigned char msg[256]; -} ca_msg_t; +}; -typedef struct ca_descr { +struct ca_descr { unsigned int index; unsigned int parity; /* 0 == even, 1 == odd */ unsigned char cw[8]; -} ca_descr_t; +}; -typedef struct ca_pid { +struct ca_pid { unsigned int pid; int index; /* -1 == disable*/ -} ca_pid_t; +}; #define CA_RESET _IO('o', 128) -#define CA_GET_CAP _IOR('o', 129, ca_caps_t) -#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) -#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) -#define CA_GET_MSG _IOR('o', 132, ca_msg_t) -#define CA_SEND_MSG _IOW('o', 133, ca_msg_t) -#define CA_SET_DESCR _IOW('o', 134, ca_descr_t) -#define CA_SET_PID _IOW('o', 135, ca_pid_t) +#define CA_GET_CAP _IOR('o', 129, struct ca_caps) +#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info) +#define CA_GET_DESCR_INFO _IOR('o', 131, struct ca_descr_info) +#define CA_GET_MSG _IOR('o', 132, struct ca_msg) +#define CA_SEND_MSG _IOW('o', 133, struct ca_msg) +#define CA_SET_DESCR _IOW('o', 134, struct ca_descr) +#define CA_SET_PID _IOW('o', 135, struct ca_pid) + +#if !defined (__KERNEL__) + +/* This is needed for legacy userspace support */ +typedef struct ca_slot_info ca_slot_info_t; +typedef struct ca_descr_info ca_descr_info_t; +typedef struct ca_caps ca_caps_t; +typedef struct ca_msg ca_msg_t; +typedef struct ca_descr ca_descr_t; +typedef struct ca_pid ca_pid_t; + +#endif + #endif -- cgit v1.2.3 From 3256b36ea36525945d8575c0100752819a309aaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Sep 2017 06:09:14 -0400 Subject: media: dmx.h: split typedefs from structs Using typedefs inside the Kernel is against CodingStyle, and there's no good usage here. Just like we did at frontend.h, at commit 0df289a209e0 ("[media] dvb: Get rid of typedev usage for enums"), let's keep those typedefs only to provide userspace backward compatibility. No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 4 +-- include/uapi/linux/dvb/dmx.h | 56 ++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 45e91add73ba..16b0b74c3114 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -562,7 +562,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev, { ktime_t timeout = 0; struct dmx_pes_filter_params *para = &filter->params.pes; - dmx_output_t otype; + enum dmx_output otype; int ret; int ts_type; enum dmx_ts_pes ts_pes; @@ -787,7 +787,7 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, return 0; } -static inline void invert_mode(dmx_filter_t *filter) +static inline void invert_mode(struct dmx_filter *filter) { int i; diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index 427e4899ed69..1bc4d6fb0f01 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h @@ -43,16 +43,14 @@ enum dmx_output DMX_OUT_TSDEMUX_TAP /* Like TS_TAP but retrieved from the DMX device */ }; -typedef enum dmx_output dmx_output_t; - -typedef enum dmx_input +enum dmx_input { DMX_IN_FRONTEND, /* Input from a front-end device. */ DMX_IN_DVR /* Input from the logical DVR device. */ -} dmx_input_t; +}; -typedef enum dmx_ts_pes +enum dmx_ts_pes { DMX_PES_AUDIO0, DMX_PES_VIDEO0, @@ -79,7 +77,7 @@ typedef enum dmx_ts_pes DMX_PES_PCR3, DMX_PES_OTHER -} dmx_pes_type_t; +}; #define DMX_PES_AUDIO DMX_PES_AUDIO0 #define DMX_PES_VIDEO DMX_PES_VIDEO0 @@ -88,20 +86,20 @@ typedef enum dmx_ts_pes #define DMX_PES_PCR DMX_PES_PCR0 -typedef struct dmx_filter +struct dmx_filter { __u8 filter[DMX_FILTER_SIZE]; __u8 mask[DMX_FILTER_SIZE]; __u8 mode[DMX_FILTER_SIZE]; -} dmx_filter_t; +}; struct dmx_sct_filter_params { - __u16 pid; - dmx_filter_t filter; - __u32 timeout; - __u32 flags; + __u16 pid; + struct dmx_filter filter; + __u32 timeout; + __u32 flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 @@ -111,19 +109,19 @@ struct dmx_sct_filter_params struct dmx_pes_filter_params { - __u16 pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; - __u32 flags; + __u16 pid; + enum dmx_input input; + enum dmx_output output; + enum dmx_ts_pes pes_type; + __u32 flags; }; -typedef struct dmx_caps { +struct dmx_caps { __u32 caps; int num_decoders; -} dmx_caps_t; +}; -typedef enum dmx_source { +enum dmx_source { DMX_SOURCE_FRONT0 = 0, DMX_SOURCE_FRONT1, DMX_SOURCE_FRONT2, @@ -132,7 +130,7 @@ typedef enum dmx_source { DMX_SOURCE_DVR1, DMX_SOURCE_DVR2, DMX_SOURCE_DVR3 -} dmx_source_t; +}; struct dmx_stc { unsigned int num; /* input : which STC? 0..N */ @@ -146,10 +144,22 @@ struct dmx_stc { #define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params) #define DMX_SET_BUFFER_SIZE _IO('o', 45) #define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5]) -#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t) -#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t) +#define DMX_GET_CAPS _IOR('o', 48, struct dmx_caps) +#define DMX_SET_SOURCE _IOW('o', 49, enum dmx_source) #define DMX_GET_STC _IOWR('o', 50, struct dmx_stc) #define DMX_ADD_PID _IOW('o', 51, __u16) #define DMX_REMOVE_PID _IOW('o', 52, __u16) +#if !defined (__KERNEL__) + +/* This is needed for legacy userspace support */ +typedef enum dmx_output dmx_output_t; +typedef enum dmx_input dmx_input_t; +typedef enum dmx_ts_pes dmx_pes_type_t; +typedef struct dmx_filter dmx_filter_t; +typedef struct dmx_caps dmx_caps_t; +typedef enum dmx_source dmx_source_t; + +#endif + #endif /* _UAPI_DVBDMX_H_ */ -- cgit v1.2.3 From f35afa4f60c868d7c7811ba747133acbf39410ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Aug 2017 07:55:47 -0400 Subject: media: dvb/frontend.h: move out a private internal structure struct dtv_cmds_h is just an ancillary struct used by the dvb_frontend.c to internally store frontend commands. It doesn't belong to the userspace header, nor it is used anywhere, except inside the DVB core. So, remove it from the header. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 11 +++++++++++ include/uapi/linux/dvb/frontend.h | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 114994ca0929..2fcba1616168 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1000,6 +1000,17 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) .buffer = b \ } +struct dtv_cmds_h { + char *name; /* A display name for debugging purposes */ + + __u32 cmd; /* A unique ID */ + + /* Flags */ + __u32 set:1; /* Either a set or get property */ + __u32 buffer:1; /* Does this property use the buffer? */ + __u32 reserved:30; /* Align */ +}; + static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_TUNE, 1, 0), _DTV_CMD(DTV_CLEAR, 1, 0), diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index afc3972b0879..3a80f3d1da1c 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -384,17 +384,6 @@ enum atscmh_rs_code_mode { #define NO_STREAM_ID_FILTER (~0U) #define LNA_AUTO (~0U) -struct dtv_cmds_h { - char *name; /* A display name for debugging purposes */ - - __u32 cmd; /* A unique ID */ - - /* Flags */ - __u32 set:1; /* Either a set or get property */ - __u32 buffer:1; /* Does this property use the buffer? */ - __u32 reserved:30; /* Align */ -}; - /** * Scale types for the quality parameters. * @FE_SCALE_NOT_AVAILABLE: That QoS measure is not available. That -- cgit v1.2.3 From 833ff5e7feda1a042b83e82208cef3d212ca0ef1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Sep 2017 07:41:49 -0400 Subject: media: ca.h: get rid of CA_SET_PID This ioctl seems to be some attempt to support a feature at the bt8xx dst_ca driver. Yet, as said there, it "needs more work". Right now, the code there is just a boilerplate. At the end of the day, no driver uses this ioctl, nor it is documented anywhere (except for "needs more work"). So, get rid of it. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/ca.h.rst.exceptions | 1 - Documentation/media/dvb-drivers/ci.rst | 1 - Documentation/media/uapi/dvb/ca-set-pid.rst | 60 ---------------------- Documentation/media/uapi/dvb/ca_data_types.rst | 14 ----- Documentation/media/uapi/dvb/ca_function_calls.rst | 1 - drivers/media/pci/bt8xx/dst_ca.c | 16 ------ include/uapi/linux/dvb/ca.h | 7 --- 7 files changed, 100 deletions(-) delete mode 100644 Documentation/media/uapi/dvb/ca-set-pid.rst (limited to 'drivers') diff --git a/Documentation/media/ca.h.rst.exceptions b/Documentation/media/ca.h.rst.exceptions index d7c9fed8c004..553559cc6ad7 100644 --- a/Documentation/media/ca.h.rst.exceptions +++ b/Documentation/media/ca.h.rst.exceptions @@ -16,7 +16,6 @@ replace define CA_NDS :c:type:`ca_descr_info` replace define CA_DSS :c:type:`ca_descr_info` # some typedefs should point to struct/enums -replace typedef ca_pid_t :c:type:`ca_pid` replace typedef ca_slot_info_t :c:type:`ca_slot_info` replace typedef ca_descr_info_t :c:type:`ca_descr_info` replace typedef ca_caps_t :c:type:`ca_caps` diff --git a/Documentation/media/dvb-drivers/ci.rst b/Documentation/media/dvb-drivers/ci.rst index 69b07e9d1816..87f3748c49b9 100644 --- a/Documentation/media/dvb-drivers/ci.rst +++ b/Documentation/media/dvb-drivers/ci.rst @@ -143,7 +143,6 @@ All these ioctls are also valid for the High level CI interface #define CA_GET_MSG _IOR('o', 132, ca_msg_t) #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) -#define CA_SET_PID _IOW('o', 135, ca_pid_t) On querying the device, the device yields information thus: diff --git a/Documentation/media/uapi/dvb/ca-set-pid.rst b/Documentation/media/uapi/dvb/ca-set-pid.rst deleted file mode 100644 index 891c1c72ef24..000000000000 --- a/Documentation/media/uapi/dvb/ca-set-pid.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _CA_SET_PID: - -========== -CA_SET_PID -========== - -Name ----- - -CA_SET_PID - - -Synopsis --------- - -.. c:function:: int ioctl(fd, CA_SET_PID, struct ca_pid *pid) - :name: CA_SET_PID - - -Arguments ---------- - -``fd`` - File descriptor returned by a previous call to :c:func:`open() `. - -``pid`` - Pointer to struct :c:type:`ca_pid`. - -.. c:type:: ca_pid - -.. flat-table:: struct ca_pid - :header-rows: 1 - :stub-columns: 0 - - - - - unsigned int - - pid - - Program ID - - - - - int - - index - - PID index. Use -1 to disable. - - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca_data_types.rst b/Documentation/media/uapi/dvb/ca_data_types.rst index d9e27c77426c..555b5137936b 100644 --- a/Documentation/media/uapi/dvb/ca_data_types.rst +++ b/Documentation/media/uapi/dvb/ca_data_types.rst @@ -94,17 +94,3 @@ ca_descr_t unsigned int parity; unsigned char cw[8]; } ca_descr_t; - - -.. c:type:: ca_pid - -ca-pid -====== - - -.. code-block:: c - - typedef struct ca_pid { - unsigned int pid; - int index; /* -1 == disable*/ - } ca_pid_t; diff --git a/Documentation/media/uapi/dvb/ca_function_calls.rst b/Documentation/media/uapi/dvb/ca_function_calls.rst index c085a0ebbc05..87d697851e82 100644 --- a/Documentation/media/uapi/dvb/ca_function_calls.rst +++ b/Documentation/media/uapi/dvb/ca_function_calls.rst @@ -18,4 +18,3 @@ CA Function Calls ca-get-msg ca-send-msg ca-set-descr - ca-set-pid diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index 90f4263452d3..7db47d8bbe15 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -64,13 +64,6 @@ static int ca_set_slot_descr(void) return -EOPNOTSUPP; } -/* Need some more work */ -static int ca_set_pid(void) -{ - /* We could make this more graceful ? */ - return -EOPNOTSUPP; -} - static void put_command_and_length(u8 *data, int command, int length) { data[0] = (command >> 16) & 0xff; @@ -629,15 +622,6 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct } dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); break; - case CA_SET_PID: - dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); - if ((ca_set_pid()) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); - break; default: result = -EOPNOTSUPP; } diff --git a/include/uapi/linux/dvb/ca.h b/include/uapi/linux/dvb/ca.h index 00cf24587bea..859f6c0c4751 100644 --- a/include/uapi/linux/dvb/ca.h +++ b/include/uapi/linux/dvb/ca.h @@ -73,11 +73,6 @@ struct ca_descr { unsigned char cw[8]; }; -struct ca_pid { - unsigned int pid; - int index; /* -1 == disable*/ -}; - #define CA_RESET _IO('o', 128) #define CA_GET_CAP _IOR('o', 129, struct ca_caps) #define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info) @@ -85,7 +80,6 @@ struct ca_pid { #define CA_GET_MSG _IOR('o', 132, struct ca_msg) #define CA_SEND_MSG _IOW('o', 133, struct ca_msg) #define CA_SET_DESCR _IOW('o', 134, struct ca_descr) -#define CA_SET_PID _IOW('o', 135, struct ca_pid) #if !defined (__KERNEL__) @@ -95,7 +89,6 @@ typedef struct ca_descr_info ca_descr_info_t; typedef struct ca_caps ca_caps_t; typedef struct ca_msg ca_msg_t; typedef struct ca_descr ca_descr_t; -typedef struct ca_pid ca_pid_t; #endif -- cgit v1.2.3 From 39a7c8a8b5fb679f1f2d77f0f30efe1d14ff0dbc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Sep 2017 08:21:04 -0400 Subject: media: dst_ca: return a proper error code from CA errors Right now, on several places, the driver is returning a "-1" error to userspace, instead of a proper error code. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/dst_ca.c | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index 7db47d8bbe15..5ebb86f22935 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -137,7 +137,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, } if(dst_ca_comm_err == RETRIES) - return -1; + return -EIO; return 0; } @@ -152,7 +152,7 @@ static int ca_get_app_info(struct dst_state *state) put_checksum(&command[0], command[0]); if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; + return -EIO; } dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================"); @@ -191,7 +191,7 @@ static int ca_get_ca_info(struct dst_state *state) put_checksum(&slot_command[0], slot_command[0]); if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; + return -EIO; } dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); @@ -235,7 +235,7 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, put_checksum(&slot_command[0], slot_command[0]); if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; + return -EIO; } dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !"); @@ -275,7 +275,7 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s put_checksum(&slot_command[0], 7); if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; + return -EIO; } dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); @@ -347,7 +347,7 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, } else { if (length > 247) { dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !"); - return -1; + return -EIO; } hw_buffer->msg[0] = (length & 0xff) + 7; hw_buffer->msg[1] = 0x40; @@ -373,7 +373,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed."); dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST."); rdc_reset_state(state); - return -1; + return -EIO; } dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); @@ -446,7 +446,7 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message if (ca_pmt_reply_test) { if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); - return -1; + return -EIO; } /* Process CA PMT Reply */ @@ -457,7 +457,7 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message if (!ca_pmt_reply_test) { if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); - return -1; + return -EIO; } dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !"); /* put a dummy message */ @@ -566,17 +566,18 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct switch (cmd) { case CA_SEND_MSG: dprintk(verbose, DST_CA_INFO, 1, " Sending message"); - if ((ca_send_message(state, p_ca_message, arg)) < 0) { + result = ca_send_message(state, p_ca_message, arg); + + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); - result = -1; goto free_mem_and_exit; } break; case CA_GET_MSG: dprintk(verbose, DST_CA_INFO, 1, " Getting message"); - if ((ca_get_message(state, p_ca_message, arg)) < 0) { + result = ca_get_message(state, p_ca_message, arg); + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); - result = -1; goto free_mem_and_exit; } dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); @@ -588,7 +589,8 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct break; case CA_GET_SLOT_INFO: dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); - if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { + result = ca_get_slot_info(state, p_ca_slot_info, arg); + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); result = -1; goto free_mem_and_exit; @@ -597,25 +599,26 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct break; case CA_GET_CAP: dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); - if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { + result = ca_get_slot_caps(state, p_ca_caps, arg); + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); - result = -1; goto free_mem_and_exit; } dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); break; case CA_GET_DESCR_INFO: dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); - if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { + result = ca_get_slot_descr(state, p_ca_message, arg); + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); - result = -1; goto free_mem_and_exit; } dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); break; case CA_SET_DESCR: dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); - if ((ca_set_slot_descr()) < 0) { + result = ca_set_slot_descr(); + if (result < 0) { dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); result = -1; goto free_mem_and_exit; -- cgit v1.2.3 From d8bc60a90d0090b7cae1bd6296230d82f6cac455 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 1 Sep 2017 09:18:02 -0400 Subject: media: dst_ca: remove CA_SET_DESCR boilerplate This ioctl is not implemented at dst_ca driver. There's just a boilerplate code there. Remove it, as it is unlikely that anyone would implement it those days. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/dst_ca.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index 5ebb86f22935..530b3e9764ce 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -57,13 +57,6 @@ static unsigned int verbose = 5; module_param(verbose, int, 0644); MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); -/* Need some more work */ -static int ca_set_slot_descr(void) -{ - /* We could make this more graceful ? */ - return -EOPNOTSUPP; -} - static void put_command_and_length(u8 *data, int command, int length) { data[0] = (command >> 16) & 0xff; @@ -615,16 +608,6 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct } dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); break; - case CA_SET_DESCR: - dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); - result = ca_set_slot_descr(); - if (result < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); - break; default: result = -EOPNOTSUPP; } -- cgit v1.2.3 From a607f51e5a4c421e2097077db88105402099c528 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 4 Aug 2017 10:12:03 -0400 Subject: media: Revert "[media] lirc_dev: remove superfluous get/put_device() calls" This reverts commit 5be2b76a9ca4ea5fd3e221114d62eeb0d78267ca. Only when the lirc device is freed, should we drop our reference to rc_dev, else we the rc_dev is freed to early. If userspace has a file descriptor open during unplug, it goes bang. ================================================================== BUG: KASAN: use-after-free in __lock_acquire+0x7bb/0x1e10 Read of size 8 at addr ffff8801d7d61ed0 by task ir-rec/2609 -snip- mutex_lock_nested+0x1b/0x20 ? mutex_lock_nested+0x1b/0x20 rc_close.part.6+0x20/0x60 [rc_core] rc_close+0x13/0x20 [rc_core] lirc_dev_fop_close+0x62/0xd0 [lirc_dev] __fput+0x236/0x410 ? fput+0xb0/0xb0 ? do_raw_spin_trylock+0x110/0x110 ? set_rq_offline.part.70+0xa0/0xa0 ____fput+0xe/0x10 task_work_run+0x116/0x180 ? task_work_cancel+0x170/0x170 ? _raw_spin_unlock+0x27/0x40 ? switch_task_namespaces+0x5f/0x90 do_exit+0x68b/0xe80 Cc: stable@vger.kernel.org # For Kernel 4.13 Fixes: 5be2b76a9ca4 ("[media] lirc_dev: remove superfluous get/put_device() calls") Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/lirc_dev.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index db1e7b70c998..9080e39ea391 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -59,6 +59,8 @@ static void lirc_release(struct device *ld) { struct irctl *ir = container_of(ld, struct irctl, dev); + put_device(ir->dev.parent); + if (ir->buf_internal) { lirc_buffer_free(ir->buf); kfree(ir->buf); @@ -218,6 +220,8 @@ int lirc_register_driver(struct lirc_driver *d) mutex_unlock(&lirc_dev_lock); + get_device(ir->dev.parent); + dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", ir->d.name, ir->d.minor); -- cgit v1.2.3 From bfc133515ffba42cf81389275ec24ea3c744bb17 Mon Sep 17 00:00:00 2001 From: "Sergei A. Trusov" Date: Wed, 2 Aug 2017 04:00:01 -0400 Subject: media: staging: atomisp: sh_css_calloc shall return a pointer to the allocated space The calloc function returns either a null pointer or a pointer to the allocated space. Add the second case that is missed. Fixes: da22013f7df4 ("atomisp: remove indirection from sh_css_malloc") Signed-off-by: Sergei A. Trusov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c index 471f2be974e2..e882b5596813 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c @@ -1939,6 +1939,7 @@ void *sh_css_calloc(size_t N, size_t size) p = sh_css_malloc(N*size); if (p) memset(p, 0, size); + return p; } return NULL; } -- cgit v1.2.3 From 12f92866f13f9ca12e158c07978246ed83d52ed0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Jul 2017 18:06:22 -0400 Subject: media: Revert "[media] v4l: async: make v4l2 coexist with devicetree nodes in a dt overlay" This reverts commit d2180e0cf77dc7a7049671d5d57dfa0a228f83c1. The commit was flawed in that if the device_node pointers are different, then in fact a different device is present and the device node could be different in ways other than full_name. As Frank Rowand explained: "When an overlay (1) is removed, all uses and references to the nodes and properties in that overlay are no longer valid. Any driver that uses any information from the overlay _must_ stop using any data from the overlay. Any driver that is bound to a new node in the overlay _must_ unbind. Any driver that became bound to a pre-existing node that was modified by the overlay (became bound after the overlay was applied) _must_ adjust itself to account for any changes to that node when the overlay is removed. One way to do this is to unbind when notified that the overlay is about to be removed, then to re-bind after the overlay is completely removed. If an overlay (2) is subsequently applied, a node with the same full_name as from overlay (1) may exist. There is no guarantee that overlay (1) and overlay (2) are the same overlay, even if that node has the same full_name in both cases." Also, there's not sufficient overlay support in mainline to actually remove and re-apply an overlay to hit this condition as overlays can only be applied from in kernel APIs. Fixes: d2180e0cf77d ("[media] v4l: async: make v4l2 coexist with devicetree nodes in a dt overlay") Cc: Javier Martinez Canillas Cc: Sylwester Nawrocki Cc: Frank Rowand Signed-off-by: Rob Herring Acked-by: Javi Merino Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 851f128eba22..d741a8e0fdac 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -44,12 +44,7 @@ static bool match_devname(struct v4l2_subdev *sd, static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) { - if (!is_of_node(sd->fwnode) || !is_of_node(asd->match.fwnode.fwnode)) - return sd->fwnode == asd->match.fwnode.fwnode; - - return !of_node_cmp(of_node_full_name(to_of_node(sd->fwnode)), - of_node_full_name( - to_of_node(asd->match.fwnode.fwnode))); + return sd->fwnode == asd->match.fwnode.fwnode; } static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) -- cgit v1.2.3 From 4cd7d6c957b085d319bcf97814f95854375da0a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 5 Sep 2017 08:23:42 -0400 Subject: media: get rid of removed DMX_GET_CAPS and DMX_SET_SOURCE leftovers Those two ioctls were never used within the Kernel. Still, there used to have compat32 code there (and an if #0 block at the core). Get rid of them. Fixes: 286fe1ca3fa1 ("media: dmx.h: get rid of DMX_GET_CAPS") Fixes: 13adefbe9e56 ("media: dmx.h: get rid of DMX_SET_SOURCE") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 20 -------------------- fs/compat_ioctl.c | 2 -- 2 files changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 16b0b74c3114..18e4230865be 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -1025,26 +1025,6 @@ static int dvb_demux_do_ioctl(struct file *file, dmxdev->demux->get_pes_pids(dmxdev->demux, parg); break; -#if 0 - /* Not used upstream and never documented */ - - case DMX_GET_CAPS: - if (!dmxdev->demux->get_caps) { - ret = -EINVAL; - break; - } - ret = dmxdev->demux->get_caps(dmxdev->demux, parg); - break; - - case DMX_SET_SOURCE: - if (!dmxdev->demux->set_source) { - ret = -EINVAL; - break; - } - ret = dmxdev->demux->set_source(dmxdev->demux, parg); - break; -#endif - case DMX_GET_STC: if (!dmxdev->demux->get_stc) { ret = -EINVAL; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 2dd4a7af7dd7..d27b326d96f4 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1331,8 +1331,6 @@ COMPATIBLE_IOCTL(DMX_SET_FILTER) COMPATIBLE_IOCTL(DMX_SET_PES_FILTER) COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE) COMPATIBLE_IOCTL(DMX_GET_PES_PIDS) -COMPATIBLE_IOCTL(DMX_GET_CAPS) -COMPATIBLE_IOCTL(DMX_SET_SOURCE) COMPATIBLE_IOCTL(DMX_GET_STC) COMPATIBLE_IOCTL(FE_GET_INFO) COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD) -- cgit v1.2.3 From 1efdf1776e2253b77413c997bed862410e4b6aaf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Sep 2017 09:13:20 +0200 Subject: media: leds: as3645a: add V4L2_FLASH_LED_CLASS dependency We get a link error when V4L2_FLASH_LED_CLASS=m and AS3645A is built-in: drivers/leds/leds-as3645a.o: In function `as3645a_v4l2_setup': leds-as3645a.c:(.text+0x258): undefined reference to `v4l2_flash_init' leds-as3645a.c:(.text+0x284): undefined reference to `v4l2_flash_indicator_init' leds-as3645a.c:(.text+0x2a4): undefined reference to `v4l2_flash_release' drivers/leds/leds-as3645a.o: In function `as3645a_remove': leds-as3645a.c:(.text+0x784): undefined reference to `v4l2_flash_release' This adds the same Kconfig dependency that the other V4L2 flash drivers in drivers/leds use, to avoid that broken configuration. Fixes: a56ba8fbcb55 ("media: leds: as3645a: Add LED flash class driver") Signed-off-by: Arnd Bergmann Acked-by: Jacek Anaszewski Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/leds/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index bad3a4098104..27dc8002b121 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -61,6 +61,7 @@ config LEDS_AAT1290 config LEDS_AS3645A tristate "AS3645A LED flash controller support" depends on I2C && LEDS_CLASS_FLASH + depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS help Enable LED flash class support for AS3645A LED flash controller. V4L2 flash API is provided as well if -- cgit v1.2.3