diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-05-02 09:50:09 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-05-02 09:50:09 +1000 |
commit | e235125db6c8bd5fbad0b2dd34933cc2aa2a35c6 (patch) | |
tree | c661a58fff1e894e0ebb470b19d662026e4ec85d | |
parent | 15732ca5a4546dc80051d95f2d3743f1001b90ec (diff) | |
parent | 4a7d735191dec9ccaf95f26f63cb6b46fb8cd260 (diff) | |
download | linux-next-e235125db6c8bd5fbad0b2dd34933cc2aa2a35c6.tar.gz |
next-20240430/v4l-dvb-next
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
114 files changed, 2488 insertions, 4336 deletions
diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml index f81e7daed67b61..2bf1a81feaf478 100644 --- a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml +++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml @@ -15,7 +15,7 @@ description: | They include an ISP capable of auto exposure and auto white balance. allOf: - - $ref: ../video-interface-devices.yaml# + - $ref: /schemas/media/video-interface-devices.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc2145.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc2145.yaml index 1726ecca4c77e4..9eac588de0bc28 100644 --- a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc2145.yaml +++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc2145.yaml @@ -19,7 +19,7 @@ description: either through a parallel interface or through MIPI CSI-2. allOf: - - $ref: ../video-interface-devices.yaml# + - $ref: /schemas/media/video-interface-devices.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml index 60903da84e1f32..0162eec8ca993a 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml @@ -16,7 +16,7 @@ description: | maximum throughput of 1.2Gbps/lane. allOf: - - $ref: ../video-interface-devices.yaml# + - $ref: /schemas/media/video-interface-devices.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml index a531badc16c98b..bf05ca48601abd 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml @@ -23,6 +23,9 @@ description: |- is treated the same as this as it was the original compatible string. imx290llr is the mono version of the sensor. +allOf: + - $ref: /schemas/media/video-interface-devices.yaml# + properties: compatible: oneOf: @@ -101,7 +104,7 @@ required: - vdddo-supply - port -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml index 9a00dab2e8a3f0..34962c5c70065e 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml @@ -18,7 +18,7 @@ description: |- available via CSI-2 serial data output (two or four lanes). allOf: - - $ref: ../video-interface-devices.yaml# + - $ref: /schemas/media/video-interface-devices.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml index e4665469a86c3a..4d5348d456a1fe 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml @@ -84,6 +84,7 @@ allOf: properties: port@0: description: MIPI CSI-2 RX + port@1: false required: - port@0 diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml index 3d9d1db37040de..2be30c5fdc8398 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml @@ -31,6 +31,11 @@ properties: reg: maxItems: 1 + clocks: + items: + - description: AXI DMA engine clock for fetching JPEG bitstream from memory (per) + - description: IP bus clock for register access (ipg) + interrupts: description: | There are 4 slots available in the IP, which the driver may use @@ -49,6 +54,7 @@ properties: required: - compatible - reg + - clocks - interrupts - power-domains @@ -56,12 +62,15 @@ additionalProperties: false examples: - | + #include <dt-bindings/clock/imx8-lpcg.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/firmware/imx/rsrc.h> jpegdec: jpegdec@58400000 { compatible = "nxp,imx8qxp-jpgdec"; reg = <0x58400000 0x00050000 >; + clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>, + <&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>; interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>, @@ -76,6 +85,8 @@ examples: jpegenc: jpegenc@58450000 { compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc"; reg = <0x58450000 0x00050000 >; + clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>, + <&img_jpeg__lpcg IMX_LPCG_CLK_4>; interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>, diff --git a/Documentation/userspace-api/media/cec/cec-func-open.rst b/Documentation/userspace-api/media/cec/cec-func-open.rst index d86563a34b9e77..125c8ac6680b96 100644 --- a/Documentation/userspace-api/media/cec/cec-func-open.rst +++ b/Documentation/userspace-api/media/cec/cec-func-open.rst @@ -70,5 +70,5 @@ include: ``ENOMEM`` Insufficient kernel memory was available. -``ENXIO`` - No device corresponding to this device special file exists. +``ENODEV`` + Device not found or was removed. diff --git a/Documentation/userspace-api/media/v4l/func-open.rst b/Documentation/userspace-api/media/v4l/func-open.rst index ba23ff1e45dd3d..be3808cbf87614 100644 --- a/Documentation/userspace-api/media/v4l/func-open.rst +++ b/Documentation/userspace-api/media/v4l/func-open.rst @@ -65,8 +65,8 @@ EBUSY The driver does not support multiple opens and the device is already in use. -ENXIO - No device corresponding to this device special file exists. +ENODEV + Device not found or was removed. ENOMEM Not enough kernel memory was available to complete the request. diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 5a54db839e5d64..6f940df0230c95 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -62,12 +62,12 @@ int cec_get_device(struct cec_devnode *devnode) */ mutex_lock(&devnode->lock); /* - * return ENXIO if the cec device has been removed + * return ENODEV if the cec device has been removed * already or if it is not registered anymore. */ if (!devnode->registered) { mutex_unlock(&devnode->lock); - return -ENXIO; + return -ENODEV; } /* and increase the device refcount */ get_device(&devnode->dev); diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 0b2b48e1b2df64..358f1fe429751d 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -2584,7 +2584,7 @@ int vb2_core_queue_init(struct vb2_queue *q) WARN_ON(!q->ops->buf_queue)) return -EINVAL; - if (WARN_ON(q->max_num_buffers > MAX_BUFFER_INDEX) || + if (WARN_ON(q->max_num_buffers < VB2_MAX_FRAME) || WARN_ON(q->min_queued_buffers > q->max_num_buffers)) return -EINVAL; @@ -2855,6 +2855,12 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) ret = vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count); if (ret) goto err_kfree; + /* vb2_fileio_data supports max VB2_MAX_FRAME buffers */ + if (fileio->count > VB2_MAX_FRAME) { + dprintk(q, 1, "fileio: more than VB2_MAX_FRAME buffers requested\n"); + ret = -ENOSPC; + goto err_reqbufs; + } /* * Userspace can never add or delete buffers later, so there diff --git a/drivers/media/dvb-frontends/as102_fe_types.h b/drivers/media/dvb-frontends/as102_fe_types.h index 297f9520ebf9d8..8a4e392c889653 100644 --- a/drivers/media/dvb-frontends/as102_fe_types.h +++ b/drivers/media/dvb-frontends/as102_fe_types.h @@ -174,6 +174,6 @@ struct as10x_register_addr { uint32_t addr; /* register mode access */ uint8_t mode; -}; +} __packed; #endif diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h index 15f7e58c5a3080..2c2fd4bf79ccf3 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h +++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h @@ -33,7 +33,6 @@ #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/firmware.h> #include <linux/i2c.h> /* @@ -1910,7 +1909,6 @@ struct drx_demod_instance { /* generic demodulator data */ struct i2c_adapter *i2c; - const struct firmware *firmware; }; /*------------------------------------------------------------------------- diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 19d8de400a6875..1ef53754bc0376 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -56,6 +56,7 @@ INCLUDE FILES #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include <linux/module.h> +#include <linux/firmware.h> #include <linux/init.h> #include <linux/string.h> #include <linux/slab.h> @@ -11750,6 +11751,7 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod, u8 *mc_data = NULL; unsigned size; char *mc_file; + const struct firmware *fw; /* Check arguments */ if (!mc_info || !mc_info->mc_file) @@ -11757,28 +11759,22 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod, mc_file = mc_info->mc_file; - if (!demod->firmware) { - const struct firmware *fw = NULL; - - rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent); - if (rc < 0) { - pr_err("Couldn't read firmware %s\n", mc_file); - return rc; - } - demod->firmware = fw; - - if (demod->firmware->size < 2 * sizeof(u16)) { - rc = -EINVAL; - pr_err("Firmware is too short!\n"); - goto release; - } + rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent); + if (rc < 0) { + pr_err("Couldn't read firmware %s\n", mc_file); + return rc; + } - pr_info("Firmware %s, size %zu\n", - mc_file, demod->firmware->size); + if (fw->size < 2 * sizeof(u16)) { + rc = -EINVAL; + pr_err("Firmware is too short!\n"); + goto release; } - mc_data_init = demod->firmware->data; - size = demod->firmware->size; + pr_info("Firmware %s, size %zu\n", mc_file, fw->size); + + mc_data_init = fw->data; + size = fw->size; mc_data = (void *)mc_data_init; /* Check data */ @@ -11874,7 +11870,8 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod, 0x0000)) { pr_err("error reading firmware at pos %zd\n", mc_data - mc_data_init); - return -EIO; + rc = -EIO; + goto release; } result = memcmp(curr_ptr, mc_data_buffer, @@ -11883,7 +11880,8 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod, if (result) { pr_err("error verifying firmware at pos %zd\n", mc_data - mc_data_init); - return -EIO; + rc = -EIO; + goto release; } curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2)); @@ -11893,17 +11891,17 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod, break; } default: - return -EINVAL; + rc = -EINVAL; + goto release; } mc_data += mc_block_nr_bytes; } - return 0; + rc = 0; release: - release_firmware(demod->firmware); - demod->firmware = NULL; + release_firmware(fw); return rc; } @@ -12271,7 +12269,6 @@ static void drx39xxj_release(struct dvb_frontend *fe) kfree(demod->my_ext_attr); kfree(demod->my_common_attr); kfree(demod->my_i2c_dev_addr); - release_firmware(demod->firmware); kfree(demod); kfree(state); } diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index e0272054fca511..389548fa2e0c47 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1000,6 +1000,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) if (ret) goto err; + if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) { + /* to light up the LOCK led */ + ret = m88ds3103_update_bits(dev, 0x11, 0x80, 0x00); + if (ret) + goto err; + } + dev->delivery_system = c->delivery_system; return 0; diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 56f276b920ab7b..c6d3ee472d814f 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -195,6 +195,7 @@ config VIDEO_IMX334 config VIDEO_IMX335 tristate "Sony IMX335 sensor support" depends on OF_GPIO + select V4L2_CCI_I2C help This is a Video4Linux2 sensor driver for the Sony IMX335 camera. @@ -405,6 +406,7 @@ config VIDEO_OV2740 config VIDEO_OV4689 tristate "OmniVision OV4689 sensor support" depends on GPIOLIB + select V4L2_CCI_I2C help This is a Video4Linux2 sensor-level driver for the OmniVision OV4689 camera. diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 4829cbe3241986..819ff9f7c90fea 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1486,7 +1486,7 @@ static int adv7180_probe(struct i2c_client *client) if (ret) goto err_media_entity_cleanup; - if (state->irq) { + if (state->irq > 0) { ret = request_threaded_irq(client->irq, NULL, adv7180_irq, IRQF_ONESHOT | IRQF_TRIGGER_FALLING, KBUILD_MODNAME, state); diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index 38c77d51578675..b440f386f0622e 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -3,10 +3,13 @@ #include <asm/unaligned.h> #include <linux/acpi.h> +#include <linux/clk.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/regulator/consumer.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> @@ -633,6 +636,11 @@ struct hi556 { struct v4l2_ctrl *hblank; struct v4l2_ctrl *exposure; + /* GPIOs, clocks, etc. */ + struct gpio_desc *reset_gpio; + struct clk *clk; + struct regulator *avdd; + /* Current mode */ const struct hi556_mode *cur_mode; @@ -1206,8 +1214,18 @@ static int hi556_check_hwcfg(struct device *dev) int ret = 0; unsigned int i, j; - if (!fwnode) - return -ENXIO; + /* + * Sometimes the fwnode graph is initialized by the bridge driver, + * wait for this. + */ + ep = fwnode_graph_get_next_endpoint(fwnode, NULL); + if (!ep) + return -EPROBE_DEFER; + + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); + fwnode_handle_put(ep); + if (ret) + return ret; ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); if (ret) { @@ -1220,15 +1238,6 @@ static int hi556_check_hwcfg(struct device *dev) return -EINVAL; } - ep = fwnode_graph_get_next_endpoint(fwnode, NULL); - if (!ep) - return -ENXIO; - - ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); - fwnode_handle_put(ep); - if (ret) - return ret; - if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) { dev_err(dev, "number of CSI2 data lanes %d is not supported", bus_cfg.bus.mipi_csi2.num_data_lanes); @@ -1275,6 +1284,47 @@ static void hi556_remove(struct i2c_client *client) mutex_destroy(&hi556->mutex); } +static int hi556_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct hi556 *hi556 = to_hi556(sd); + int ret; + + gpiod_set_value_cansleep(hi556->reset_gpio, 1); + + ret = regulator_disable(hi556->avdd); + if (ret) { + dev_err(dev, "failed to disable avdd: %d\n", ret); + gpiod_set_value_cansleep(hi556->reset_gpio, 0); + return ret; + } + + clk_disable_unprepare(hi556->clk); + return 0; +} + +static int hi556_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct hi556 *hi556 = to_hi556(sd); + int ret; + + ret = clk_prepare_enable(hi556->clk); + if (ret) + return ret; + + ret = regulator_enable(hi556->avdd); + if (ret) { + dev_err(dev, "failed to enable avdd: %d\n", ret); + clk_disable_unprepare(hi556->clk); + return ret; + } + + gpiod_set_value_cansleep(hi556->reset_gpio, 0); + usleep_range(5000, 5500); + return 0; +} + static int hi556_probe(struct i2c_client *client) { struct hi556 *hi556; @@ -1294,12 +1344,35 @@ static int hi556_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops); + hi556->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(hi556->reset_gpio)) + return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio), + "failed to get reset GPIO\n"); + + hi556->clk = devm_clk_get_optional(&client->dev, "clk"); + if (IS_ERR(hi556->clk)) + return dev_err_probe(&client->dev, PTR_ERR(hi556->clk), + "failed to get clock\n"); + + /* The regulator core will provide a "dummy" regulator if necessary */ + hi556->avdd = devm_regulator_get(&client->dev, "avdd"); + if (IS_ERR(hi556->avdd)) + return dev_err_probe(&client->dev, PTR_ERR(hi556->avdd), + "failed to get avdd regulator\n"); + full_power = acpi_dev_state_d0(&client->dev); if (full_power) { + /* Ensure non ACPI managed resources are enabled */ + ret = hi556_resume(&client->dev); + if (ret) + return dev_err_probe(&client->dev, ret, + "failed to power on sensor\n"); + ret = hi556_identify_module(hi556); if (ret) { dev_err(&client->dev, "failed to find sensor: %d", ret); - return ret; + goto probe_error_power_off; } } @@ -1344,9 +1417,16 @@ probe_error_v4l2_ctrl_handler_free: v4l2_ctrl_handler_free(hi556->sd.ctrl_handler); mutex_destroy(&hi556->mutex); +probe_error_power_off: + if (full_power) + hi556_suspend(&client->dev); + return ret; } +static DEFINE_RUNTIME_DEV_PM_OPS(hi556_pm_ops, hi556_suspend, hi556_resume, + NULL); + #ifdef CONFIG_ACPI static const struct acpi_device_id hi556_acpi_ids[] = { {"INT3537"}, @@ -1360,6 +1440,7 @@ static struct i2c_driver hi556_i2c_driver = { .driver = { .name = "hi556", .acpi_match_table = ACPI_PTR(hi556_acpi_ids), + .pm = pm_sleep_ptr(&hi556_pm_ops), }, .probe = hi556_probe, .remove = hi556_remove, diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index e17ef2e9d9d09a..51ebf5453fcebe 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -551,8 +551,7 @@ static int imx219_init_controls(struct imx219 *imx219) if (ctrl_hdlr->error) { ret = ctrl_hdlr->error; - dev_err(&client->dev, "%s control init failed (%d)\n", - __func__, ret); + dev_err_probe(&client->dev, ret, "Control init failed\n"); goto error; } @@ -1024,17 +1023,15 @@ static int imx219_identify_module(struct imx219 *imx219) u64 val; ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); - if (ret) { - dev_err(&client->dev, "failed to read chip id %x\n", - IMX219_CHIP_ID); - return ret; - } + if (ret) + return dev_err_probe(&client->dev, ret, + "failed to read chip id %x\n", + IMX219_CHIP_ID); - if (val != IMX219_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", - IMX219_CHIP_ID, val); - return -EIO; - } + if (val != IMX219_CHIP_ID) + return dev_err_probe(&client->dev, -EIO, + "chip id mismatch: %x!=%llx\n", + IMX219_CHIP_ID, val); return 0; } @@ -1048,35 +1045,36 @@ static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219) int ret = -EINVAL; endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); - if (!endpoint) { - dev_err(dev, "endpoint node not found\n"); - return -EINVAL; - } + if (!endpoint) + return dev_err_probe(dev, -EINVAL, "endpoint node not found\n"); if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) { - dev_err(dev, "could not parse endpoint\n"); + dev_err_probe(dev, -EINVAL, "could not parse endpoint\n"); goto error_out; } /* Check the number of MIPI CSI2 data lanes */ if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2 && ep_cfg.bus.mipi_csi2.num_data_lanes != 4) { - dev_err(dev, "only 2 or 4 data lanes are currently supported\n"); + dev_err_probe(dev, -EINVAL, + "only 2 or 4 data lanes are currently supported\n"); goto error_out; } imx219->lanes = ep_cfg.bus.mipi_csi2.num_data_lanes; /* Check the link frequency set in device tree */ if (!ep_cfg.nr_of_link_frequencies) { - dev_err(dev, "link-frequency property not found in DT\n"); + dev_err_probe(dev, -EINVAL, + "link-frequency property not found in DT\n"); goto error_out; } if (ep_cfg.nr_of_link_frequencies != 1 || (ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ? IMX219_DEFAULT_LINK_FREQ : IMX219_DEFAULT_LINK_FREQ_4LANE))) { - dev_err(dev, "Link frequency not supported: %lld\n", - ep_cfg.link_frequencies[0]); + dev_err_probe(dev, -EINVAL, + "Link frequency not supported: %lld\n", + ep_cfg.link_frequencies[0]); goto error_out; } @@ -1107,31 +1105,25 @@ static int imx219_probe(struct i2c_client *client) return -EINVAL; imx219->regmap = devm_cci_regmap_init_i2c(client, 16); - if (IS_ERR(imx219->regmap)) { - ret = PTR_ERR(imx219->regmap); - dev_err(dev, "failed to initialize CCI: %d\n", ret); - return ret; - } + if (IS_ERR(imx219->regmap)) + return dev_err_probe(dev, PTR_ERR(imx219->regmap), + "failed to initialize CCI\n"); /* Get system clock (xclk) */ imx219->xclk = devm_clk_get(dev, NULL); - if (IS_ERR(imx219->xclk)) { - dev_err(dev, "failed to get xclk\n"); - return PTR_ERR(imx219->xclk); - } + if (IS_ERR(imx219->xclk)) + return dev_err_probe(dev, PTR_ERR(imx219->xclk), + "failed to get xclk\n"); imx219->xclk_freq = clk_get_rate(imx219->xclk); - if (imx219->xclk_freq != IMX219_XCLK_FREQ) { - dev_err(dev, "xclk frequency not supported: %d Hz\n", - imx219->xclk_freq); - return -EINVAL; - } + if (imx219->xclk_freq != IMX219_XCLK_FREQ) + return dev_err_probe(dev, -EINVAL, + "xclk frequency not supported: %d Hz\n", + imx219->xclk_freq); ret = imx219_get_regulators(imx219); - if (ret) { - dev_err(dev, "failed to get regulators\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to get regulators\n"); /* Request optional enable pin */ imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", @@ -1183,20 +1175,21 @@ static int imx219_probe(struct i2c_client *client) ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad); if (ret) { - dev_err(dev, "failed to init entity pads: %d\n", ret); + dev_err_probe(dev, ret, "failed to init entity pads\n"); goto error_handler_free; } imx219->sd.state_lock = imx219->ctrl_handler.lock; ret = v4l2_subdev_init_finalize(&imx219->sd); if (ret < 0) { - dev_err(dev, "subdev init error: %d\n", ret); + dev_err_probe(dev, ret, "subdev init error\n"); goto error_media_entity; } ret = v4l2_async_register_subdev_sensor(&imx219->sd); if (ret < 0) { - dev_err(dev, "failed to register sensor sub-device: %d\n", ret); + dev_err_probe(dev, ret, + "failed to register sensor sub-device\n"); goto error_subdev_cleanup; } diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index dab6d080bc4c9b..990d74214cc2e4 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -11,57 +11,108 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <media/v4l2-cci.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-fwnode.h> #include <media/v4l2-subdev.h> /* Streaming Mode */ -#define IMX335_REG_MODE_SELECT 0x3000 -#define IMX335_MODE_STANDBY 0x01 -#define IMX335_MODE_STREAMING 0x00 +#define IMX335_REG_MODE_SELECT CCI_REG8(0x3000) +#define IMX335_MODE_STANDBY 0x01 +#define IMX335_MODE_STREAMING 0x00 + +/* Group hold register */ +#define IMX335_REG_HOLD CCI_REG8(0x3001) + +#define IMX335_REG_MASTER_MODE CCI_REG8(0x3002) +#define IMX335_REG_BCWAIT_TIME CCI_REG8(0x300c) +#define IMX335_REG_CPWAIT_TIME CCI_REG8(0x300d) +#define IMX335_REG_WINMODE CCI_REG8(0x3018) +#define IMX335_REG_HTRIMMING_START CCI_REG16_LE(0x302c) +#define IMX335_REG_HNUM CCI_REG8(0x302e) /* Lines per frame */ -#define IMX335_REG_LPFR 0x3030 +#define IMX335_REG_VMAX CCI_REG24_LE(0x3030) -/* Chip ID */ -#define IMX335_REG_ID 0x3912 -#define IMX335_ID 0x00 - -/* Exposure control */ -#define IMX335_REG_SHUTTER 0x3058 -#define IMX335_EXPOSURE_MIN 1 -#define IMX335_EXPOSURE_OFFSET 9 -#define IMX335_EXPOSURE_STEP 1 -#define IMX335_EXPOSURE_DEFAULT 0x0648 - -/* Analog gain control */ -#define IMX335_REG_AGAIN 0x30e8 -#define IMX335_AGAIN_MIN 0 -#define IMX335_AGAIN_MAX 240 -#define IMX335_AGAIN_STEP 1 -#define IMX335_AGAIN_DEFAULT 0 +#define IMX335_REG_OPB_SIZE_V CCI_REG8(0x304c) +#define IMX335_REG_ADBIT CCI_REG8(0x3050) +#define IMX335_REG_Y_OUT_SIZE CCI_REG16_LE(0x3056) -/* Group hold register */ -#define IMX335_REG_HOLD 0x3001 +#define IMX335_REG_SHUTTER CCI_REG24_LE(0x3058) +#define IMX335_EXPOSURE_MIN 1 +#define IMX335_EXPOSURE_OFFSET 9 +#define IMX335_EXPOSURE_STEP 1 +#define IMX335_EXPOSURE_DEFAULT 0x0648 + +#define IMX335_REG_AREA3_ST_ADR_1 CCI_REG16_LE(0x3074) +#define IMX335_REG_AREA3_WIDTH_1 CCI_REG16_LE(0x3076) + +/* Analog and Digital gain control */ +#define IMX335_REG_GAIN CCI_REG8(0x30e8) +#define IMX335_AGAIN_MIN 0 +#define IMX335_AGAIN_MAX 100 +#define IMX335_AGAIN_STEP 1 +#define IMX335_AGAIN_DEFAULT 0 + +#define IMX335_REG_TPG_TESTCLKEN CCI_REG8(0x3148) + +#define IMX335_REG_INCLKSEL1 CCI_REG16_LE(0x314c) +#define IMX335_REG_INCLKSEL2 CCI_REG8(0x315a) +#define IMX335_REG_INCLKSEL3 CCI_REG8(0x3168) +#define IMX335_REG_INCLKSEL4 CCI_REG8(0x316a) + +#define IMX335_REG_MDBIT CCI_REG8(0x319d) +#define IMX335_REG_SYSMODE CCI_REG8(0x319e) + +#define IMX335_REG_XVS_XHS_DRV CCI_REG8(0x31a1) /* Test pattern generator */ -#define IMX335_REG_TPG 0x329e -#define IMX335_TPG_ALL_000 0 -#define IMX335_TPG_ALL_FFF 1 -#define IMX335_TPG_ALL_555 2 -#define IMX335_TPG_ALL_AAA 3 -#define IMX335_TPG_TOG_555_AAA 4 -#define IMX335_TPG_TOG_AAA_555 5 -#define IMX335_TPG_TOG_000_555 6 -#define IMX335_TPG_TOG_555_000 7 -#define IMX335_TPG_TOG_000_FFF 8 -#define IMX335_TPG_TOG_FFF_000 9 -#define IMX335_TPG_H_COLOR_BARS 10 -#define IMX335_TPG_V_COLOR_BARS 11 +#define IMX335_REG_TPG_DIG_CLP_MODE CCI_REG8(0x3280) +#define IMX335_REG_TPG_EN_DUOUT CCI_REG8(0x329c) +#define IMX335_REG_TPG CCI_REG8(0x329e) +#define IMX335_TPG_ALL_000 0 +#define IMX335_TPG_ALL_FFF 1 +#define IMX335_TPG_ALL_555 2 +#define IMX335_TPG_ALL_AAA 3 +#define IMX335_TPG_TOG_555_AAA 4 +#define IMX335_TPG_TOG_AAA_555 5 +#define IMX335_TPG_TOG_000_555 6 +#define IMX335_TPG_TOG_555_000 7 +#define IMX335_TPG_TOG_000_FFF 8 +#define IMX335_TPG_TOG_FFF_000 9 +#define IMX335_TPG_H_COLOR_BARS 10 +#define IMX335_TPG_V_COLOR_BARS 11 +#define IMX335_REG_TPG_COLORWIDTH CCI_REG8(0x32a0) + +#define IMX335_REG_BLKLEVEL CCI_REG16_LE(0x3302) + +#define IMX335_REG_WRJ_OPEN CCI_REG8(0x336c) + +#define IMX335_REG_ADBIT1 CCI_REG16_LE(0x341c) + +/* Chip ID */ +#define IMX335_REG_ID CCI_REG8(0x3912) +#define IMX335_ID 0x00 + +/* Data Lanes */ +#define IMX335_REG_LANEMODE CCI_REG8(0x3a01) +#define IMX335_2LANE 1 +#define IMX335_4LANE 3 + +#define IMX335_REG_TCLKPOST CCI_REG16_LE(0x3a18) +#define IMX335_REG_TCLKPREPARE CCI_REG16_LE(0x3a1a) +#define IMX335_REG_TCLK_TRAIL CCI_REG16_LE(0x3a1c) +#define IMX335_REG_TCLK_ZERO CCI_REG16_LE(0x3a1e) +#define IMX335_REG_THS_PREPARE CCI_REG16_LE(0x3a20) +#define IMX335_REG_THS_ZERO CCI_REG16_LE(0x3a22) +#define IMX335_REG_THS_TRAIL CCI_REG16_LE(0x3a24) +#define IMX335_REG_THS_EXIT CCI_REG16_LE(0x3a26) +#define IMX335_REG_TPLX CCI_REG16_LE(0x3a28) /* Input clock rate */ -#define IMX335_INCLK_RATE 24000000 +#define IMX335_INCLK_RATE 24000000 /* CSI2 HW configuration */ #define IMX335_LINK_FREQ_594MHz 594000000LL @@ -69,9 +120,6 @@ #define IMX335_NUM_DATA_LANES 4 -#define IMX335_REG_MIN 0x00 -#define IMX335_REG_MAX 0xfffff - /* IMX335 native and active pixel array size. */ #define IMX335_NATIVE_WIDTH 2616U #define IMX335_NATIVE_HEIGHT 1964U @@ -81,23 +129,13 @@ #define IMX335_PIXEL_ARRAY_HEIGHT 1944U /** - * struct imx335_reg - imx335 sensor register - * @address: Register address - * @val: Register value - */ -struct imx335_reg { - u16 address; - u8 val; -}; - -/** * struct imx335_reg_list - imx335 sensor register list * @num_of_regs: Number of registers in the list * @regs: Pointer to register list */ struct imx335_reg_list { u32 num_of_regs; - const struct imx335_reg *regs; + const struct cci_reg_sequence *regs; }; static const char * const imx335_supply_name[] = { @@ -138,6 +176,7 @@ struct imx335_mode { * @pad: Media pad. Only one pad supported * @reset_gpio: Sensor reset gpio * @supplies: Regulator supplies to handle power control + * @cci: CCI register map * @inclk: Sensor input clock * @ctrl_handler: V4L2 control handler * @link_freq_ctrl: Pointer to link frequency control @@ -147,6 +186,7 @@ struct imx335_mode { * @exp_ctrl: Pointer to exposure control * @again_ctrl: Pointer to analog gain control * @vblank: Vertical blanking in lines + * @lane_mode: Mode for number of connected data lanes * @cur_mode: Pointer to current selected sensor mode * @mutex: Mutex for serializing sensor controls * @link_freq_bitmap: Menu bitmap for link_freq_ctrl @@ -159,6 +199,7 @@ struct imx335 { struct media_pad pad; struct gpio_desc *reset_gpio; struct regulator_bulk_data supplies[ARRAY_SIZE(imx335_supply_name)]; + struct regmap *cci; struct clk *inclk; struct v4l2_ctrl_handler ctrl_handler; @@ -171,6 +212,7 @@ struct imx335 { struct v4l2_ctrl *again_ctrl; }; u32 vblank; + u32 lane_mode; const struct imx335_mode *cur_mode; struct mutex mutex; unsigned long link_freq_bitmap; @@ -210,140 +252,135 @@ static const int imx335_tpg_val[] = { }; /* Sensor mode registers */ -static const struct imx335_reg mode_2592x1940_regs[] = { - {0x3000, 0x01}, - {0x3002, 0x00}, - {0x3018, 0x04}, - {0x302c, 0x3c}, - {0x302e, 0x20}, - {0x3056, 0x94}, - {0x3074, 0xc8}, - {0x3076, 0x28}, - {0x304c, 0x00}, - {0x31a1, 0x00}, - {0x3288, 0x21}, - {0x328a, 0x02}, - {0x3414, 0x05}, - {0x3416, 0x18}, - {0x3648, 0x01}, - {0x364a, 0x04}, - {0x364c, 0x04}, - {0x3678, 0x01}, - {0x367c, 0x31}, - {0x367e, 0x31}, - {0x3706, 0x10}, - {0x3708, 0x03}, - {0x3714, 0x02}, - {0x3715, 0x02}, - {0x3716, 0x01}, - {0x3717, 0x03}, - {0x371c, 0x3d}, - {0x371d, 0x3f}, - {0x372c, 0x00}, - {0x372d, 0x00}, - {0x372e, 0x46}, - {0x372f, 0x00}, - {0x3730, 0x89}, - {0x3731, 0x00}, - {0x3732, 0x08}, - {0x3733, 0x01}, - {0x3734, 0xfe}, - {0x3735, 0x05}, - {0x3740, 0x02}, - {0x375d, 0x00}, - {0x375e, 0x00}, - {0x375f, 0x11}, - {0x3760, 0x01}, - {0x3768, 0x1b}, - {0x3769, 0x1b}, - {0x376a, 0x1b}, - {0x376b, 0x1b}, - {0x376c, 0x1a}, - {0x376d, 0x17}, - {0x376e, 0x0f}, - {0x3776, 0x00}, - {0x3777, 0x00}, - {0x3778, 0x46}, - {0x3779, 0x00}, - {0x377a, 0x89}, - {0x377b, 0x00}, - {0x377c, 0x08}, - {0x377d, 0x01}, - {0x377e, 0x23}, - {0x377f, 0x02}, - {0x3780, 0xd9}, - {0x3781, 0x03}, - {0x3782, 0xf5}, - {0x3783, 0x06}, - {0x3784, 0xa5}, - {0x3788, 0x0f}, - {0x378a, 0xd9}, - {0x378b, 0x03}, - {0x378c, 0xeb}, - {0x378d, 0x05}, - {0x378e, 0x87}, - {0x378f, 0x06}, - {0x3790, 0xf5}, - {0x3792, 0x43}, - {0x3794, 0x7a}, - {0x3796, 0xa1}, - {0x37b0, 0x36}, - {0x3a00, 0x00}, +static const struct cci_reg_sequence mode_2592x1940_regs[] = { + { IMX335_REG_MODE_SELECT, IMX335_MODE_STANDBY }, + { IMX335_REG_MASTER_MODE, 0x00 }, + { IMX335_REG_WINMODE, 0x04 }, + { IMX335_REG_HTRIMMING_START, 48 }, + { IMX335_REG_HNUM, 2592 }, + { IMX335_REG_Y_OUT_SIZE, 1944 }, + { IMX335_REG_AREA3_ST_ADR_1, 176 }, + { IMX335_REG_AREA3_WIDTH_1, 3928 }, + { IMX335_REG_OPB_SIZE_V, 0 }, + { IMX335_REG_XVS_XHS_DRV, 0x00 }, + { CCI_REG8(0x3288), 0x21 }, + { CCI_REG8(0x328a), 0x02 }, + { CCI_REG8(0x3414), 0x05 }, + { CCI_REG8(0x3416), 0x18 }, + { CCI_REG8(0x3648), 0x01 }, + { CCI_REG8(0x364a), 0x04 }, + { CCI_REG8(0x364c), 0x04 }, + { CCI_REG8(0x3678), 0x01 }, + { CCI_REG8(0x367c), 0x31 }, + { CCI_REG8(0x367e), 0x31 }, + { CCI_REG8(0x3706), 0x10 }, + { CCI_REG8(0x3708), 0x03 }, + { CCI_REG8(0x3714), 0x02 }, + { CCI_REG8(0x3715), 0x02 }, + { CCI_REG8(0x3716), 0x01 }, + { CCI_REG8(0x3717), 0x03 }, + { CCI_REG8(0x371c), 0x3d }, + { CCI_REG8(0x371d), 0x3f }, + { CCI_REG8(0x372c), 0x00 }, + { CCI_REG8(0x372d), 0x00 }, + { CCI_REG8(0x372e), 0x46 }, + { CCI_REG8(0x372f), 0x00 }, + { CCI_REG8(0x3730), 0x89 }, + { CCI_REG8(0x3731), 0x00 }, + { CCI_REG8(0x3732), 0x08 }, + { CCI_REG8(0x3733), 0x01 }, + { CCI_REG8(0x3734), 0xfe }, + { CCI_REG8(0x3735), 0x05 }, + { CCI_REG8(0x3740), 0x02 }, + { CCI_REG8(0x375d), 0x00 }, + { CCI_REG8(0x375e), 0x00 }, + { CCI_REG8(0x375f), 0x11 }, + { CCI_REG8(0x3760), 0x01 }, + { CCI_REG8(0x3768), 0x1b }, + { CCI_REG8(0x3769), 0x1b }, + { CCI_REG8(0x376a), 0x1b }, + { CCI_REG8(0x376b), 0x1b }, + { CCI_REG8(0x376c), 0x1a }, + { CCI_REG8(0x376d), 0x17 }, + { CCI_REG8(0x376e), 0x0f }, + { CCI_REG8(0x3776), 0x00 }, + { CCI_REG8(0x3777), 0x00 }, + { CCI_REG8(0x3778), 0x46 }, + { CCI_REG8(0x3779), 0x00 }, + { CCI_REG8(0x377a), 0x89 }, + { CCI_REG8(0x377b), 0x00 }, + { CCI_REG8(0x377c), 0x08 }, + { CCI_REG8(0x377d), 0x01 }, + { CCI_REG8(0x377e), 0x23 }, + { CCI_REG8(0x377f), 0x02 }, + { CCI_REG8(0x3780), 0xd9 }, + { CCI_REG8(0x3781), 0x03 }, + { CCI_REG8(0x3782), 0xf5 }, + { CCI_REG8(0x3783), 0x06 }, + { CCI_REG8(0x3784), 0xa5 }, + { CCI_REG8(0x3788), 0x0f }, + { CCI_REG8(0x378a), 0xd9 }, + { CCI_REG8(0x378b), 0x03 }, + { CCI_REG8(0x378c), 0xeb }, + { CCI_REG8(0x378d), 0x05 }, + { CCI_REG8(0x378e), 0x87 }, + { CCI_REG8(0x378f), 0x06 }, + { CCI_REG8(0x3790), 0xf5 }, + { CCI_REG8(0x3792), 0x43 }, + { CCI_REG8(0x3794), 0x7a }, + { CCI_REG8(0x3796), 0xa1 }, + { CCI_REG8(0x37b0), 0x36 }, + { CCI_REG8(0x3a00), 0x00 }, }; -static const struct imx335_reg raw10_framefmt_regs[] = { - {0x3050, 0x00}, - {0x319d, 0x00}, - {0x341c, 0xff}, - {0x341d, 0x01}, +static const struct cci_reg_sequence raw10_framefmt_regs[] = { + { IMX335_REG_ADBIT, 0x00 }, + { IMX335_REG_MDBIT, 0x00 }, + { IMX335_REG_ADBIT1, 0x1ff }, }; -static const struct imx335_reg raw12_framefmt_regs[] = { - {0x3050, 0x01}, - {0x319d, 0x01}, - {0x341c, 0x47}, - {0x341d, 0x00}, +static const struct cci_reg_sequence raw12_framefmt_regs[] = { + { IMX335_REG_ADBIT, 0x01 }, + { IMX335_REG_MDBIT, 0x01 }, + { IMX335_REG_ADBIT1, 0x47 }, }; -static const struct imx335_reg mipi_data_rate_1188Mbps[] = { - {0x300c, 0x3b}, - {0x300d, 0x2a}, - {0x314c, 0xc6}, - {0x314d, 0x00}, - {0x315a, 0x02}, - {0x3168, 0xa0}, - {0x316a, 0x7e}, - {0x319e, 0x01}, - {0x3a18, 0x8f}, - {0x3a1a, 0x4f}, - {0x3a1c, 0x47}, - {0x3a1e, 0x37}, - {0x3a1f, 0x01}, - {0x3a20, 0x4f}, - {0x3a22, 0x87}, - {0x3a24, 0x4f}, - {0x3a26, 0x7f}, - {0x3a28, 0x3f}, +static const struct cci_reg_sequence mipi_data_rate_1188Mbps[] = { + { IMX335_REG_BCWAIT_TIME, 0x3b }, + { IMX335_REG_CPWAIT_TIME, 0x2a }, + { IMX335_REG_INCLKSEL1, 0x00c6 }, + { IMX335_REG_INCLKSEL2, 0x02 }, + { IMX335_REG_INCLKSEL3, 0xa0 }, + { IMX335_REG_INCLKSEL4, 0x7e }, + { IMX335_REG_SYSMODE, 0x01 }, + { IMX335_REG_TCLKPOST, 0x8f }, + { IMX335_REG_TCLKPREPARE, 0x4f }, + { IMX335_REG_TCLK_TRAIL, 0x47 }, + { IMX335_REG_TCLK_ZERO, 0x0137 }, + { IMX335_REG_THS_PREPARE, 0x4f }, + { IMX335_REG_THS_ZERO, 0x87 }, + { IMX335_REG_THS_TRAIL, 0x4f }, + { IMX335_REG_THS_EXIT, 0x7f }, + { IMX335_REG_TPLX, 0x3f }, }; -static const struct imx335_reg mipi_data_rate_891Mbps[] = { - {0x300c, 0x3b}, - {0x300d, 0x2a}, - {0x314c, 0x29}, - {0x314d, 0x01}, - {0x315a, 0x06}, - {0x3168, 0xa0}, - {0x316a, 0x7e}, - {0x319e, 0x02}, - {0x3a18, 0x7f}, - {0x3a1a, 0x37}, - {0x3a1c, 0x37}, - {0x3a1e, 0xf7}, - {0x3a20, 0x3f}, - {0x3a22, 0x6f}, - {0x3a24, 0x3f}, - {0x3a26, 0x5f}, - {0x3a28, 0x2f}, +static const struct cci_reg_sequence mipi_data_rate_891Mbps[] = { + { IMX335_REG_BCWAIT_TIME, 0x3b }, + { IMX335_REG_CPWAIT_TIME, 0x2a }, + { IMX335_REG_INCLKSEL1, 0x0129 }, + { IMX335_REG_INCLKSEL2, 0x06 }, + { IMX335_REG_INCLKSEL3, 0xa0 }, + { IMX335_REG_INCLKSEL4, 0x7e }, + { IMX335_REG_SYSMODE, 0x02 }, + { IMX335_REG_TCLKPOST, 0x7f }, + { IMX335_REG_TCLKPREPARE, 0x37 }, + { IMX335_REG_TCLK_TRAIL, 0x37 }, + { IMX335_REG_TCLK_ZERO, 0xf7 }, + { IMX335_REG_THS_PREPARE, 0x3f }, + { IMX335_REG_THS_ZERO, 0x6f }, + { IMX335_REG_THS_TRAIL, 0x3f }, + { IMX335_REG_THS_EXIT, 0x5f }, + { IMX335_REG_TPLX, 0x2f }, }; static const s64 link_freq[] = { @@ -372,10 +409,10 @@ static const u32 imx335_mbus_codes[] = { /* Supported sensor mode configurations */ static const struct imx335_mode supported_mode = { .width = 2592, - .height = 1940, + .height = 1944, .hblank = 342, - .vblank = 2560, - .vblank_min = 2560, + .vblank = 2556, + .vblank_min = 2556, .vblank_max = 133060, .pclk = 396000000, .reg_list = { @@ -396,101 +433,6 @@ static inline struct imx335 *to_imx335(struct v4l2_subdev *subdev) } /** - * imx335_read_reg() - Read registers. - * @imx335: pointer to imx335 device - * @reg: register address - * @len: length of bytes to read. Max supported bytes is 4 - * @val: pointer to register value to be filled. - * - * Big endian register addresses with little endian values. - * - * Return: 0 if successful, error code otherwise. - */ -static int imx335_read_reg(struct imx335 *imx335, u16 reg, u32 len, u32 *val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx335->sd); - struct i2c_msg msgs[2] = {0}; - u8 addr_buf[2] = {0}; - u8 data_buf[4] = {0}; - int ret; - - if (WARN_ON(len > 4)) - return -EINVAL; - - put_unaligned_be16(reg, addr_buf); - - /* Write register address */ - msgs[0].addr = client->addr; - msgs[0].flags = 0; - msgs[0].len = ARRAY_SIZE(addr_buf); - msgs[0].buf = addr_buf; - - /* Read data from register */ - msgs[1].addr = client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = len; - msgs[1].buf = data_buf; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret != ARRAY_SIZE(msgs)) - return -EIO; - - *val = get_unaligned_le32(data_buf); - - return 0; -} - -/** - * imx335_write_reg() - Write register - * @imx335: pointer to imx335 device - * @reg: register address - * @len: length of bytes. Max supported bytes is 4 - * @val: register value - * - * Big endian register addresses with little endian values. - * - * Return: 0 if successful, error code otherwise. - */ -static int imx335_write_reg(struct imx335 *imx335, u16 reg, u32 len, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx335->sd); - u8 buf[6] = {0}; - - if (WARN_ON(len > 4)) - return -EINVAL; - - put_unaligned_be16(reg, buf); - put_unaligned_le32(val, buf + 2); - if (i2c_master_send(client, buf, len + 2) != len + 2) - return -EIO; - - return 0; -} - -/** - * imx335_write_regs() - Write a list of registers - * @imx335: pointer to imx335 device - * @regs: list of registers to be written - * @len: length of registers array - * - * Return: 0 if successful. error code otherwise. - */ -static int imx335_write_regs(struct imx335 *imx335, - const struct imx335_reg *regs, u32 len) -{ - unsigned int i; - int ret; - - for (i = 0; i < len; i++) { - ret = imx335_write_reg(imx335, regs[i].address, 1, regs[i].val); - if (ret) - return ret; - } - - return 0; -} - -/** * imx335_update_controls() - Update control ranges based on streaming mode * @imx335: pointer to imx335 device * @mode: pointer to imx335_mode sensor mode @@ -526,7 +468,8 @@ static int imx335_update_controls(struct imx335 *imx335, static int imx335_update_exp_gain(struct imx335 *imx335, u32 exposure, u32 gain) { u32 lpfr, shutter; - int ret; + int ret_hold; + int ret = 0; lpfr = imx335->vblank + imx335->cur_mode->height; shutter = lpfr - exposure; @@ -534,64 +477,55 @@ static int imx335_update_exp_gain(struct imx335 *imx335, u32 exposure, u32 gain) dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u\n", exposure, gain, shutter, lpfr); - ret = imx335_write_reg(imx335, IMX335_REG_HOLD, 1, 1); - if (ret) - return ret; - - ret = imx335_write_reg(imx335, IMX335_REG_LPFR, 3, lpfr); - if (ret) - goto error_release_group_hold; - - ret = imx335_write_reg(imx335, IMX335_REG_SHUTTER, 3, shutter); - if (ret) - goto error_release_group_hold; - - ret = imx335_write_reg(imx335, IMX335_REG_AGAIN, 2, gain); - -error_release_group_hold: - imx335_write_reg(imx335, IMX335_REG_HOLD, 1, 0); + cci_write(imx335->cci, IMX335_REG_HOLD, 1, &ret); + cci_write(imx335->cci, IMX335_REG_VMAX, lpfr, &ret); + cci_write(imx335->cci, IMX335_REG_SHUTTER, shutter, &ret); + cci_write(imx335->cci, IMX335_REG_GAIN, gain, &ret); + /* + * Unconditionally attempt to release the hold, but track the + * error if the unhold itself fails. + */ + ret_hold = cci_write(imx335->cci, IMX335_REG_HOLD, 0, NULL); + if (ret_hold) + ret = ret_hold; return ret; } static int imx335_update_test_pattern(struct imx335 *imx335, u32 pattern_index) { - int ret; + int ret = 0; if (pattern_index >= ARRAY_SIZE(imx335_tpg_val)) return -EINVAL; if (pattern_index) { - const struct imx335_reg tpg_enable_regs[] = { - { 0x3148, 0x10 }, - { 0x3280, 0x00 }, - { 0x329c, 0x01 }, - { 0x32a0, 0x11 }, - { 0x3302, 0x00 }, - { 0x3303, 0x00 }, - { 0x336c, 0x00 }, + const struct cci_reg_sequence tpg_enable_regs[] = { + { IMX335_REG_TPG_TESTCLKEN, 0x10 }, + { IMX335_REG_TPG_DIG_CLP_MODE, 0x00 }, + { IMX335_REG_TPG_EN_DUOUT, 0x01 }, + { IMX335_REG_TPG_COLORWIDTH, 0x11 }, + { IMX335_REG_BLKLEVEL, 0x00 }, + { IMX335_REG_WRJ_OPEN, 0x00 }, }; - ret = imx335_write_reg(imx335, IMX335_REG_TPG, 1, - imx335_tpg_val[pattern_index]); - if (ret) - return ret; + cci_write(imx335->cci, IMX335_REG_TPG, + imx335_tpg_val[pattern_index], &ret); - ret = imx335_write_regs(imx335, tpg_enable_regs, - ARRAY_SIZE(tpg_enable_regs)); + cci_multi_reg_write(imx335->cci, tpg_enable_regs, + ARRAY_SIZE(tpg_enable_regs), &ret); } else { - const struct imx335_reg tpg_disable_regs[] = { - { 0x3148, 0x00 }, - { 0x3280, 0x01 }, - { 0x329c, 0x00 }, - { 0x32a0, 0x10 }, - { 0x3302, 0x32 }, - { 0x3303, 0x00 }, - { 0x336c, 0x01 }, + const struct cci_reg_sequence tpg_disable_regs[] = { + { IMX335_REG_TPG_TESTCLKEN, 0x00 }, + { IMX335_REG_TPG_DIG_CLP_MODE, 0x01 }, + { IMX335_REG_TPG_EN_DUOUT, 0x00 }, + { IMX335_REG_TPG_COLORWIDTH, 0x10 }, + { IMX335_REG_BLKLEVEL, 0x32 }, + { IMX335_REG_WRJ_OPEN, 0x01 }, }; - ret = imx335_write_regs(imx335, tpg_disable_regs, - ARRAY_SIZE(tpg_disable_regs)); + cci_multi_reg_write(imx335->cci, tpg_disable_regs, + ARRAY_SIZE(tpg_disable_regs), &ret); } return ret; @@ -890,12 +824,14 @@ static int imx335_set_framefmt(struct imx335 *imx335) { switch (imx335->cur_mbus_code) { case MEDIA_BUS_FMT_SRGGB10_1X10: - return imx335_write_regs(imx335, raw10_framefmt_regs, - ARRAY_SIZE(raw10_framefmt_regs)); + return cci_multi_reg_write(imx335->cci, raw10_framefmt_regs, + ARRAY_SIZE(raw10_framefmt_regs), + NULL); case MEDIA_BUS_FMT_SRGGB12_1X12: - return imx335_write_regs(imx335, raw12_framefmt_regs, - ARRAY_SIZE(raw12_framefmt_regs)); + return cci_multi_reg_write(imx335->cci, raw12_framefmt_regs, + ARRAY_SIZE(raw12_framefmt_regs), + NULL); } return -EINVAL; @@ -914,7 +850,8 @@ static int imx335_start_streaming(struct imx335 *imx335) /* Setup PLL */ reg_list = &link_freq_reglist[__ffs(imx335->link_freq_bitmap)]; - ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs); + ret = cci_multi_reg_write(imx335->cci, reg_list->regs, + reg_list->num_of_regs, NULL); if (ret) { dev_err(imx335->dev, "%s failed to set plls\n", __func__); return ret; @@ -922,8 +859,8 @@ static int imx335_start_streaming(struct imx335 *imx335) /* Write sensor mode registers */ reg_list = &imx335->cur_mode->reg_list; - ret = imx335_write_regs(imx335, reg_list->regs, - reg_list->num_of_regs); + ret = cci_multi_reg_write(imx335->cci, reg_list->regs, + reg_list->num_of_regs, NULL); if (ret) { dev_err(imx335->dev, "fail to write initial registers\n"); return ret; @@ -936,6 +873,12 @@ static int imx335_start_streaming(struct imx335 *imx335) return ret; } + /* Configure lanes */ + ret = cci_write(imx335->cci, IMX335_REG_LANEMODE, + imx335->lane_mode, NULL); + if (ret) + return ret; + /* Setup handler will write actual exposure and gain */ ret = __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler); if (ret) { @@ -944,8 +887,8 @@ static int imx335_start_streaming(struct imx335 *imx335) } /* Start streaming */ - ret = imx335_write_reg(imx335, IMX335_REG_MODE_SELECT, - 1, IMX335_MODE_STREAMING); + ret = cci_write(imx335->cci, IMX335_REG_MODE_SELECT, + IMX335_MODE_STREAMING, NULL); if (ret) { dev_err(imx335->dev, "fail to start streaming\n"); return ret; @@ -965,8 +908,8 @@ static int imx335_start_streaming(struct imx335 *imx335) */ static int imx335_stop_streaming(struct imx335 *imx335) { - return imx335_write_reg(imx335, IMX335_REG_MODE_SELECT, - 1, IMX335_MODE_STANDBY); + return cci_write(imx335->cci, IMX335_REG_MODE_SELECT, + IMX335_MODE_STANDBY, NULL); } /** @@ -1017,14 +960,14 @@ error_unlock: static int imx335_detect(struct imx335 *imx335) { int ret; - u32 val; + u64 val; - ret = imx335_read_reg(imx335, IMX335_REG_ID, 2, &val); + ret = cci_read(imx335->cci, IMX335_REG_ID, &val, NULL); if (ret) return ret; if (val != IMX335_ID) { - dev_err(imx335->dev, "chip id mismatch: %x!=%x\n", + dev_err(imx335->dev, "chip id mismatch: %x!=%llx\n", IMX335_ID, val); return -ENXIO; } @@ -1096,7 +1039,14 @@ static int imx335_parse_hw_config(struct imx335 *imx335) if (ret) return ret; - if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX335_NUM_DATA_LANES) { + switch (bus_cfg.bus.mipi_csi2.num_data_lanes) { + case 2: + imx335->lane_mode = IMX335_2LANE; + break; + case 4: + imx335->lane_mode = IMX335_4LANE; + break; + default: dev_err(imx335->dev, "number of CSI2 data lanes %d is not supported\n", bus_cfg.bus.mipi_csi2.num_data_lanes); @@ -1208,10 +1158,16 @@ static int imx335_init_controls(struct imx335 *imx335) { struct v4l2_ctrl_handler *ctrl_hdlr = &imx335->ctrl_handler; const struct imx335_mode *mode = imx335->cur_mode; + struct v4l2_fwnode_device_properties props; u32 lpfr; int ret; - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 7); + ret = v4l2_fwnode_device_parse(imx335->dev, &props); + if (ret) + return ret; + + /* v4l2_fwnode_device_properties can add two more controls */ + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9); if (ret) return ret; @@ -1228,6 +1184,14 @@ static int imx335_init_controls(struct imx335 *imx335) IMX335_EXPOSURE_STEP, IMX335_EXPOSURE_DEFAULT); + /* + * The sensor has an analog gain and a digital gain, both controlled + * through a single gain value, expressed in 0.3dB increments. Values + * from 0.0dB (0) to 30.0dB (100) apply analog gain only, higher values + * up to 72.0dB (240) add further digital gain. Limit the range to + * analog gain only, support for digital gain can be added separately + * if needed. + */ imx335->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, @@ -1276,6 +1240,8 @@ static int imx335_init_controls(struct imx335 *imx335) if (imx335->hblank_ctrl) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx335_ctrl_ops, &props); + if (ctrl_hdlr->error) { dev_err(imx335->dev, "control init failed: %d\n", ctrl_hdlr->error); @@ -1304,6 +1270,11 @@ static int imx335_probe(struct i2c_client *client) return -ENOMEM; imx335->dev = &client->dev; + imx335->cci = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(imx335->cci)) { + dev_err(imx335->dev, "Unable to initialize I2C\n"); + return -ENODEV; + } /* Initialize subdev */ v4l2_i2c_subdev_init(&imx335->sd, client, &imx335_subdev_ops); diff --git a/drivers/media/i2c/max9271.h b/drivers/media/i2c/max9271.h index dc5e4e70ba6f5c..0bf1d40811eba9 100644 --- a/drivers/media/i2c/max9271.h +++ b/drivers/media/i2c/max9271.h @@ -8,6 +8,9 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ +#ifndef __MEDIA_I2C_MAX9271_H__ +#define __MEDIA_I2C_MAX9271_H__ + #include <linux/i2c.h> #define MAX9271_DEFAULT_ADDR 0x40 @@ -231,3 +234,5 @@ int max9271_set_deserializer_address(struct max9271_device *dev, u8 addr); * Return 0 on success or a negative error code on failure */ int max9271_set_translation(struct max9271_device *dev, u8 source, u8 dest); + +#endif /* __MEDIA_I2C_MAX9271_H__ */ diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index a857763c7984c5..3ae0ea58668d9f 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -75,6 +75,8 @@ #define OV2680_ACTIVE_START_TOP 8 #define OV2680_MIN_CROP_WIDTH 2 #define OV2680_MIN_CROP_HEIGHT 2 +#define OV2680_MIN_VBLANK 4 +#define OV2680_MAX_VBLANK 0xffff /* Fixed pre-div of 1/2 */ #define OV2680_PLL_PREDIV0 2 @@ -84,10 +86,7 @@ /* 66MHz pixel clock: 66MHz / 1704 * 1294 = 30fps */ #define OV2680_PIXELS_PER_LINE 1704 -#define OV2680_LINES_PER_FRAME 1294 - -/* If possible send 16 extra rows / lines to the ISP as padding */ -#define OV2680_END_MARGIN 16 +#define OV2680_LINES_PER_FRAME_30FPS 1294 /* Max exposure time is VTS - 8 */ #define OV2680_INTEGRATION_TIME_MARGIN 8 @@ -130,6 +129,8 @@ struct ov2680_ctrls { struct v4l2_ctrl *test_pattern; struct v4l2_ctrl *link_freq; struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; }; struct ov2680_mode { @@ -143,8 +144,6 @@ struct ov2680_mode { u16 v_end; u16 h_output_size; u16 v_output_size; - u16 hts; - u16 vts; }; struct ov2680_dev { @@ -359,15 +358,11 @@ static void ov2680_calc_mode(struct ov2680_dev *sensor) sensor->mode.v_start = (sensor->mode.crop.top + (sensor->mode.crop.height - height) / 2) & ~1; sensor->mode.h_end = - min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1, - OV2680_NATIVE_WIDTH - 1); + min(sensor->mode.h_start + width - 1, OV2680_NATIVE_WIDTH - 1); sensor->mode.v_end = - min(sensor->mode.v_start + height + OV2680_END_MARGIN - 1, - OV2680_NATIVE_HEIGHT - 1); + min(sensor->mode.v_start + height - 1, OV2680_NATIVE_HEIGHT - 1); sensor->mode.h_output_size = orig_width; sensor->mode.v_output_size = orig_height; - sensor->mode.hts = OV2680_PIXELS_PER_LINE; - sensor->mode.vts = OV2680_LINES_PER_FRAME; } static int ov2680_set_mode(struct ov2680_dev *sensor) @@ -402,9 +397,8 @@ static int ov2680_set_mode(struct ov2680_dev *sensor) cci_write(sensor->regmap, OV2680_REG_VERTICAL_OUTPUT_SIZE, sensor->mode.v_output_size, &ret); cci_write(sensor->regmap, OV2680_REG_TIMING_HTS, - sensor->mode.hts, &ret); - cci_write(sensor->regmap, OV2680_REG_TIMING_VTS, - sensor->mode.vts, &ret); + OV2680_PIXELS_PER_LINE, &ret); + /* VTS gets set by the vblank ctrl */ cci_write(sensor->regmap, OV2680_REG_ISP_X_WIN, 0, &ret); cci_write(sensor->regmap, OV2680_REG_ISP_Y_WIN, 0, &ret); cci_write(sensor->regmap, OV2680_REG_X_INC, inc, &ret); @@ -478,6 +472,15 @@ static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) NULL); } +static int ov2680_exposure_update_range(struct ov2680_dev *sensor) +{ + int exp_max = sensor->mode.fmt.height + sensor->ctrls.vblank->val - + OV2680_INTEGRATION_TIME_MARGIN; + + return __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 0, exp_max, + 1, exp_max); +} + static int ov2680_stream_enable(struct ov2680_dev *sensor) { int ret; @@ -644,7 +647,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *try_fmt; const struct v4l2_rect *crop; unsigned int width, height; - int ret = 0; + int def, max, ret = 0; crop = __ov2680_get_pad_crop(sensor, sd_state, format->pad, format->which); @@ -673,6 +676,27 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, sensor->mode.fmt = format->format; ov2680_calc_mode(sensor); + /* vblank range is height dependent adjust and reset to default */ + max = OV2680_MAX_VBLANK - height; + def = OV2680_LINES_PER_FRAME_30FPS - height; + ret = __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV2680_MIN_VBLANK, + max, 1, def); + if (ret) + goto unlock; + + ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, def); + if (ret) + goto unlock; + + /* exposure range depends on vts which may have changed */ + ret = ov2680_exposure_update_range(sensor); + if (ret) + goto unlock; + + /* adjust hblank value for new width */ + def = OV2680_PIXELS_PER_LINE - width; + ret = __v4l2_ctrl_modify_range(sensor->ctrls.hblank, def, def, 1, def); + unlock: mutex_unlock(&sensor->lock); @@ -842,6 +866,13 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) struct ov2680_dev *sensor = to_ov2680_dev(sd); int ret; + /* Update exposure range on vblank changes */ + if (ctrl->id == V4L2_CID_VBLANK) { + ret = ov2680_exposure_update_range(sensor); + if (ret) + return ret; + } + /* Only apply changes to the controls if the device is powered up */ if (!pm_runtime_get_if_in_use(sensor->sd.dev)) { ov2680_set_bayer_order(sensor, &sensor->mode.fmt); @@ -864,6 +895,10 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_TEST_PATTERN: ret = ov2680_test_pattern_set(sensor, ctrl->val); break; + case V4L2_CID_VBLANK: + ret = cci_write(sensor->regmap, OV2680_REG_TIMING_VTS, + sensor->mode.fmt.height + ctrl->val, NULL); + break; default: ret = -EINVAL; break; @@ -922,8 +957,8 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops; struct ov2680_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; - int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN; - int ret = 0; + struct v4l2_fwnode_device_properties props; + int def, max, ret = 0; v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_subdev_ops); sensor->sd.internal_ops = &ov2680_internal_ops; @@ -948,8 +983,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, test_pattern_menu); + max = OV2680_LINES_PER_FRAME_30FPS - OV2680_INTEGRATION_TIME_MARGIN; ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, - 0, exp_max, 1, exp_max); + 0, max, 1, max); ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 1023, 1, 250); @@ -960,6 +996,21 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) 0, sensor->pixel_rate, 1, sensor->pixel_rate); + max = OV2680_MAX_VBLANK - OV2680_DEFAULT_HEIGHT; + def = OV2680_LINES_PER_FRAME_30FPS - OV2680_DEFAULT_HEIGHT; + ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, + OV2680_MIN_VBLANK, max, 1, def); + + def = OV2680_PIXELS_PER_LINE - OV2680_DEFAULT_WIDTH; + ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, + def, def, 1, def); + + ret = v4l2_fwnode_device_parse(sensor->dev, &props); + if (ret) + goto cleanup_entity; + + v4l2_ctrl_new_fwnode_properties(hdl, ops, &props); + if (hdl->error) { ret = hdl->error; goto cleanup_entity; @@ -968,6 +1019,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; sensor->sd.ctrl_handler = hdl; @@ -1116,13 +1168,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) sensor->pixel_rate = sensor->link_freq[0] * 2; do_div(sensor->pixel_rate, 10); - /* Verify bus cfg */ - if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1) { - ret = dev_err_probe(dev, -EINVAL, - "only a 1-lane CSI2 config is supported"); - goto out_free_bus_cfg; - } - if (!bus_cfg.nr_of_link_frequencies) { dev_warn(dev, "Consider passing 'link-frequencies' in DT\n"); goto skip_link_freq_validation; diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 403091651885a5..1c3a449f935462 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -3,7 +3,7 @@ * ov4689 driver * * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. - * Copyright (C) 2022 Mikhail Rudenko + * Copyright (C) 2022, 2024 Mikhail Rudenko */ #include <linux/clk.h> @@ -15,45 +15,86 @@ #include <linux/regulator/consumer.h> #include <media/media-entity.h> #include <media/v4l2-async.h> +#include <media/v4l2-cci.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-subdev.h> #include <media/v4l2-fwnode.h> -#define CHIP_ID 0x004688 -#define OV4689_REG_CHIP_ID 0x300a - -#define OV4689_XVCLK_FREQ 24000000 - -#define OV4689_REG_CTRL_MODE 0x0100 +#define OV4689_REG_CTRL_MODE CCI_REG8(0x0100) #define OV4689_MODE_SW_STANDBY 0x0 #define OV4689_MODE_STREAMING BIT(0) -#define OV4689_REG_EXPOSURE 0x3500 +#define OV4689_REG_CHIP_ID CCI_REG16(0x300a) +#define CHIP_ID 0x004688 + +#define OV4689_REG_EXPOSURE CCI_REG24(0x3500) #define OV4689_EXPOSURE_MIN 4 #define OV4689_EXPOSURE_STEP 1 -#define OV4689_VTS_MAX 0x7fff -#define OV4689_REG_GAIN_H 0x3508 -#define OV4689_REG_GAIN_L 0x3509 -#define OV4689_GAIN_H_MASK 0x07 -#define OV4689_GAIN_H_SHIFT 8 -#define OV4689_GAIN_L_MASK 0xff +#define OV4689_REG_GAIN CCI_REG16(0x3508) #define OV4689_GAIN_STEP 1 #define OV4689_GAIN_DEFAULT 0x80 -#define OV4689_REG_TEST_PATTERN 0x5040 -#define OV4689_TEST_PATTERN_ENABLE 0x80 -#define OV4689_TEST_PATTERN_DISABLE 0x0 +#define OV4689_REG_DIG_GAIN CCI_REG16(0x352a) +#define OV4689_DIG_GAIN_MIN 1 +#define OV4689_DIG_GAIN_MAX 0x7fff +#define OV4689_DIG_GAIN_STEP 1 +#define OV4689_DIG_GAIN_DEFAULT 0x800 -#define OV4689_REG_VTS 0x380e +#define OV4689_REG_H_CROP_START CCI_REG16(0x3800) +#define OV4689_REG_V_CROP_START CCI_REG16(0x3802) +#define OV4689_REG_H_CROP_END CCI_REG16(0x3804) +#define OV4689_REG_V_CROP_END CCI_REG16(0x3806) +#define OV4689_REG_H_OUTPUT_SIZE CCI_REG16(0x3808) +#define OV4689_REG_V_OUTPUT_SIZE CCI_REG16(0x380a) -#define REG_NULL 0xFFFF +#define OV4689_REG_HTS CCI_REG16(0x380c) +#define OV4689_HTS_DIVIDER 4 +#define OV4689_HTS_MAX 0x7fff -#define OV4689_REG_VALUE_08BIT 1 -#define OV4689_REG_VALUE_16BIT 2 -#define OV4689_REG_VALUE_24BIT 3 +#define OV4689_REG_VTS CCI_REG16(0x380e) +#define OV4689_VTS_MAX 0x7fff + +#define OV4689_REG_H_WIN_OFF CCI_REG16(0x3810) +#define OV4689_REG_V_WIN_OFF CCI_REG16(0x3812) + +#define OV4689_REG_TIMING_FORMAT1 CCI_REG8(0x3820) /* Vertical */ +#define OV4689_REG_TIMING_FORMAT2 CCI_REG8(0x3821) /* Horizontal */ +#define OV4689_TIMING_FLIP_MASK GENMASK(2, 1) +#define OV4689_TIMING_FLIP_ARRAY BIT(1) +#define OV4689_TIMING_FLIP_DIGITAL BIT(2) +#define OV4689_TIMING_FLIP_BOTH (OV4689_TIMING_FLIP_ARRAY |\ + OV4689_TIMING_FLIP_DIGITAL) + +#define OV4689_REG_ANCHOR_LEFT_START CCI_REG16(0x4020) +#define OV4689_ANCHOR_LEFT_START_DEF 576 +#define OV4689_REG_ANCHOR_LEFT_END CCI_REG16(0x4022) +#define OV4689_ANCHOR_LEFT_END_DEF 831 +#define OV4689_REG_ANCHOR_RIGHT_START CCI_REG16(0x4024) +#define OV4689_ANCHOR_RIGHT_START_DEF 1984 +#define OV4689_REG_ANCHOR_RIGHT_END CCI_REG16(0x4026) +#define OV4689_ANCHOR_RIGHT_END_DEF 2239 + +#define OV4689_REG_VFIFO_CTRL_01 CCI_REG8(0x4601) + +#define OV4689_REG_WB_GAIN_RED CCI_REG16(0x500c) +#define OV4689_REG_WB_GAIN_BLUE CCI_REG16(0x5010) +#define OV4689_WB_GAIN_MIN 1 +#define OV4689_WB_GAIN_MAX 0xfff +#define OV4689_WB_GAIN_STEP 1 +#define OV4689_WB_GAIN_DEFAULT 0x400 + +#define OV4689_REG_TEST_PATTERN CCI_REG8(0x5040) +#define OV4689_TEST_PATTERN_ENABLE 0x80 +#define OV4689_TEST_PATTERN_DISABLE 0x0 #define OV4689_LANES 4 +#define OV4689_XVCLK_FREQ 24000000 + +#define OV4689_PIXEL_ARRAY_WIDTH 2720 +#define OV4689_PIXEL_ARRAY_HEIGHT 1536 +#define OV4689_DUMMY_ROWS 8 /* 8 dummy rows on each side */ +#define OV4689_DUMMY_COLUMNS 16 /* 16 dummy columns on each side */ static const char *const ov4689_supply_names[] = { "avdd", /* Analog power */ @@ -61,11 +102,6 @@ static const char *const ov4689_supply_names[] = { "dvdd", /* Digital core power */ }; -struct regval { - u16 addr; - u8 val; -}; - enum ov4689_mode_id { OV4689_MODE_2688_1520 = 0, OV4689_NUM_MODES, @@ -75,20 +111,18 @@ struct ov4689_mode { enum ov4689_mode_id id; u32 width; u32 height; - u32 max_fps; u32 hts_def; + u32 hts_min; u32 vts_def; u32 exp_def; u32 pixel_rate; - u32 sensor_width; - u32 sensor_height; - u32 crop_top; - u32 crop_left; - const struct regval *reg_list; + const struct cci_reg_sequence *reg_list; + unsigned int num_regs; }; struct ov4689 { - struct i2c_client *client; + struct device *dev; + struct regmap *regmap; struct clk *xvclk; struct gpio_desc *reset_gpio; struct gpio_desc *pwdn_gpio; @@ -99,7 +133,6 @@ struct ov4689 { u32 clock_rate; - struct mutex mutex; /* lock to protect ctrls and cur_mode */ struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *exposure; @@ -119,95 +152,108 @@ struct ov4689_gain_range { /* * Xclk 24Mhz - * max_framerate 30fps + * max_framerate 90fps * mipi_datarate per lane 1008Mbps */ -static const struct regval ov4689_2688x1520_regs[] = { - {0x0103, 0x01}, {0x3638, 0x00}, {0x0300, 0x00}, - {0x0302, 0x2a}, {0x0303, 0x00}, {0x0304, 0x03}, - {0x030b, 0x00}, {0x030d, 0x1e}, {0x030e, 0x04}, - {0x030f, 0x01}, {0x0312, 0x01}, {0x031e, 0x00}, - {0x3000, 0x20}, {0x3002, 0x00}, {0x3018, 0x72}, - {0x3020, 0x93}, {0x3021, 0x03}, {0x3022, 0x01}, - {0x3031, 0x0a}, {0x303f, 0x0c}, {0x3305, 0xf1}, - {0x3307, 0x04}, {0x3309, 0x29}, {0x3500, 0x00}, - {0x3501, 0x60}, {0x3502, 0x00}, {0x3503, 0x04}, - {0x3504, 0x00}, {0x3505, 0x00}, {0x3506, 0x00}, - {0x3507, 0x00}, {0x3508, 0x00}, {0x3509, 0x80}, - {0x350a, 0x00}, {0x350b, 0x00}, {0x350c, 0x00}, - {0x350d, 0x00}, {0x350e, 0x00}, {0x350f, 0x80}, - {0x3510, 0x00}, {0x3511, 0x00}, {0x3512, 0x00}, - {0x3513, 0x00}, {0x3514, 0x00}, {0x3515, 0x80}, - {0x3516, 0x00}, {0x3517, 0x00}, {0x3518, 0x00}, - {0x3519, 0x00}, {0x351a, 0x00}, {0x351b, 0x80}, - {0x351c, 0x00}, {0x351d, 0x00}, {0x351e, 0x00}, - {0x351f, 0x00}, {0x3520, 0x00}, {0x3521, 0x80}, - {0x3522, 0x08}, {0x3524, 0x08}, {0x3526, 0x08}, - {0x3528, 0x08}, {0x352a, 0x08}, {0x3602, 0x00}, - {0x3603, 0x40}, {0x3604, 0x02}, {0x3605, 0x00}, - {0x3606, 0x00}, {0x3607, 0x00}, {0x3609, 0x12}, - {0x360a, 0x40}, {0x360c, 0x08}, {0x360f, 0xe5}, - {0x3608, 0x8f}, {0x3611, 0x00}, {0x3613, 0xf7}, - {0x3616, 0x58}, {0x3619, 0x99}, {0x361b, 0x60}, - {0x361c, 0x7a}, {0x361e, 0x79}, {0x361f, 0x02}, - {0x3632, 0x00}, {0x3633, 0x10}, {0x3634, 0x10}, - {0x3635, 0x10}, {0x3636, 0x15}, {0x3646, 0x86}, - {0x364a, 0x0b}, {0x3700, 0x17}, {0x3701, 0x22}, - {0x3703, 0x10}, {0x370a, 0x37}, {0x3705, 0x00}, - {0x3706, 0x63}, {0x3709, 0x3c}, {0x370b, 0x01}, - {0x370c, 0x30}, {0x3710, 0x24}, {0x3711, 0x0c}, - {0x3716, 0x00}, {0x3720, 0x28}, {0x3729, 0x7b}, - {0x372a, 0x84}, {0x372b, 0xbd}, {0x372c, 0xbc}, - {0x372e, 0x52}, {0x373c, 0x0e}, {0x373e, 0x33}, - {0x3743, 0x10}, {0x3744, 0x88}, {0x3745, 0xc0}, - {0x374a, 0x43}, {0x374c, 0x00}, {0x374e, 0x23}, - {0x3751, 0x7b}, {0x3752, 0x84}, {0x3753, 0xbd}, - {0x3754, 0xbc}, {0x3756, 0x52}, {0x375c, 0x00}, - {0x3760, 0x00}, {0x3761, 0x00}, {0x3762, 0x00}, - {0x3763, 0x00}, {0x3764, 0x00}, {0x3767, 0x04}, - {0x3768, 0x04}, {0x3769, 0x08}, {0x376a, 0x08}, - {0x376b, 0x20}, {0x376c, 0x00}, {0x376d, 0x00}, - {0x376e, 0x00}, {0x3773, 0x00}, {0x3774, 0x51}, - {0x3776, 0xbd}, {0x3777, 0xbd}, {0x3781, 0x18}, - {0x3783, 0x25}, {0x3798, 0x1b}, {0x3800, 0x00}, - {0x3801, 0x08}, {0x3802, 0x00}, {0x3803, 0x04}, - {0x3804, 0x0a}, {0x3805, 0x97}, {0x3806, 0x05}, - {0x3807, 0xfb}, {0x3808, 0x0a}, {0x3809, 0x80}, - {0x380a, 0x05}, {0x380b, 0xf0}, {0x380c, 0x0a}, - {0x380d, 0x0e}, {0x380e, 0x06}, {0x380f, 0x12}, - {0x3810, 0x00}, {0x3811, 0x08}, {0x3812, 0x00}, - {0x3813, 0x04}, {0x3814, 0x01}, {0x3815, 0x01}, - {0x3819, 0x01}, {0x3820, 0x00}, {0x3821, 0x06}, - {0x3829, 0x00}, {0x382a, 0x01}, {0x382b, 0x01}, - {0x382d, 0x7f}, {0x3830, 0x04}, {0x3836, 0x01}, - {0x3837, 0x00}, {0x3841, 0x02}, {0x3846, 0x08}, - {0x3847, 0x07}, {0x3d85, 0x36}, {0x3d8c, 0x71}, - {0x3d8d, 0xcb}, {0x3f0a, 0x00}, {0x4000, 0xf1}, - {0x4001, 0x40}, {0x4002, 0x04}, {0x4003, 0x14}, - {0x400e, 0x00}, {0x4011, 0x00}, {0x401a, 0x00}, - {0x401b, 0x00}, {0x401c, 0x00}, {0x401d, 0x00}, - {0x401f, 0x00}, {0x4020, 0x00}, {0x4021, 0x10}, - {0x4022, 0x07}, {0x4023, 0xcf}, {0x4024, 0x09}, - {0x4025, 0x60}, {0x4026, 0x09}, {0x4027, 0x6f}, - {0x4028, 0x00}, {0x4029, 0x02}, {0x402a, 0x06}, - {0x402b, 0x04}, {0x402c, 0x02}, {0x402d, 0x02}, - {0x402e, 0x0e}, {0x402f, 0x04}, {0x4302, 0xff}, - {0x4303, 0xff}, {0x4304, 0x00}, {0x4305, 0x00}, - {0x4306, 0x00}, {0x4308, 0x02}, {0x4500, 0x6c}, - {0x4501, 0xc4}, {0x4502, 0x40}, {0x4503, 0x01}, - {0x4601, 0xa7}, {0x4800, 0x04}, {0x4813, 0x08}, - {0x481f, 0x40}, {0x4829, 0x78}, {0x4837, 0x10}, - {0x4b00, 0x2a}, {0x4b0d, 0x00}, {0x4d00, 0x04}, - {0x4d01, 0x42}, {0x4d02, 0xd1}, {0x4d03, 0x93}, - {0x4d04, 0xf5}, {0x4d05, 0xc1}, {0x5000, 0xf3}, - {0x5001, 0x11}, {0x5004, 0x00}, {0x500a, 0x00}, - {0x500b, 0x00}, {0x5032, 0x00}, {0x5040, 0x00}, - {0x5050, 0x0c}, {0x5500, 0x00}, {0x5501, 0x10}, - {0x5502, 0x01}, {0x5503, 0x0f}, {0x8000, 0x00}, - {0x8001, 0x00}, {0x8002, 0x00}, {0x8003, 0x00}, - {0x8004, 0x00}, {0x8005, 0x00}, {0x8006, 0x00}, - {0x8007, 0x00}, {0x8008, 0x00}, {0x3638, 0x00}, - {REG_NULL, 0x00}, +static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { + /* System control*/ + { CCI_REG8(0x0103), 0x01 }, /* SC_CTRL0103 software_reset = 1 */ + { CCI_REG8(0x3000), 0x20 }, /* SC_CMMN_PAD_OEN0 FSIN_output_enable = 1 */ + { CCI_REG8(0x3021), 0x03 }, /* + * SC_CMMN_MISC_CTRL fst_stby_ctr = 0, + * sleep_no_latch_enable = 0 + */ + + /* AEC PK */ + { CCI_REG8(0x3503), 0x04 }, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */ + + /* ADC and analog control*/ + { CCI_REG8(0x3603), 0x40 }, + { CCI_REG8(0x3604), 0x02 }, + { CCI_REG8(0x3609), 0x12 }, + { CCI_REG8(0x360c), 0x08 }, + { CCI_REG8(0x360f), 0xe5 }, + { CCI_REG8(0x3608), 0x8f }, + { CCI_REG8(0x3611), 0x00 }, + { CCI_REG8(0x3613), 0xf7 }, + { CCI_REG8(0x3616), 0x58 }, + { CCI_REG8(0x3619), 0x99 }, + { CCI_REG8(0x361b), 0x60 }, + { CCI_REG8(0x361e), 0x79 }, + { CCI_REG8(0x3634), 0x10 }, + { CCI_REG8(0x3635), 0x10 }, + { CCI_REG8(0x3636), 0x15 }, + { CCI_REG8(0x3646), 0x86 }, + { CCI_REG8(0x364a), 0x0b }, + + /* Sensor control */ + { CCI_REG8(0x3700), 0x17 }, + { CCI_REG8(0x3701), 0x22 }, + { CCI_REG8(0x3703), 0x10 }, + { CCI_REG8(0x370a), 0x37 }, + { CCI_REG8(0x3706), 0x63 }, + { CCI_REG8(0x3709), 0x3c }, + { CCI_REG8(0x370c), 0x30 }, + { CCI_REG8(0x3710), 0x24 }, + { CCI_REG8(0x3720), 0x28 }, + { CCI_REG8(0x3729), 0x7b }, + { CCI_REG8(0x372b), 0xbd }, + { CCI_REG8(0x372c), 0xbc }, + { CCI_REG8(0x372e), 0x52 }, + { CCI_REG8(0x373c), 0x0e }, + { CCI_REG8(0x373e), 0x33 }, + { CCI_REG8(0x3743), 0x10 }, + { CCI_REG8(0x3744), 0x88 }, + { CCI_REG8(0x3745), 0xc0 }, + { CCI_REG8(0x374c), 0x00 }, + { CCI_REG8(0x374e), 0x23 }, + { CCI_REG8(0x3751), 0x7b }, + { CCI_REG8(0x3753), 0xbd }, + { CCI_REG8(0x3754), 0xbc }, + { CCI_REG8(0x3756), 0x52 }, + { CCI_REG8(0x376b), 0x20 }, + { CCI_REG8(0x3774), 0x51 }, + { CCI_REG8(0x3776), 0xbd }, + { CCI_REG8(0x3777), 0xbd }, + { CCI_REG8(0x3781), 0x18 }, + { CCI_REG8(0x3783), 0x25 }, + { CCI_REG8(0x3798), 0x1b }, + + /* Timing control */ + { CCI_REG8(0x3819), 0x01 }, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ + + /* OTP control */ + { CCI_REG8(0x3d85), 0x36 }, /* OTP_REG85 OTP_power_up_load_setting_enable = 1, + * OTP_power_up_load_data_enable = 1, + * OTP_bist_select = 1 (compare with zero) + */ + { CCI_REG8(0x3d8c), 0x71 }, /* OTP_SETTING_STT_ADDRESS_H */ + { CCI_REG8(0x3d8d), 0xcb }, /* OTP_SETTING_STT_ADDRESS_L */ + + /* BLC registers*/ + { CCI_REG8(0x4001), 0x40 }, /* DEBUG_MODE */ + { CCI_REG8(0x401b), 0x00 }, /* DEBUG_MODE */ + { CCI_REG8(0x401d), 0x00 }, /* DEBUG_MODE */ + { CCI_REG8(0x401f), 0x00 }, /* DEBUG_MODE */ + + /* ADC sync control */ + { CCI_REG8(0x4500), 0x6c }, /* ADC_SYNC_CTRL */ + { CCI_REG8(0x4503), 0x01 }, /* ADC_SYNC_CTRL */ + + /* Temperature monitor */ + { CCI_REG8(0x4d00), 0x04 }, /* TPM_CTRL_00 tmp_slope[15:8] = 0x04 */ + { CCI_REG8(0x4d01), 0x42 }, /* TPM_CTRL_01 tmp_slope[7:0] = 0x42 */ + { CCI_REG8(0x4d02), 0xd1 }, /* TPM_CTRL_02 tpm_offset[31:24] = 0xd1 */ + { CCI_REG8(0x4d03), 0x93 }, /* TPM_CTRL_03 tpm_offset[23:16] = 0x93 */ + { CCI_REG8(0x4d04), 0xf5 }, /* TPM_CTRL_04 tpm_offset[15:8] = 0xf5 */ + { CCI_REG8(0x4d05), 0xc1 }, /* TPM_CTRL_05 tpm_offset[7:0] = 0xc1 */ + + /* pre-ISP control */ + { CCI_REG8(0x5050), 0x0c }, /* DEBUG_MODE */ + + /* OTP-DPC control */ + { CCI_REG8(0x5501), 0x10 }, /* OTP_DPC_START_L otp_start_address[7:0] = 0x10 */ + { CCI_REG8(0x5503), 0x0f }, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ }; static const struct ov4689_mode supported_modes[] = { @@ -215,16 +261,13 @@ static const struct ov4689_mode supported_modes[] = { .id = OV4689_MODE_2688_1520, .width = 2688, .height = 1520, - .sensor_width = 2720, - .sensor_height = 1536, - .crop_top = 8, - .crop_left = 16, - .max_fps = 30, .exp_def = 1536, - .hts_def = 4 * 2574, + .hts_def = 10296, + .hts_min = 3432, .vts_def = 1554, .pixel_rate = 480000000, .reg_list = ov4689_2688x1520_regs, + .num_regs = ARRAY_SIZE(ov4689_2688x1520_regs), }, }; @@ -277,83 +320,6 @@ static const struct ov4689_gain_range ov4689_gain_ranges[] = { }, }; -/* Write registers up to 4 at a time */ -static int ov4689_write_reg(struct i2c_client *client, u16 reg, u32 len, - u32 val) -{ - u32 buf_i, val_i; - __be32 val_be; - u8 *val_p; - u8 buf[6]; - - if (len > 4) - return -EINVAL; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - - val_be = cpu_to_be32(val); - val_p = (u8 *)&val_be; - 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; -} - -static int ov4689_write_array(struct i2c_client *client, - const struct regval *regs) -{ - int ret = 0; - u32 i; - - for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) - ret = ov4689_write_reg(client, regs[i].addr, - OV4689_REG_VALUE_08BIT, regs[i].val); - - return ret; -} - -/* Read registers up to 4 at a time */ -static int ov4689_read_reg(struct i2c_client *client, u16 reg, unsigned int len, - u32 *val) -{ - __be16 reg_addr_be = cpu_to_be16(reg); - struct i2c_msg msgs[2]; - __be32 data_be = 0; - u8 *data_be_p; - int ret; - - if (len > 4 || !len) - 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; -} - static void ov4689_fill_fmt(const struct ov4689_mode *mode, struct v4l2_mbus_framefmt *fmt) { @@ -376,19 +342,6 @@ static int ov4689_set_fmt(struct v4l2_subdev *sd, return 0; } -static int ov4689_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; - struct ov4689 *ov4689 = to_ov4689(sd); - - /* only one mode supported for now */ - ov4689_fill_fmt(ov4689->cur_mode, mbus_fmt); - - return 0; -} - static int ov4689_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) @@ -427,16 +380,14 @@ static int ov4689_enable_test_pattern(struct ov4689 *ov4689, u32 pattern) else val = OV4689_TEST_PATTERN_DISABLE; - return ov4689_write_reg(ov4689->client, OV4689_REG_TEST_PATTERN, - OV4689_REG_VALUE_08BIT, val); + return cci_write(ov4689->regmap, OV4689_REG_TEST_PATTERN, + val, NULL); } static int ov4689_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { - const struct ov4689_mode *mode = to_ov4689(sd)->cur_mode; - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; @@ -444,63 +395,114 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, case V4L2_SEL_TGT_CROP_BOUNDS: sel->r.top = 0; sel->r.left = 0; - sel->r.width = mode->sensor_width; - sel->r.height = mode->sensor_height; + sel->r.width = OV4689_PIXEL_ARRAY_WIDTH; + sel->r.height = OV4689_PIXEL_ARRAY_HEIGHT; return 0; case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.top = mode->crop_top; - sel->r.left = mode->crop_left; - sel->r.width = mode->width; - sel->r.height = mode->height; + sel->r.top = OV4689_DUMMY_ROWS; + sel->r.left = OV4689_DUMMY_COLUMNS; + sel->r.width = + OV4689_PIXEL_ARRAY_WIDTH - 2 * OV4689_DUMMY_COLUMNS; + sel->r.height = + OV4689_PIXEL_ARRAY_HEIGHT - 2 * OV4689_DUMMY_ROWS; return 0; } return -EINVAL; } +static int ov4689_setup_timings(struct ov4689 *ov4689) +{ + const struct ov4689_mode *mode = ov4689->cur_mode; + struct regmap *rm = ov4689->regmap; + int ret = 0; + + cci_write(rm, OV4689_REG_H_CROP_START, 8, &ret); + cci_write(rm, OV4689_REG_V_CROP_START, 8, &ret); + cci_write(rm, OV4689_REG_H_CROP_END, 2711, &ret); + cci_write(rm, OV4689_REG_V_CROP_END, 1531, &ret); + + cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, mode->width, &ret); + cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, mode->height, &ret); + + cci_write(rm, OV4689_REG_H_WIN_OFF, 8, &ret); + cci_write(rm, OV4689_REG_V_WIN_OFF, 4, &ret); + + cci_write(rm, OV4689_REG_VFIFO_CTRL_01, 167, &ret); + + return ret; +} + +static int ov4689_setup_blc_anchors(struct ov4689 *ov4689) +{ + struct regmap *rm = ov4689->regmap; + int ret = 0; + + cci_write(rm, OV4689_REG_ANCHOR_LEFT_START, 16, &ret); + cci_write(rm, OV4689_REG_ANCHOR_LEFT_END, 1999, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_START, 2400, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_END, 2415, &ret); + + return ret; +} + static int ov4689_s_stream(struct v4l2_subdev *sd, int on) { struct ov4689 *ov4689 = to_ov4689(sd); - struct i2c_client *client = ov4689->client; + struct v4l2_subdev_state *sd_state; + struct device *dev = ov4689->dev; int ret = 0; - mutex_lock(&ov4689->mutex); + sd_state = v4l2_subdev_lock_and_get_active_state(&ov4689->subdev); if (on) { - ret = pm_runtime_resume_and_get(&client->dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) goto unlock_and_return; - ret = ov4689_write_array(ov4689->client, - ov4689->cur_mode->reg_list); + ret = cci_multi_reg_write(ov4689->regmap, + ov4689->cur_mode->reg_list, + ov4689->cur_mode->num_regs, + NULL); + if (ret) { + pm_runtime_put(dev); + goto unlock_and_return; + } + + ret = ov4689_setup_timings(ov4689); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); + goto unlock_and_return; + } + + ret = ov4689_setup_blc_anchors(ov4689); + if (ret) { + pm_runtime_put(dev); goto unlock_and_return; } ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); goto unlock_and_return; } - ret = ov4689_write_reg(ov4689->client, OV4689_REG_CTRL_MODE, - OV4689_REG_VALUE_08BIT, - OV4689_MODE_STREAMING); + ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, + OV4689_MODE_STREAMING, NULL); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); goto unlock_and_return; } } else { - ov4689_write_reg(ov4689->client, OV4689_REG_CTRL_MODE, - OV4689_REG_VALUE_08BIT, - OV4689_MODE_SW_STANDBY); - pm_runtime_put(&client->dev); + cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, + OV4689_MODE_SW_STANDBY, NULL); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } unlock_and_return: - mutex_unlock(&ov4689->mutex); + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -563,18 +565,13 @@ static int __maybe_unused ov4689_power_off(struct device *dev) return 0; } -static int ov4689_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +static int ov4689_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { - struct ov4689 *ov4689 = to_ov4689(sd); - struct v4l2_mbus_framefmt *try_fmt; - - mutex_lock(&ov4689->mutex); - - try_fmt = v4l2_subdev_state_get_format(fh->state, 0); - /* Initialize try_fmt */ - ov4689_fill_fmt(&supported_modes[OV4689_MODE_2688_1520], try_fmt); + struct v4l2_mbus_framefmt *fmt = + v4l2_subdev_state_get_format(sd_state, 0); - mutex_unlock(&ov4689->mutex); + ov4689_fill_fmt(&supported_modes[OV4689_MODE_2688_1520], fmt); return 0; } @@ -583,10 +580,6 @@ static const struct dev_pm_ops ov4689_pm_ops = { SET_RUNTIME_PM_OPS(ov4689_power_off, ov4689_power_on, NULL) }; -static const struct v4l2_subdev_internal_ops ov4689_internal_ops = { - .open = ov4689_open, -}; - static const struct v4l2_subdev_video_ops ov4689_video_ops = { .s_stream = ov4689_s_stream, }; @@ -594,11 +587,15 @@ static const struct v4l2_subdev_video_ops ov4689_video_ops = { static const struct v4l2_subdev_pad_ops ov4689_pad_ops = { .enum_mbus_code = ov4689_enum_mbus_code, .enum_frame_size = ov4689_enum_frame_sizes, - .get_fmt = ov4689_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ov4689_set_fmt, .get_selection = ov4689_get_selection, }; +static const struct v4l2_subdev_internal_ops ov4689_internal_ops = { + .init_state = ov4689_init_state, +}; + static const struct v4l2_subdev_ops ov4689_subdev_ops = { .video = &ov4689_video_ops, .pad = &ov4689_pad_ops, @@ -610,7 +607,6 @@ static const struct v4l2_subdev_ops ov4689_subdev_ops = { */ static int ov4689_map_gain(struct ov4689 *ov4689, int logical_gain, int *result) { - const struct device *dev = &ov4689->client->dev; const struct ov4689_gain_range *range; unsigned int n; @@ -621,7 +617,8 @@ static int ov4689_map_gain(struct ov4689 *ov4689, int logical_gain, int *result) } if (n == ARRAY_SIZE(ov4689_gain_ranges)) { - dev_warn_ratelimited(dev, "no mapping found for gain %d\n", + dev_warn_ratelimited(ov4689->dev, + "no mapping found for gain %d\n", logical_gain); return -EINVAL; } @@ -637,10 +634,11 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov4689 *ov4689 = container_of(ctrl->handler, struct ov4689, ctrl_handler); - struct i2c_client *client = ov4689->client; - int sensor_gain; + struct regmap *regmap = ov4689->regmap; + struct device *dev = ov4689->dev; + int sensor_gain = 0; s64 max_expo; - int ret; + int ret = 0; /* Propagate change of current control to all related controls */ switch (ctrl->id) { @@ -654,44 +652,58 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) break; } - if (!pm_runtime_get_if_in_use(&client->dev)) + if (!pm_runtime_get_if_in_use(dev)) return 0; switch (ctrl->id) { case V4L2_CID_EXPOSURE: - /* 4 least significant bits of expsoure are fractional part */ - ret = ov4689_write_reg(ov4689->client, OV4689_REG_EXPOSURE, - OV4689_REG_VALUE_24BIT, ctrl->val << 4); + /* 4 least significant bits of exposure are fractional part */ + cci_write(regmap, OV4689_REG_EXPOSURE, ctrl->val << 4, &ret); break; case V4L2_CID_ANALOGUE_GAIN: ret = ov4689_map_gain(ov4689, ctrl->val, &sensor_gain); - - ret = ret ?: - ov4689_write_reg(ov4689->client, OV4689_REG_GAIN_H, - OV4689_REG_VALUE_08BIT, - (sensor_gain >> OV4689_GAIN_H_SHIFT) & - OV4689_GAIN_H_MASK); - ret = ret ?: - ov4689_write_reg(ov4689->client, OV4689_REG_GAIN_L, - OV4689_REG_VALUE_08BIT, - sensor_gain & OV4689_GAIN_L_MASK); + cci_write(regmap, OV4689_REG_GAIN, sensor_gain, &ret); break; case V4L2_CID_VBLANK: - ret = ov4689_write_reg(ov4689->client, OV4689_REG_VTS, - OV4689_REG_VALUE_16BIT, - ctrl->val + ov4689->cur_mode->height); + cci_write(regmap, OV4689_REG_VTS, + ctrl->val + ov4689->cur_mode->height, &ret); break; case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); break; + case V4L2_CID_HBLANK: + cci_write(regmap, OV4689_REG_HTS, + (ctrl->val + ov4689->cur_mode->width) / + OV4689_HTS_DIVIDER, &ret); + break; + case V4L2_CID_VFLIP: + cci_update_bits(regmap, OV4689_REG_TIMING_FORMAT1, + OV4689_TIMING_FLIP_MASK, + ctrl->val ? OV4689_TIMING_FLIP_BOTH : 0, &ret); + break; + case V4L2_CID_HFLIP: + cci_update_bits(regmap, OV4689_REG_TIMING_FORMAT2, + OV4689_TIMING_FLIP_MASK, + ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret); + break; + case V4L2_CID_DIGITAL_GAIN: + cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret); + break; + case V4L2_CID_RED_BALANCE: + cci_write(regmap, OV4689_REG_WB_GAIN_RED, ctrl->val, &ret); + break; + case V4L2_CID_BLUE_BALANCE: + cci_write(regmap, OV4689_REG_WB_GAIN_BLUE, ctrl->val, &ret); + break; default: - dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", + dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); ret = -EINVAL; break; } - pm_runtime_put(&client->dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return ret; } @@ -707,16 +719,15 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) struct v4l2_ctrl_handler *handler; const struct ov4689_mode *mode; s64 exposure_max, vblank_def; + s64 hblank_def, hblank_min; struct v4l2_ctrl *ctrl; - s64 h_blank_def; int ret; handler = &ov4689->ctrl_handler; mode = ov4689->cur_mode; - ret = v4l2_ctrl_handler_init(handler, 10); + ret = v4l2_ctrl_handler_init(handler, 15); if (ret) return ret; - handler->lock = &ov4689->mutex; ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, 0, 0, link_freq_menu_items); @@ -726,11 +737,11 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 0, mode->pixel_rate, 1, mode->pixel_rate); - h_blank_def = mode->hts_def - mode->width; - ctrl = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, h_blank_def, - h_blank_def, 1, h_blank_def); - if (ctrl) - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + hblank_def = mode->hts_def - mode->width; + hblank_min = mode->hts_min - mode->width; + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HBLANK, + hblank_min, OV4689_HTS_MAX - mode->width, + OV4689_HTS_DIVIDER, hblank_def); vblank_def = mode->vts_def - mode->height; v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VBLANK, @@ -754,10 +765,24 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) ARRAY_SIZE(ov4689_test_pattern_menu) - 1, 0, 0, ov4689_test_pattern_menu); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + OV4689_DIG_GAIN_MIN, OV4689_DIG_GAIN_MAX, + OV4689_DIG_GAIN_STEP, OV4689_DIG_GAIN_DEFAULT); + + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_RED_BALANCE, + OV4689_WB_GAIN_MIN, OV4689_WB_GAIN_MAX, + OV4689_WB_GAIN_STEP, OV4689_WB_GAIN_DEFAULT); + + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_BLUE_BALANCE, + OV4689_WB_GAIN_MIN, OV4689_WB_GAIN_MAX, + OV4689_WB_GAIN_STEP, OV4689_WB_GAIN_DEFAULT); + if (handler->error) { ret = handler->error; - dev_err(&ov4689->client->dev, "Failed to init controls(%d)\n", - ret); + dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); goto err_free_handler; } @@ -783,19 +808,18 @@ err_free_handler: static int ov4689_check_sensor_id(struct ov4689 *ov4689, struct i2c_client *client) { - struct device *dev = &ov4689->client->dev; - u32 id = 0; + struct device *dev = ov4689->dev; + u64 id = 0; int ret; - ret = ov4689_read_reg(client, OV4689_REG_CHIP_ID, - OV4689_REG_VALUE_16BIT, &id); + ret = cci_read(ov4689->regmap, OV4689_REG_CHIP_ID, &id, NULL); if (ret) { dev_err(dev, "Cannot read sensor ID\n"); return ret; } if (id != CHIP_ID) { - dev_err(dev, "Unexpected sensor ID %06x, expected %06x\n", + dev_err(dev, "Unexpected sensor ID %06llx, expected %06x\n", id, CHIP_ID); return -ENODEV; } @@ -812,7 +836,7 @@ static int ov4689_configure_regulators(struct ov4689 *ov4689) for (i = 0; i < ARRAY_SIZE(ov4689_supply_names); i++) ov4689->supplies[i].supply = ov4689_supply_names[i]; - return devm_regulator_bulk_get(&ov4689->client->dev, + return devm_regulator_bulk_get(ov4689->dev, ARRAY_SIZE(ov4689_supply_names), ov4689->supplies); } @@ -881,7 +905,8 @@ static int ov4689_probe(struct i2c_client *client) if (!ov4689) return -ENOMEM; - ov4689->client = client; + ov4689->dev = dev; + ov4689->cur_mode = &supported_modes[OV4689_MODE_2688_1520]; ov4689->xvclk = devm_clk_get_optional(dev, NULL); @@ -905,6 +930,13 @@ static int ov4689_probe(struct i2c_client *client) return -EINVAL; } + ov4689->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(ov4689->regmap)) { + ret = PTR_ERR(ov4689->regmap); + dev_err(dev, "failed to initialize CCI: %d\n", ret); + return ret; + } + ov4689->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ov4689->reset_gpio)) { @@ -923,13 +955,15 @@ static int ov4689_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "Failed to get power regulators\n"); - mutex_init(&ov4689->mutex); - sd = &ov4689->subdev; v4l2_i2c_subdev_init(sd, client, &ov4689_subdev_ops); + sd->internal_ops = &ov4689_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ret = ov4689_initialize_controls(ov4689); - if (ret) - goto err_destroy_mutex; + if (ret) { + dev_err(dev, "Failed to initialize controls\n"); + return ret; + } ret = ov4689_power_on(dev); if (ret) @@ -939,35 +973,47 @@ static int ov4689_probe(struct i2c_client *client) if (ret) goto err_power_off; - sd->internal_ops = &ov4689_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - ov4689->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + ov4689->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_pads_init(&sd->entity, 1, &ov4689->pad); if (ret < 0) goto err_power_off; - ret = v4l2_async_register_subdev_sensor(sd); + sd->state_lock = ov4689->ctrl_handler.lock; + ret = v4l2_subdev_init_finalize(sd); if (ret) { - dev_err(dev, "v4l2 async register subdev failed\n"); + dev_err(dev, "Could not register v4l2 device\n"); goto err_clean_entity; } pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); pm_runtime_enable(dev); - pm_runtime_idle(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + + ret = v4l2_async_register_subdev_sensor(sd); + if (ret) { + dev_err(dev, "v4l2 async register subdev failed\n"); + goto err_clean_subdev_pm; + } + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); return 0; +err_clean_subdev_pm: + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + v4l2_subdev_cleanup(sd); err_clean_entity: media_entity_cleanup(&sd->entity); err_power_off: ov4689_power_off(dev); err_free_handler: v4l2_ctrl_handler_free(&ov4689->ctrl_handler); -err_destroy_mutex: - mutex_destroy(&ov4689->mutex); return ret; } @@ -979,9 +1025,8 @@ static void ov4689_remove(struct i2c_client *client) v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); - + v4l2_subdev_cleanup(sd); v4l2_ctrl_handler_free(&ov4689->ctrl_handler); - mutex_destroy(&ov4689->mutex); pm_runtime_disable(&client->dev); if (!pm_runtime_status_suspended(&client->dev)) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index b4647bda8c21f8..b8bd8354d100a8 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -463,8 +463,8 @@ static int rdacm20_initialize(struct rdacm20_device *dev) return ret; /* - * Ensure that we have a good link configuration before attempting to - * identify the device. + * Ensure that we have a good link configuration before attempting to + * identify the device. */ ret = max9271_configure_i2c(&dev->serializer, MAX9271_I2CSLVSH_469NS_234NS | diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 7f67825c8757ff..318e267e798e3a 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -245,15 +245,14 @@ int __must_check media_devnode_register(struct media_device *mdev, kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); /* Part 3: Add the media and char device */ + set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); ret = cdev_device_add(&devnode->cdev, &devnode->dev); if (ret < 0) { + clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); pr_err("%s: cdev_device_add failed\n", __func__); goto cdev_add_error; } - /* Part 4: Activate this minor. The char device can now be used. */ - set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - return 0; cdev_add_error: diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index d3cde05a6ebab8..dd2236c5c4a17f 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -1096,9 +1096,6 @@ static void snd_saa7134_free(struct snd_card * card) if (chip->dev->dmasound.priv_data == NULL) return; - if (chip->irq >= 0) - free_irq(chip->irq, &chip->dev->dmasound); - chip->dev->dmasound.priv_data = NULL; } @@ -1147,10 +1144,8 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) chip->iobase = pci_resource_start(dev->pci, 0); - err = request_irq(dev->pci->irq, saa7134_alsa_irq, - IRQF_SHARED, dev->name, - (void*) &dev->dmasound); - + err = devm_request_irq(&dev->pci->dev, dev->pci->irq, saa7134_alsa_irq, + IRQF_SHARED, dev->name, &dev->dmasound); if (err < 0) { pr_err("%s: can't get IRQ %d for ALSA\n", dev->name, dev->pci->irq); diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c index 6d87fbb0ee04ab..1a9e2bccc4136a 100644 --- a/drivers/media/pci/solo6x10/solo6x10-core.c +++ b/drivers/media/pci/solo6x10/solo6x10-core.c @@ -144,11 +144,8 @@ static void free_solo_dev(struct solo_dev *solo_dev) /* Now cleanup the PCI device */ solo_irq_off(solo_dev, ~0); - free_irq(pdev->irq, solo_dev); - pci_iounmap(pdev, solo_dev->reg_base); } - pci_release_regions(pdev); pci_disable_device(pdev); v4l2_device_unregister(&solo_dev->v4l2_dev); pci_set_drvdata(pdev, NULL); @@ -480,15 +477,10 @@ static int solo_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_write_config_byte(pdev, 0x40, 0x00); pci_write_config_byte(pdev, 0x41, 0x00); - ret = pci_request_regions(pdev, SOLO6X10_NAME); + ret = pcim_iomap_regions(pdev, BIT(0), SOLO6X10_NAME); if (ret) goto fail_probe; - - solo_dev->reg_base = pci_ioremap_bar(pdev, 0); - if (solo_dev->reg_base == NULL) { - ret = -ENOMEM; - goto fail_probe; - } + solo_dev->reg_base = pcim_iomap_table(pdev)[0]; chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & SOLO_CHIP_ID_MASK; @@ -551,8 +543,8 @@ static int solo_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* PLL locking time of 1ms */ mdelay(1); - ret = request_irq(pdev->irq, solo_isr, IRQF_SHARED, SOLO6X10_NAME, - solo_dev); + ret = devm_request_irq(&pdev->dev, pdev->irq, solo_isr, IRQF_SHARED, + SOLO6X10_NAME, solo_dev); if (ret) goto fail_probe; diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index a47c5850ef8758..2e62c938e2cb22 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * budget-av.c: driver for the SAA7146 based Budget DVB cards - * with analog video in + * budget-av.ko: driver for the SAA7146 based Budget DVB cards + * with analog video input (and optionally with CI) * * Compiled from various sources by Michael Hunold <michael@mihu.de> * @@ -16,7 +16,6 @@ * the project's page is at https://linuxtv.org */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include "budget.h" #include "stv0299.h" @@ -63,8 +62,8 @@ struct budget_av { static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); - -/* GPIO Connections: +/* + * GPIO Connections: * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory * 2 - CI Card Enable (Active Low) @@ -95,12 +94,12 @@ static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg) return mm2[0]; } -static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len) +static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 *buf, u8 len) { u8 mm1[] = { reg }; struct i2c_msg msgs[2] = { - {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1}, - {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len} + {.addr = id / 2, .flags = 0, .buf = mm1, .len = 1}, + {.addr = id / 2, .flags = I2C_M_RD, .buf = buf, .len = len} }; if (i2c_transfer(i2c, msgs, 2) != 2) @@ -206,7 +205,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - dprintk(1, "ciintf_slot_reset\n"); + dprintk(1, "ci slot reset\n"); budget_av->slot_status = SLOTSTATUS_RESET; saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ @@ -235,7 +234,7 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - dprintk(1, "ciintf_slot_shutdown\n"); + dprintk(1, "ci slot shutdown\n"); ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); budget_av->slot_status = SLOTSTATUS_NONE; @@ -251,7 +250,7 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) if (slot != 0) return -EINVAL; - dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); + dprintk(1, "ci slot status: %d\n", budget_av->slot_status); ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); @@ -267,8 +266,10 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open if (slot != 0) return -EINVAL; - /* test the card detect line - needs to be done carefully - * since it never goes high for some CAMs on this interface (e.g. topuptv) */ + /* + * test the card detect line - needs to be done carefully + * since it never goes high for some CAMs on this interface (e.g. topuptv) + */ if (budget_av->slot_status == SLOTSTATUS_NONE) { saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); udelay(1); @@ -281,12 +282,14 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); } - /* We also try and read from IO memory to work round the above detection bug. If + /* + * We also try and read from IO memory to work round the above detection bug. If * there is no CAM, we will get a timeout. Only done if there is no cam * present, since this test actually breaks some cams :( * * if the CI interface is not open, we also do the above test since we - * don't care if the cam has problems - we'll be resetting it on open() anyway */ + * don't care if the cam has problems - we'll be resetting it on open() anyway + */ if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); @@ -305,16 +308,14 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open /* read from attribute memory in reset/ready state to know when the CAM is ready */ if (budget_av->slot_status == SLOTSTATUS_RESET) { result = ciintf_read_attribute_mem(ca, slot, 0); - if (result == 0x1d) { + if (result == 0x1d) budget_av->slot_status = SLOTSTATUS_READY; - } } /* work out correct return code */ if (budget_av->slot_status != SLOTSTATUS_NONE) { - if (budget_av->slot_status & SLOTSTATUS_READY) { + if (budget_av->slot_status & SLOTSTATUS_READY) return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } return DVB_CA_EN50221_POLL_CAM_PRESENT; } return 0; @@ -349,8 +350,9 @@ static int ciintf_init(struct budget_av *budget_av) budget_av->budget.ci_present = 1; budget_av->slot_status = SLOTSTATUS_NONE; - if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, - &budget_av->ca, 0, 1)) != 0) { + result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, + &budget_av->ca, 0, 1); + if (result != 0) { pr_err("ci initialisation failed\n"); goto error; } @@ -439,7 +441,7 @@ static int saa7113_setinput(struct budget_av *budget_av, int input) { struct budget *budget = &budget_av->budget; - if (1 != budget_av->has_saa7113) + if (budget_av->has_saa7113 != 1) return -ENODEV; if (input == 1) { @@ -448,8 +450,9 @@ static int saa7113_setinput(struct budget_av *budget_av, int input) } else if (input == 0) { i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0); i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00); - } else + } else { return -EINVAL; + } budget_av->cur_input = input; return 0; @@ -492,7 +495,7 @@ static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe) u32 div; u8 buf[4]; struct budget *budget = fe->dvb->priv; - struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; + struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; if ((c->frequency < 950000) || (c->frequency > 2150000)) return -EINVAL; @@ -606,7 +609,7 @@ static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget *budget = fe->dvb->priv; u8 buf[6]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; + struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) }; int i; #define CU1216_IF 36125000 @@ -670,7 +673,7 @@ static int philips_tu1216_tuner_init(struct dvb_frontend *fe) { struct budget *budget = fe->dvb->priv; static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; + struct i2c_msg tuner_msg = {.addr = 0x60, .flags = 0, .buf = tu1216_init, .len = sizeof(tu1216_init) }; // setup PLL configuration if (fe->ops.i2c_gate_ctrl) @@ -687,7 +690,7 @@ static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct budget *budget = fe->dvb->priv; u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = + struct i2c_msg tuner_msg = {.addr = 0x60, .flags = 0, .buf = tuner_buf, .len = sizeof(tuner_buf) }; int tuner_frequency = 0; u8 band, cp, filter; @@ -865,7 +868,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, static const struct stv0299_config philips_sd1878_config = { .demod_address = 0x68, - .inittab = philips_sd1878_inittab, + .inittab = philips_sd1878_inittab, .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, @@ -878,222 +881,222 @@ static const struct stv0299_config philips_sd1878_config = { /* KNC1 DVB-S (STB0899) Inittab */ static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, + { STB0899_DEV_ID, 0x81 }, + { STB0899_DISCNTRL1, 0x32 }, + { STB0899_DISCNTRL2, 0x80 }, + { STB0899_DISRX_ST0, 0x04 }, + { STB0899_DISRX_ST1, 0x00 }, + { STB0899_DISPARITY, 0x00 }, + { STB0899_DISSTATUS, 0x20 }, + { STB0899_DISF22, 0x8c }, + { STB0899_DISF22RX, 0x9a }, + { STB0899_SYSREG, 0x0b }, + { STB0899_ACRPRESC, 0x11 }, + { STB0899_ACRDIV1, 0x0a }, + { STB0899_ACRDIV2, 0x05 }, + { STB0899_DACR1, 0x00 }, + { STB0899_DACR2, 0x00 }, + { STB0899_OUTCFG, 0x00 }, + { STB0899_MODECFG, 0x00 }, + { STB0899_IRQSTATUS_3, 0x30 }, + { STB0899_IRQSTATUS_2, 0x00 }, + { STB0899_IRQSTATUS_1, 0x00 }, + { STB0899_IRQSTATUS_0, 0x00 }, + { STB0899_IRQMSK_3, 0xf3 }, + { STB0899_IRQMSK_2, 0xfc }, + { STB0899_IRQMSK_1, 0xff }, + { STB0899_IRQMSK_0, 0xff }, + { STB0899_IRQCFG, 0x00 }, + { STB0899_I2CCFG, 0x88 }, + { STB0899_I2CRPT, 0x58 }, /* Repeater=8, Stop=disabled */ + { STB0899_IOPVALUE5, 0x00 }, + { STB0899_IOPVALUE4, 0x20 }, + { STB0899_IOPVALUE3, 0xc9 }, + { STB0899_IOPVALUE2, 0x90 }, + { STB0899_IOPVALUE1, 0x40 }, + { STB0899_IOPVALUE0, 0x00 }, + { STB0899_GPIO00CFG, 0x82 }, + { STB0899_GPIO01CFG, 0x82 }, + { STB0899_GPIO02CFG, 0x82 }, + { STB0899_GPIO03CFG, 0x82 }, + { STB0899_GPIO04CFG, 0x82 }, + { STB0899_GPIO05CFG, 0x82 }, + { STB0899_GPIO06CFG, 0x82 }, + { STB0899_GPIO07CFG, 0x82 }, + { STB0899_GPIO08CFG, 0x82 }, + { STB0899_GPIO09CFG, 0x82 }, + { STB0899_GPIO10CFG, 0x82 }, + { STB0899_GPIO11CFG, 0x82 }, + { STB0899_GPIO12CFG, 0x82 }, + { STB0899_GPIO13CFG, 0x82 }, + { STB0899_GPIO14CFG, 0x82 }, + { STB0899_GPIO15CFG, 0x82 }, + { STB0899_GPIO16CFG, 0x82 }, + { STB0899_GPIO17CFG, 0x82 }, + { STB0899_GPIO18CFG, 0x82 }, + { STB0899_GPIO19CFG, 0x82 }, + { STB0899_GPIO20CFG, 0x82 }, + { STB0899_SDATCFG, 0xb8 }, + { STB0899_SCLTCFG, 0xba }, + { STB0899_AGCRFCFG, 0x08 }, /* 0x1c */ + { STB0899_GPIO22, 0x82 }, /* AGCBB2CFG */ + { STB0899_GPIO21, 0x91 }, /* AGCBB1CFG */ + { STB0899_DIRCLKCFG, 0x82 }, + { STB0899_CLKOUT27CFG, 0x7e }, + { STB0899_STDBYCFG, 0x82 }, + { STB0899_CS0CFG, 0x82 }, + { STB0899_CS1CFG, 0x82 }, + { STB0899_DISEQCOCFG, 0x20 }, + { STB0899_GPIO32CFG, 0x82 }, + { STB0899_GPIO33CFG, 0x82 }, + { STB0899_GPIO34CFG, 0x82 }, + { STB0899_GPIO35CFG, 0x82 }, + { STB0899_GPIO36CFG, 0x82 }, + { STB0899_GPIO37CFG, 0x82 }, + { STB0899_GPIO38CFG, 0x82 }, + { STB0899_GPIO39CFG, 0x82 }, + { STB0899_NCOARSE, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ + { STB0899_SYNTCTRL, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ + { STB0899_FILTCTRL, 0x00 }, + { STB0899_SYSCTRL, 0x00 }, + { STB0899_STOPCLK1, 0x20 }, + { STB0899_STOPCLK2, 0x00 }, + { STB0899_INTBUFSTATUS, 0x00 }, + { STB0899_INTBUFCTRL, 0x0a }, + { 0xffff, 0xff }, }; static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x08 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x33 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xee }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, + { STB0899_DEMOD, 0x00 }, + { STB0899_RCOMPC, 0xc9 }, + { STB0899_AGC1CN, 0x41 }, + { STB0899_AGC1REF, 0x08 }, + { STB0899_RTC, 0x7a }, + { STB0899_TMGCFG, 0x4e }, + { STB0899_AGC2REF, 0x33 }, + { STB0899_TLSR, 0x84 }, + { STB0899_CFD, 0xee }, + { STB0899_ACLC, 0x87 }, + { STB0899_BCLC, 0x94 }, + { STB0899_EQON, 0x41 }, + { STB0899_LDT, 0xdd }, + { STB0899_LDT2, 0xc9 }, + { STB0899_EQUALREF, 0xb4 }, + { STB0899_TMGRAMP, 0x10 }, + { STB0899_TMGTHD, 0x30 }, + { STB0899_IDCCOMP, 0xfb }, + { STB0899_QDCCOMP, 0x03 }, + { STB0899_POWERI, 0x3b }, + { STB0899_POWERQ, 0x3d }, + { STB0899_RCOMP, 0x81 }, + { STB0899_AGCIQIN, 0x80 }, + { STB0899_AGC2I1, 0x04 }, + { STB0899_AGC2I2, 0xf5 }, + { STB0899_TLIR, 0x25 }, + { STB0899_RTF, 0x80 }, + { STB0899_DSTATUS, 0x00 }, + { STB0899_LDI, 0xca }, + { STB0899_CFRM, 0xf1 }, + { STB0899_CFRL, 0xf3 }, + { STB0899_NIRM, 0x2a }, + { STB0899_NIRL, 0x05 }, + { STB0899_ISYMB, 0x17 }, + { STB0899_QSYMB, 0xfa }, + { STB0899_SFRH, 0x2f }, + { STB0899_SFRM, 0x68 }, + { STB0899_SFRL, 0x40 }, + { STB0899_SFRUPH, 0x2f }, + { STB0899_SFRUPM, 0x68 }, + { STB0899_SFRUPL, 0x40 }, + { STB0899_EQUAI1, 0xfd }, + { STB0899_EQUAQ1, 0x04 }, + { STB0899_EQUAI2, 0x0f }, + { STB0899_EQUAQ2, 0xff }, + { STB0899_EQUAI3, 0xdf }, + { STB0899_EQUAQ3, 0xfa }, + { STB0899_EQUAI4, 0x37 }, + { STB0899_EQUAQ4, 0x0d }, + { STB0899_EQUAI5, 0xbd }, + { STB0899_EQUAQ5, 0xf7 }, + { STB0899_DSTATUS2, 0x00 }, + { STB0899_VSTATUS, 0x00 }, + { STB0899_VERROR, 0xff }, + { STB0899_IQSWAP, 0x2a }, + { STB0899_ECNT1M, 0x00 }, + { STB0899_ECNT1L, 0x00 }, + { STB0899_ECNT2M, 0x00 }, + { STB0899_ECNT2L, 0x00 }, + { STB0899_ECNT3M, 0x00 }, + { STB0899_ECNT3L, 0x00 }, + { STB0899_FECAUTO1, 0x06 }, + { STB0899_FECM, 0x01 }, + { STB0899_VTH12, 0xf0 }, + { STB0899_VTH23, 0xa0 }, + { STB0899_VTH34, 0x78 }, + { STB0899_VTH56, 0x4e }, + { STB0899_VTH67, 0x48 }, + { STB0899_VTH78, 0x38 }, + { STB0899_PRVIT, 0xff }, + { STB0899_VITSYNC, 0x19 }, + { STB0899_RSULC, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ + { STB0899_TSULC, 0x42 }, + { STB0899_RSLLC, 0x40 }, + { STB0899_TSLPL, 0x12 }, + { STB0899_TSCFGH, 0x0c }, + { STB0899_TSCFGM, 0x00 }, + { STB0899_TSCFGL, 0x0c }, + { STB0899_TSOUT, 0x4d }, /* 0x0d for CAM */ + { STB0899_RSSYNCDEL, 0x00 }, + { STB0899_TSINHDELH, 0x02 }, + { STB0899_TSINHDELM, 0x00 }, + { STB0899_TSINHDELL, 0x00 }, + { STB0899_TSLLSTKM, 0x00 }, + { STB0899_TSLLSTKL, 0x00 }, + { STB0899_TSULSTKM, 0x00 }, + { STB0899_TSULSTKL, 0xab }, + { STB0899_PCKLENUL, 0x00 }, + { STB0899_PCKLENLL, 0xcc }, + { STB0899_RSPCKLEN, 0xcc }, + { STB0899_TSSTATUS, 0x80 }, + { STB0899_ERRCTRL1, 0xb6 }, + { STB0899_ERRCTRL2, 0x96 }, + { STB0899_ERRCTRL3, 0x89 }, + { STB0899_DMONMSK1, 0x27 }, + { STB0899_DMONMSK0, 0x03 }, + { STB0899_DEMAPVIT, 0x5c }, + { STB0899_PLPARM, 0x1f }, + { STB0899_PDELCTRL, 0x48 }, + { STB0899_PDELCTRL2, 0x00 }, + { STB0899_BBHCTRL1, 0x00 }, + { STB0899_BBHCTRL2, 0x00 }, + { STB0899_HYSTTHRESH, 0x77 }, + { STB0899_MATCSTM, 0x00 }, + { STB0899_MATCSTL, 0x00 }, + { STB0899_UPLCSTM, 0x00 }, + { STB0899_UPLCSTL, 0x00 }, + { STB0899_DFLCSTM, 0x00 }, + { STB0899_DFLCSTL, 0x00 }, + { STB0899_SYNCCST, 0x00 }, + { STB0899_SYNCDCSTM, 0x00 }, + { STB0899_SYNCDCSTL, 0x00 }, + { STB0899_ISI_ENTRY, 0x00 }, + { STB0899_ISI_BIT_EN, 0x00 }, + { STB0899_MATSTRM, 0x00 }, + { STB0899_MATSTRL, 0x00 }, + { STB0899_UPLSTRM, 0x00 }, + { STB0899_UPLSTRL, 0x00 }, + { STB0899_DFLSTRM, 0x00 }, + { STB0899_DFLSTRL, 0x00 }, + { STB0899_SYNCSTR, 0x00 }, + { STB0899_SYNCDSTRM, 0x00 }, + { STB0899_SYNCDSTRL, 0x00 }, + { STB0899_CFGPDELSTATUS1, 0x10 }, + { STB0899_CFGPDELSTATUS2, 0x00 }, + { STB0899_BBFERRORM, 0x00 }, + { STB0899_BBFERRORL, 0x00 }, + { STB0899_UPKTERRORM, 0x00 }, + { STB0899_UPKTERRORL, 0x00 }, + { 0xffff, 0xff }, }; /* STB0899 demodulator config for the KNC1 and clones */ @@ -1153,8 +1156,8 @@ static u8 read_pwm(struct budget_av *budget_av) { u8 b = 0xff; u8 pwm; - struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1}, - {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} + struct i2c_msg msg[] = { {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, + {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} }; if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2) @@ -1196,8 +1199,8 @@ static u8 read_pwm(struct budget_av *budget_av) static void frontend_init(struct budget_av *budget_av) { - struct saa7146_dev * saa = budget_av->budget.dev; - struct dvb_frontend * fe = NULL; + struct saa7146_dev *saa = budget_av->budget.dev; + struct dvb_frontend *fe = NULL; /* Enable / PowerON Frontend */ saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); @@ -1207,16 +1210,16 @@ static void frontend_init(struct budget_av *budget_av) /* additional setup necessary for the PLUS cards */ switch (saa->pci->subsystem_device) { - case SUBID_DVBS_KNC1_PLUS: - case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBT_KNC1_PLUS: - case SUBID_DVBC_EASYWATCH: - case SUBID_DVBC_KNC1_PLUS_MK3: - case SUBID_DVBS2_KNC1: - case SUBID_DVBS2_KNC1_OEM: - case SUBID_DVBS2_EASYWATCH: - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); - break; + case SUBID_DVBS_KNC1_PLUS: + case SUBID_DVBC_KNC1_PLUS: + case SUBID_DVBT_KNC1_PLUS: + case SUBID_DVBC_EASYWATCH: + case SUBID_DVBC_KNC1_PLUS_MK3: + case SUBID_DVBS2_KNC1: + case SUBID_DVBS2_KNC1_OEM: + case SUBID_DVBS2_EASYWATCH: + saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); + break; } switch (saa->pci->subsystem_device) { @@ -1233,15 +1236,13 @@ static void frontend_init(struct budget_av *budget_av) if (saa->pci->subsystem_vendor == 0x1894) { fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config, &budget_av->budget.i2c_adap); - if (fe) { + if (fe) dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap); - } } else { fe = dvb_attach(stv0299_attach, &typhoon_config, &budget_av->budget.i2c_adap); - if (fe) { + if (fe) fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } } break; @@ -1253,34 +1254,32 @@ static void frontend_init(struct budget_av *budget_av) case SUBID_DVBS_EASYWATCH_2: fe = dvb_attach(stv0299_attach, &philips_sd1878_config, &budget_av->budget.i2c_adap); - if (fe) { + if (fe) dvb_attach(dvb_pll_attach, fe, 0x60, &budget_av->budget.i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261); - } break; case SUBID_DVBS_TYPHOON: fe = dvb_attach(stv0299_attach, &typhoon_config, &budget_av->budget.i2c_adap); - if (fe) { + if (fe) fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } break; case SUBID_DVBS2_KNC1: case SUBID_DVBS2_KNC1_OEM: case SUBID_DVBS2_EASYWATCH: budget_av->reinitialise_demod = 1; - if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap))) + fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap); + if (fe) dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap); break; case SUBID_DVBS_CINERGY1200: fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, &budget_av->budget.i2c_adap); - if (fe) { + if (fe) fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } break; case SUBID_DVBC_KNC1: @@ -1296,9 +1295,8 @@ static void frontend_init(struct budget_av *budget_av) fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress, &budget_av->budget.i2c_adap, read_pwm(budget_av)); - if (fe) { + if (fe) fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } break; case SUBID_DVBC_EASYWATCH_MK3: @@ -1312,9 +1310,8 @@ static void frontend_init(struct budget_av *budget_av) &philips_cu1216_tda10023_config, &budget_av->budget.i2c_adap, read_pwm(budget_av)); - if (fe) { + if (fe) fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } break; case SUBID_DVBT_EASYWATCH: @@ -1351,7 +1348,7 @@ static void frontend_init(struct budget_av *budget_av) } -static void budget_av_irq(struct saa7146_dev *dev, u32 * isr) +static void budget_av_irq(struct saa7146_dev *dev, u32 *isr) { struct budget_av *budget_av = dev->ext_priv; @@ -1368,7 +1365,7 @@ static int budget_av_detach(struct saa7146_dev *dev) dprintk(2, "dev: %p\n", dev); - if (1 == budget_av->has_saa7113) { + if (budget_av->has_saa7113 == 1) { saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); msleep(200); @@ -1439,7 +1436,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio dprintk(2, "dev: %p\n", dev); - if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL))) + budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL); + if (!budget_av) return -ENOMEM; budget_av->has_saa7113 = 0; @@ -1465,18 +1463,19 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio if (err != 0) { ttpci_budget_deinit(&budget_av->budget); kfree(budget_av); - ERR("cannot init vv subsystem\n"); + pr_err("cannot init vv subsystem\n"); return err; } vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; vv_data.vid_ops.vidioc_g_input = vidioc_g_input; vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) { + err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO); + if (err) { saa7146_vv_release(dev); ttpci_budget_deinit(&budget_av->budget); kfree(budget_av); - ERR("cannot register capture v4l2 device\n"); + pr_err("cannot register capture v4l2 device\n"); return err; } @@ -1510,15 +1509,15 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio } static struct saa7146_standard standard[] = { - {.name = "PAL",.id = V4L2_STD_PAL, - .v_offset = 0x17,.v_field = 288, - .h_offset = 0x14,.h_pixels = 680, - .v_max_out = 576,.h_max_out = 768 }, - - {.name = "NTSC",.id = V4L2_STD_NTSC, - .v_offset = 0x16,.v_field = 240, - .h_offset = 0x06,.h_pixels = 708, - .v_max_out = 480,.h_max_out = 640, }, + {.name = "PAL", .id = V4L2_STD_PAL, + .v_offset = 0x17, .v_field = 288, + .h_offset = 0x14, .h_pixels = 680, + .v_max_out = 576, .h_max_out = 768 }, + + {.name = "NTSC", .id = V4L2_STD_NTSC, + .v_offset = 0x16, .v_field = 240, + .h_offset = 0x06, .h_pixels = 708, + .v_max_out = 480, .h_max_out = 640, }, }; static struct saa7146_ext_vv vv_data = { @@ -1532,8 +1531,8 @@ static struct saa7146_ext_vv vv_data = { static struct saa7146_extension budget_extension; MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); -MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2); -MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); +MAKE_BUDGET_INFO(knc1s2, "KNC1 DVB-S2", BUDGET_KNC1S2); +MAKE_BUDGET_INFO(sates2, "Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 66e1a004ee431c..76de40e3c80230 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * budget-ci.c: driver for the SAA7146 based Budget DVB cards + * budget-ci.ko: driver for the SAA7146 based Budget DVB cards + * with CI (but without analog video input) * * Compiled from various sources by Michael Hunold <michael@mihu.de> * @@ -123,7 +124,7 @@ static void msp430_ir_interrupt(struct tasklet_struct *t) */ if (ir_debug) - printk("budget_ci: received byte 0x%02x\n", command); + pr_info("received byte 0x%02x\n", command); /* Remove repeat bit, we use every command */ command = command & 0x7f; @@ -164,7 +165,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) dev = rc_allocate_device(RC_DRIVER_SCANCODE); if (!dev) { - printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); + pr_err("IR interface initialisation failed\n"); return -ENOMEM; } @@ -223,7 +224,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) error = rc_register_device(dev); if (error) { - printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); + pr_err("could not init driver for IR device (code %d)\n", error); rc_free_device(dev); return error; } @@ -411,24 +412,21 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); if (flags & CICONTROL_CAMDETECT) { // mark it as present if it wasn't before - if (budget_ci->slot_status & SLOTSTATUS_NONE) { + if (budget_ci->slot_status & SLOTSTATUS_NONE) budget_ci->slot_status = SLOTSTATUS_PRESENT; - } // during a RESET, we check if we can read from IO memory to see when CAM is ready if (budget_ci->slot_status & SLOTSTATUS_RESET) { - if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { + if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) budget_ci->slot_status = SLOTSTATUS_READY; - } } } else { budget_ci->slot_status = SLOTSTATUS_NONE; } if (budget_ci->slot_status != SLOTSTATUS_NONE) { - if (budget_ci->slot_status & SLOTSTATUS_READY) { + if (budget_ci->slot_status & SLOTSTATUS_READY) return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } return DVB_CA_EN50221_POLL_CAM_PRESENT; } @@ -483,21 +481,21 @@ static int ciintf_init(struct budget_ci *budget_ci) budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; budget_ci->ca.data = budget_ci; - if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, - &budget_ci->ca, - ca_flags, 1)) != 0) { - printk("budget_ci: CI interface detected, but initialisation failed.\n"); + + result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, + &budget_ci->ca, ca_flags, 1); + if (result != 0) { + pr_err("CI interface detected, but initialisation failed.\n"); goto error; } // Setup CI slot IRQ if (budget_ci->ci_irq) { tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { + if (budget_ci->slot_status != SLOTSTATUS_NONE) saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { + else saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } SAA7146_IER_ENABLE(saa, MASK_03); } @@ -506,7 +504,7 @@ static int ciintf_init(struct budget_ci *budget_ci) CICONTROL_RESET, 1, 0); // success! - printk("budget_ci: CI interface initialised\n"); + pr_info("CI interface initialised\n"); budget_ci->budget.ci_present = 1; // forge a fake CI IRQ so the CAM state is setup correctly @@ -551,7 +549,7 @@ static void ciintf_deinit(struct budget_ci *budget_ci) saa7146_write(saa, MC1, MASK_27); } -static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) +static void budget_ci_irq(struct saa7146_dev *dev, u32 *isr) { struct budget_ci *budget_ci = dev->ext_priv; @@ -651,7 +649,7 @@ static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe) struct budget_ci *budget_ci = fe->dvb->priv; u32 div; u8 buf[4]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; + struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) }; if ((p->frequency < 950000) || (p->frequency > 2150000)) return -EINVAL; @@ -701,7 +699,7 @@ static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) struct budget_ci *budget_ci = fe->dvb->priv; static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len = + struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, .flags = 0, .buf = td1316_init, .len = sizeof(td1316_init) }; // setup PLL configuration @@ -731,7 +729,7 @@ static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct budget_ci *budget_ci = fe->dvb->priv; u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; + struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, .flags = 0, .buf = tuner_buf, .len = sizeof(tuner_buf) }; int tuner_frequency = 0; u8 band, cp, filter; @@ -856,9 +854,9 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) // determine charge pump tuner_frequency = p->frequency + 36125000; - if (tuner_frequency < 87000000) + if (tuner_frequency < 87000000) { return -EINVAL; - else if (tuner_frequency < 130000000) { + } else if (tuner_frequency < 130000000) { cp = 3; band = 1; } else if (tuner_frequency < 160000000) { @@ -885,8 +883,9 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) } else if (tuner_frequency < 895000000) { cp = 7; band = 4; - } else + } else { return -EINVAL; + } // assume PLL filter should always be 8MHz for the moment. filter = 1; @@ -1035,222 +1034,222 @@ static struct tda827x_config tda827x_config = { /* TT S2-3200 DVB-S (STB0899) Inittab */ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, + { STB0899_DEV_ID, 0x81 }, + { STB0899_DISCNTRL1, 0x32 }, + { STB0899_DISCNTRL2, 0x80 }, + { STB0899_DISRX_ST0, 0x04 }, + { STB0899_DISRX_ST1, 0x00 }, + { STB0899_DISPARITY, 0x00 }, + { STB0899_DISSTATUS, 0x20 }, + { STB0899_DISF22, 0x8c }, + { STB0899_DISF22RX, 0x9a }, + { STB0899_SYSREG, 0x0b }, + { STB0899_ACRPRESC, 0x11 }, + { STB0899_ACRDIV1, 0x0a }, + { STB0899_ACRDIV2, 0x05 }, + { STB0899_DACR1, 0x00 }, + { STB0899_DACR2, 0x00 }, + { STB0899_OUTCFG, 0x00 }, + { STB0899_MODECFG, 0x00 }, + { STB0899_IRQSTATUS_3, 0x30 }, + { STB0899_IRQSTATUS_2, 0x00 }, + { STB0899_IRQSTATUS_1, 0x00 }, + { STB0899_IRQSTATUS_0, 0x00 }, + { STB0899_IRQMSK_3, 0xf3 }, + { STB0899_IRQMSK_2, 0xfc }, + { STB0899_IRQMSK_1, 0xff }, + { STB0899_IRQMSK_0, 0xff }, + { STB0899_IRQCFG, 0x00 }, + { STB0899_I2CCFG, 0x88 }, + { STB0899_I2CRPT, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ + { STB0899_IOPVALUE5, 0x00 }, + { STB0899_IOPVALUE4, 0x20 }, + { STB0899_IOPVALUE3, 0xc9 }, + { STB0899_IOPVALUE2, 0x90 }, + { STB0899_IOPVALUE1, 0x40 }, + { STB0899_IOPVALUE0, 0x00 }, + { STB0899_GPIO00CFG, 0x82 }, + { STB0899_GPIO01CFG, 0x82 }, + { STB0899_GPIO02CFG, 0x82 }, + { STB0899_GPIO03CFG, 0x82 }, + { STB0899_GPIO04CFG, 0x82 }, + { STB0899_GPIO05CFG, 0x82 }, + { STB0899_GPIO06CFG, 0x82 }, + { STB0899_GPIO07CFG, 0x82 }, + { STB0899_GPIO08CFG, 0x82 }, + { STB0899_GPIO09CFG, 0x82 }, + { STB0899_GPIO10CFG, 0x82 }, + { STB0899_GPIO11CFG, 0x82 }, + { STB0899_GPIO12CFG, 0x82 }, + { STB0899_GPIO13CFG, 0x82 }, + { STB0899_GPIO14CFG, 0x82 }, + { STB0899_GPIO15CFG, 0x82 }, + { STB0899_GPIO16CFG, 0x82 }, + { STB0899_GPIO17CFG, 0x82 }, + { STB0899_GPIO18CFG, 0x82 }, + { STB0899_GPIO19CFG, 0x82 }, + { STB0899_GPIO20CFG, 0x82 }, + { STB0899_SDATCFG, 0xb8 }, + { STB0899_SCLTCFG, 0xba }, + { STB0899_AGCRFCFG, 0x1c }, /* 0x11 */ + { STB0899_GPIO22, 0x82 }, /* AGCBB2CFG */ + { STB0899_GPIO21, 0x91 }, /* AGCBB1CFG */ + { STB0899_DIRCLKCFG, 0x82 }, + { STB0899_CLKOUT27CFG, 0x7e }, + { STB0899_STDBYCFG, 0x82 }, + { STB0899_CS0CFG, 0x82 }, + { STB0899_CS1CFG, 0x82 }, + { STB0899_DISEQCOCFG, 0x20 }, + { STB0899_GPIO32CFG, 0x82 }, + { STB0899_GPIO33CFG, 0x82 }, + { STB0899_GPIO34CFG, 0x82 }, + { STB0899_GPIO35CFG, 0x82 }, + { STB0899_GPIO36CFG, 0x82 }, + { STB0899_GPIO37CFG, 0x82 }, + { STB0899_GPIO38CFG, 0x82 }, + { STB0899_GPIO39CFG, 0x82 }, + { STB0899_NCOARSE, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ + { STB0899_SYNTCTRL, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ + { STB0899_FILTCTRL, 0x00 }, + { STB0899_SYSCTRL, 0x00 }, + { STB0899_STOPCLK1, 0x20 }, + { STB0899_STOPCLK2, 0x00 }, + { STB0899_INTBUFSTATUS, 0x00 }, + { STB0899_INTBUFCTRL, 0x0a }, + { 0xffff, 0xff }, }; static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x10 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xc7 }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, + { STB0899_DEMOD, 0x00 }, + { STB0899_RCOMPC, 0xc9 }, + { STB0899_AGC1CN, 0x41 }, + { STB0899_AGC1REF, 0x10 }, + { STB0899_RTC, 0x7a }, + { STB0899_TMGCFG, 0x4e }, + { STB0899_AGC2REF, 0x34 }, + { STB0899_TLSR, 0x84 }, + { STB0899_CFD, 0xc7 }, + { STB0899_ACLC, 0x87 }, + { STB0899_BCLC, 0x94 }, + { STB0899_EQON, 0x41 }, + { STB0899_LDT, 0xdd }, + { STB0899_LDT2, 0xc9 }, + { STB0899_EQUALREF, 0xb4 }, + { STB0899_TMGRAMP, 0x10 }, + { STB0899_TMGTHD, 0x30 }, + { STB0899_IDCCOMP, 0xfb }, + { STB0899_QDCCOMP, 0x03 }, + { STB0899_POWERI, 0x3b }, + { STB0899_POWERQ, 0x3d }, + { STB0899_RCOMP, 0x81 }, + { STB0899_AGCIQIN, 0x80 }, + { STB0899_AGC2I1, 0x04 }, + { STB0899_AGC2I2, 0xf5 }, + { STB0899_TLIR, 0x25 }, + { STB0899_RTF, 0x80 }, + { STB0899_DSTATUS, 0x00 }, + { STB0899_LDI, 0xca }, + { STB0899_CFRM, 0xf1 }, + { STB0899_CFRL, 0xf3 }, + { STB0899_NIRM, 0x2a }, + { STB0899_NIRL, 0x05 }, + { STB0899_ISYMB, 0x17 }, + { STB0899_QSYMB, 0xfa }, + { STB0899_SFRH, 0x2f }, + { STB0899_SFRM, 0x68 }, + { STB0899_SFRL, 0x40 }, + { STB0899_SFRUPH, 0x2f }, + { STB0899_SFRUPM, 0x68 }, + { STB0899_SFRUPL, 0x40 }, + { STB0899_EQUAI1, 0xfd }, + { STB0899_EQUAQ1, 0x04 }, + { STB0899_EQUAI2, 0x0f }, + { STB0899_EQUAQ2, 0xff }, + { STB0899_EQUAI3, 0xdf }, + { STB0899_EQUAQ3, 0xfa }, + { STB0899_EQUAI4, 0x37 }, + { STB0899_EQUAQ4, 0x0d }, + { STB0899_EQUAI5, 0xbd }, + { STB0899_EQUAQ5, 0xf7 }, + { STB0899_DSTATUS2, 0x00 }, + { STB0899_VSTATUS, 0x00 }, + { STB0899_VERROR, 0xff }, + { STB0899_IQSWAP, 0x2a }, + { STB0899_ECNT1M, 0x00 }, + { STB0899_ECNT1L, 0x00 }, + { STB0899_ECNT2M, 0x00 }, + { STB0899_ECNT2L, 0x00 }, + { STB0899_ECNT3M, 0x00 }, + { STB0899_ECNT3L, 0x00 }, + { STB0899_FECAUTO1, 0x06 }, + { STB0899_FECM, 0x01 }, + { STB0899_VTH12, 0xf0 }, + { STB0899_VTH23, 0xa0 }, + { STB0899_VTH34, 0x78 }, + { STB0899_VTH56, 0x4e }, + { STB0899_VTH67, 0x48 }, + { STB0899_VTH78, 0x38 }, + { STB0899_PRVIT, 0xff }, + { STB0899_VITSYNC, 0x19 }, + { STB0899_RSULC, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ + { STB0899_TSULC, 0x42 }, + { STB0899_RSLLC, 0x40 }, + { STB0899_TSLPL, 0x12 }, + { STB0899_TSCFGH, 0x0c }, + { STB0899_TSCFGM, 0x00 }, + { STB0899_TSCFGL, 0x0c }, + { STB0899_TSOUT, 0x4d }, /* 0x0d for CAM */ + { STB0899_RSSYNCDEL, 0x00 }, + { STB0899_TSINHDELH, 0x02 }, + { STB0899_TSINHDELM, 0x00 }, + { STB0899_TSINHDELL, 0x00 }, + { STB0899_TSLLSTKM, 0x00 }, + { STB0899_TSLLSTKL, 0x00 }, + { STB0899_TSULSTKM, 0x00 }, + { STB0899_TSULSTKL, 0xab }, + { STB0899_PCKLENUL, 0x00 }, + { STB0899_PCKLENLL, 0xcc }, + { STB0899_RSPCKLEN, 0xcc }, + { STB0899_TSSTATUS, 0x80 }, + { STB0899_ERRCTRL1, 0xb6 }, + { STB0899_ERRCTRL2, 0x96 }, + { STB0899_ERRCTRL3, 0x89 }, + { STB0899_DMONMSK1, 0x27 }, + { STB0899_DMONMSK0, 0x03 }, + { STB0899_DEMAPVIT, 0x5c }, + { STB0899_PLPARM, 0x1f }, + { STB0899_PDELCTRL, 0x48 }, + { STB0899_PDELCTRL2, 0x00 }, + { STB0899_BBHCTRL1, 0x00 }, + { STB0899_BBHCTRL2, 0x00 }, + { STB0899_HYSTTHRESH, 0x77 }, + { STB0899_MATCSTM, 0x00 }, + { STB0899_MATCSTL, 0x00 }, + { STB0899_UPLCSTM, 0x00 }, + { STB0899_UPLCSTL, 0x00 }, + { STB0899_DFLCSTM, 0x00 }, + { STB0899_DFLCSTL, 0x00 }, + { STB0899_SYNCCST, 0x00 }, + { STB0899_SYNCDCSTM, 0x00 }, + { STB0899_SYNCDCSTL, 0x00 }, + { STB0899_ISI_ENTRY, 0x00 }, + { STB0899_ISI_BIT_EN, 0x00 }, + { STB0899_MATSTRM, 0x00 }, + { STB0899_MATSTRL, 0x00 }, + { STB0899_UPLSTRM, 0x00 }, + { STB0899_UPLSTRL, 0x00 }, + { STB0899_DFLSTRM, 0x00 }, + { STB0899_DFLSTRL, 0x00 }, + { STB0899_SYNCSTR, 0x00 }, + { STB0899_SYNCDSTRM, 0x00 }, + { STB0899_SYNCDSTRL, 0x00 }, + { STB0899_CFGPDELSTATUS1, 0x10 }, + { STB0899_CFGPDELSTATUS2, 0x00 }, + { STB0899_BBFERRORM, 0x00 }, + { STB0899_BBFERRORL, 0x00 }, + { STB0899_UPKTERRORM, 0x00 }, + { STB0899_UPKTERRORL, 0x00 }, + { 0xffff, 0xff }, }; static struct stb0899_config tt3200_config = { @@ -1359,7 +1358,7 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); + pr_err("%s(): No LNBP21 found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } @@ -1370,7 +1369,7 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); if (budget_ci->budget.dvb_frontend) { if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) { - printk(KERN_ERR "%s: No tda827x found!\n", __func__); + pr_err("%s(): No tda827x found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } @@ -1382,12 +1381,12 @@ static void frontend_init(struct budget_ci *budget_ci) if (budget_ci->budget.dvb_frontend) { if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) { if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { - printk(KERN_ERR "%s: No LNBP21 found!\n", __func__); + pr_err("%s(): No LNBP21 found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } } else { - printk(KERN_ERR "%s: No STB6000 found!\n", __func__); + pr_err("%s(): No STB6000 found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } @@ -1422,13 +1421,13 @@ static void frontend_init(struct budget_ci *budget_ci) if (budget_ci->budget.dvb_frontend) { if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) { if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { - printk("%s: No LNBP21 found!\n", __func__); + pr_err("%s(): No LNBP21 found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } } else { - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; + dvb_frontend_detach(budget_ci->budget.dvb_frontend); + budget_ci->budget.dvb_frontend = NULL; } } break; @@ -1436,7 +1435,7 @@ static void frontend_init(struct budget_ci *budget_ci) } if (budget_ci->budget.dvb_frontend == NULL) { - printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", budget_ci->budget.dev->pci->vendor, budget_ci->budget.dev->pci->device, budget_ci->budget.dev->pci->subsystem_vendor, @@ -1444,7 +1443,7 @@ static void frontend_init(struct budget_ci *budget_ci) } else { if (dvb_register_frontend (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { - printk("budget-ci: Frontend registration failed!\n"); + pr_err("Frontend registration failed!\n"); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } @@ -1538,7 +1537,7 @@ static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b), { .vendor = 0, - } + } }; MODULE_DEVICE_TABLE(pci, pci_tbl); diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index 25f44c3eebf312..d33adeca196f1d 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * budget-core.c: driver for the SAA7146 based Budget DVB cards + * budget-core.ko: base-driver for the SAA7146 based Budget DVB cards * * Compiled from various sources by Michael Hunold <michael@mihu.de> * @@ -34,6 +34,7 @@ #define BUFFER_WARNING_WAIT (30*HZ) int budget_debug; +EXPORT_SYMBOL_GPL(budget_debug); static int dma_buffer_size = TS_MIN_BUFSIZE_K; module_param_named(debug, budget_debug, int, 0644); module_param_named(bufsize, dma_buffer_size, int, 0444); @@ -80,7 +81,7 @@ static int start_ts_capture(struct budget *budget) * Pitch: 188, NumBytes3: 188, NumLines3: 1024 */ - switch(budget->card->type) { + switch (budget->card->type) { case BUDGET_FS_ACTIVY: saa7146_write(dev, DD1_INIT, 0x04000000); saa7146_write(dev, MC2, (MASK_09 | MASK_25)); @@ -208,7 +209,7 @@ static void vpeirq(struct tasklet_struct *t) budget->buffer_warnings++; if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { - printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", + pr_warn("%s %s: used %d times >80%% of buffer (%u bytes now)\n", budget->dev->name, __func__, budget->buffer_warnings, count); budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; budget->buffer_warnings = 0; @@ -259,6 +260,7 @@ int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count return ttpci_budget_debiread_nolock(budget, config, addr, count, nobusyloop); } +EXPORT_SYMBOL_GPL(ttpci_budget_debiread); static int ttpci_budget_debiwrite_nolock(struct budget *budget, u32 config, int addr, int count, u32 value, int nobusyloop) @@ -299,6 +301,7 @@ int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, return ttpci_budget_debiwrite_nolock(budget, config, addr, count, value, nobusyloop); } +EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); /**************************************************************************** @@ -423,7 +426,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, budget->card = bi; budget->dev = (struct saa7146_dev *) dev; - switch(budget->card->type) { + switch (budget->card->type) { case BUDGET_FS_ACTIVY: budget->buffer_width = TS_WIDTH_ACTIVY; max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; @@ -470,7 +473,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, budget->dev->name, budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single", budget->buffer_width, budget->buffer_height); - printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); + pr_info("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev, adapter_nums); @@ -491,8 +494,10 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, spin_lock_init(&budget->feedlock); spin_lock_init(&budget->debilock); - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is loaded */ + /* + * the Siemens DVB needs this if you want to have the i2c chips + * get recognized before the main driver is loaded + */ if (bi->type != BUDGET_FS_ACTIVY) saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ @@ -511,7 +516,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt); - if (NULL == budget->grabbing) { + if (budget->grabbing == NULL) { ret = -ENOMEM; goto err_del_i2c; } @@ -526,7 +531,8 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - if ((ret = budget_register(budget)) == 0) + ret = budget_register(budget); + if (ret == 0) return 0; /* Everything OK */ /* An error occurred, cleanup resources */ @@ -540,6 +546,7 @@ err_dvb_unregister: return ret; } +EXPORT_SYMBOL_GPL(ttpci_budget_init); void ttpci_budget_init_hooks(struct budget *budget) { @@ -548,6 +555,7 @@ void ttpci_budget_init_hooks(struct budget *budget) budget->dvb_frontend->ops.read_status = budget_read_fe_status; } } +EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); int ttpci_budget_deinit(struct budget *budget) { @@ -567,8 +575,9 @@ int ttpci_budget_deinit(struct budget *budget) return 0; } +EXPORT_SYMBOL_GPL(ttpci_budget_deinit); -void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr) +void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 *isr) { struct budget *budget = dev->ext_priv; @@ -577,6 +586,7 @@ void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr) if (*isr & MASK_10) tasklet_schedule(&budget->vpe_tasklet); } +EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) { @@ -590,14 +600,6 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) } spin_unlock(&budget->feedlock); } - -EXPORT_SYMBOL_GPL(ttpci_budget_debiread); -EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); -EXPORT_SYMBOL_GPL(ttpci_budget_init); -EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); -EXPORT_SYMBOL_GPL(ttpci_budget_deinit); -EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); -EXPORT_SYMBOL_GPL(budget_debug); MODULE_LICENSE("GPL"); diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index b76a1b330b500a..f623c250909b19 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * budget.c: driver for the SAA7146 based Budget DVB cards + * budget.ko: driver for the SAA7146 based Budget DVB cards + * without analog video input or CI * * Compiled from various sources by Michael Hunold <michael@mihu.de> * @@ -42,20 +43,24 @@ MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static void Set22K (struct budget *budget, int state) +static void Set22K(struct budget *budget, int state) { - struct saa7146_dev *dev=budget->dev; + struct saa7146_dev *dev = budget->dev; + dprintk(2, "budget: %p\n", budget); saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); } -/* Diseqc functions only for TT Budget card */ -/* taken from the Skyvision DVB driver by - Ralph Metzler <rjkm@metzlerbros.de> */ +/* + * Diseqc functions only for TT Budget card + * taken from the Skyvision DVB driver by + * Ralph Metzler <rjkm@metzlerbros.de> + */ -static void DiseqcSendBit (struct budget *budget, int data) +static void DiseqcSendBit(struct budget *budget, int data) { - struct saa7146_dev *dev=budget->dev; + struct saa7146_dev *dev = budget->dev; + dprintk(2, "budget: %p\n", budget); saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); @@ -64,13 +69,13 @@ static void DiseqcSendBit (struct budget *budget, int data) udelay(data ? 1000 : 500); } -static void DiseqcSendByte (struct budget *budget, int data) +static void DiseqcSendByte(struct budget *budget, int data) { - int i, par=1, d; + int i, par = 1, d; dprintk(2, "budget: %p\n", budget); - for (i=7; i>=0; i--) { + for (i = 7; i >= 0; i--) { d = (data>>i)&1; par ^= d; DiseqcSendBit(budget, d); @@ -79,9 +84,9 @@ static void DiseqcSendByte (struct budget *budget, int data) DiseqcSendBit(budget, par); } -static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) +static int SendDiSEqCMsg(struct budget *budget, int len, u8 *msg, unsigned long burst) { - struct saa7146_dev *dev=budget->dev; + struct saa7146_dev *dev = budget->dev; int i; dprintk(2, "budget: %p\n", budget); @@ -89,15 +94,15 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); mdelay(16); - for (i=0; i<len; i++) + for (i = 0; i < len; i++) DiseqcSendByte(budget, msg[i]); mdelay(16); - if (burst!=-1) { - if (burst) + if (burst != -1) { + if (burst) { DiseqcSendByte(budget, 0xff); - else { + } else { saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); mdelay(12); udelay(500); @@ -118,24 +123,24 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long static int SetVoltage_Activy(struct budget *budget, enum fe_sec_voltage voltage) { - struct saa7146_dev *dev=budget->dev; + struct saa7146_dev *dev = budget->dev; dprintk(2, "budget: %p\n", budget); switch (voltage) { - case SEC_VOLTAGE_13: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); - break; - case SEC_VOLTAGE_18: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - break; - case SEC_VOLTAGE_OFF: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); - break; - default: - return -EINVAL; + case SEC_VOLTAGE_13: + saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); + saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); + break; + case SEC_VOLTAGE_18: + saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); + saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); + break; + case SEC_VOLTAGE_OFF: + saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); + break; + default: + return -EINVAL; } return 0; @@ -146,7 +151,7 @@ static int siemens_budget_set_voltage(struct dvb_frontend *fe, { struct budget *budget = fe->dvb->priv; - return SetVoltage_Activy (budget, voltage); + return SetVoltage_Activy(budget, voltage); } static int budget_set_tone(struct dvb_frontend *fe, @@ -156,11 +161,11 @@ static int budget_set_tone(struct dvb_frontend *fe, switch (tone) { case SEC_TONE_ON: - Set22K (budget, 1); + Set22K(budget, 1); break; case SEC_TONE_OFF: - Set22K (budget, 0); + Set22K(budget, 0); break; default: @@ -170,11 +175,11 @@ static int budget_set_tone(struct dvb_frontend *fe, return 0; } -static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) +static int budget_diseqc_send_master_cmd(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) { struct budget *budget = fe->dvb->priv; - SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); + SendDiSEqCMsg(budget, cmd->msg_len, cmd->msg, 0); return 0; } @@ -184,7 +189,7 @@ static int budget_diseqc_send_burst(struct dvb_frontend *fe, { struct budget *budget = fe->dvb->priv; - SendDiSEqCMsg (budget, 0, NULL, minicmd); + SendDiSEqCMsg(budget, 0, NULL, minicmd); return 0; } @@ -208,7 +213,8 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) pwr = 0; else if (c->frequency >= 1100000) pwr = 1; - else pwr = 2; + else + pwr = 2; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; @@ -220,12 +226,12 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + return -EIO; return 0; } -static struct ves1x93_config alps_bsrv2_config = -{ +static struct ves1x93_config alps_bsrv2_config = { .demod_address = 0x08, .xin = 90100000UL, .invert_pwm = 0, @@ -248,7 +254,8 @@ static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + return -EIO; return 0; } @@ -303,7 +310,8 @@ static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + return -EIO; return 0; } @@ -333,7 +341,8 @@ static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + return -EIO; return 0; } @@ -365,7 +374,8 @@ static int s5h1420_tuner_set_params(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; + if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) + return -EIO; return 0; } @@ -422,12 +432,12 @@ static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; } -static u8 read_pwm(struct budget* budget) +static u8 read_pwm(struct budget *budget) { u8 b = 0xff; u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; + struct i2c_msg msg[] = { { .addr = 0x50, .flags = 0, .buf = &b, .len = 1 }, + { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} }; if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) pwm = 0x48; @@ -478,7 +488,7 @@ static void frontend_init(struct budget *budget) { (void)alps_bsbe1_config; /* avoid warning */ - switch(budget->dev->pci->subsystem_device) { + switch (budget->dev->pci->subsystem_device) { case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) case 0x1013: // try the ALPS BSRV2 first of all @@ -527,7 +537,7 @@ static void frontend_init(struct budget *budget) case 0x4f52: /* Cards based on Philips Semi Sylt PCI ref. design */ budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSRU6 in Philips Semi. Sylt detected\n"); + pr_info("tuner ALPS BSRU6 in Philips Semi. Sylt detected\n"); budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; break; @@ -545,7 +555,7 @@ static void frontend_init(struct budget *budget) /* assume ALPS BSRU6 */ budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n"); + pr_info("tuner ALPS BSRU6 detected\n"); budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; @@ -561,7 +571,7 @@ static void frontend_init(struct budget *budget) msleep(250); budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n"); + pr_info("tuner ALPS BSBE1 detected\n"); budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; budget->dvb_frontend->tuner_priv = &budget->i2c_adap; budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; @@ -607,7 +617,7 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = fe; if (dvb_attach(lnbp21_attach, fe, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); + pr_err("%s(): No LNBP21 found!\n", __func__); goto error_out; } break; @@ -629,10 +639,10 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = fe; if (dvb_attach(tda826x_attach, fe, 0x60, &budget->i2c_adap, 0) == NULL) - printk("%s: No tda826x found!\n", __func__); + pr_err("%s(): No tda826x found!\n", __func__); if (dvb_attach(lnbp21_attach, fe, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); + pr_err("%s(): No LNBP21 found!\n", __func__); goto error_out; } break; @@ -642,6 +652,7 @@ static void frontend_init(struct budget *budget) case 0x101c: { /* TT S2-1600 */ const struct stv6110x_devctl *ctl; + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); msleep(50); saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); @@ -672,9 +683,11 @@ static void frontend_init(struct budget *budget) tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; - /* call the init function once to initialize - tuner's clock output divider and demod's - master clock */ + /* + * call the init function once to initialize + * tuner's clock output divider and demod's + * master clock + */ if (budget->dvb_frontend->ops.init) budget->dvb_frontend->ops.init(budget->dvb_frontend); @@ -682,11 +695,11 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend, &budget->i2c_adap, &tt1600_isl6423_config) == NULL) { - printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__); + pr_err("%s(): No Intersil ISL6423 found!\n", __func__); goto error_out; } } else { - printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); + pr_err("%s(): No STV6110(A) Silicon Tuner found!\n", __func__); goto error_out; } } @@ -695,6 +708,7 @@ static void frontend_init(struct budget *budget) case 0x1020: { /* Omicom S2 */ const struct stv6110x_devctl *ctl; + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); msleep(50); saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); @@ -706,7 +720,7 @@ static void frontend_init(struct budget *budget) STV090x_DEMODULATOR_0); if (budget->dvb_frontend) { - printk(KERN_INFO "budget: Omicom S2 detected\n"); + pr_info("Omicom S2 detected\n"); ctl = dvb_attach(stv6110x_attach, budget->dvb_frontend, @@ -726,9 +740,11 @@ static void frontend_init(struct budget *budget) tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; - /* call the init function once to initialize - tuner's clock output divider and demod's - master clock */ + /* + * call the init function once to initialize + * tuner's clock output divider and demod's + * master clock + */ if (budget->dvb_frontend->ops.init) budget->dvb_frontend->ops.init(budget->dvb_frontend); @@ -737,12 +753,11 @@ static void frontend_init(struct budget *budget) &budget->i2c_adap, LNBH24_PCL | LNBH24_TTX, LNBH24_TEN, 0x14>>1) == NULL) { - printk(KERN_ERR - "No LNBH24 found!\n"); + pr_err("No LNBH24 found!\n"); goto error_out; } } else { - printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); + pr_err("%s(): No STV6110(A) Silicon Tuner found!\n", __func__); goto error_out; } } @@ -751,7 +766,7 @@ static void frontend_init(struct budget *budget) } if (budget->dvb_frontend == NULL) { - printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", + pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", budget->dev->pci->vendor, budget->dev->pci->device, budget->dev->pci->subsystem_vendor, @@ -763,21 +778,19 @@ static void frontend_init(struct budget *budget) return; error_out: - printk("budget: Frontend registration failed!\n"); + pr_err("Frontend registration failed!\n"); dvb_frontend_detach(budget->dvb_frontend); budget->dvb_frontend = NULL; - return; } -static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) +static int budget_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) { struct budget *budget = NULL; int err; budget = kmalloc(sizeof(struct budget), GFP_KERNEL); - if( NULL == budget ) { + if (budget == NULL) return -ENOMEM; - } dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); @@ -785,8 +798,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); if (err) { - printk("==> failed\n"); - kfree (budget); + pr_err("==> failed\n"); + kfree(budget); return err; } @@ -798,7 +811,7 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ return 0; } -static int budget_detach (struct saa7146_dev* dev) +static int budget_detach(struct saa7146_dev *dev) { struct budget *budget = dev->ext_priv; int err; @@ -808,9 +821,9 @@ static int budget_detach (struct saa7146_dev* dev) dvb_frontend_detach(budget->dvb_frontend); } - err = ttpci_budget_deinit (budget); + err = ttpci_budget_deinit(budget); - kfree (budget); + kfree(budget); dev->ext_priv = NULL; return err; @@ -839,8 +852,8 @@ static const struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), - MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), - MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), + MAKE_EXTENSION_PCI(fsacs1, 0x1131, 0x4f60), + MAKE_EXTENSION_PCI(fsacs0, 0x1131, 0x4f61), MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020), diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h index bd87432e6cde02..83ead34dc766b1 100644 --- a/drivers/media/pci/ttpci/budget.h +++ b/drivers/media/pci/ttpci/budget.h @@ -3,6 +3,12 @@ #ifndef __BUDGET_DVB__ #define __BUDGET_DVB__ +#ifdef pr_fmt +#undef pr_fmt +#endif + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <media/dvb_frontend.h> #include <media/dvbdev.h> #include <media/demux.h> @@ -22,9 +28,8 @@ extern int budget_debug; #endif #define dprintk(level, fmt, arg...) do { \ - if (level & budget_debug) \ - printk(KERN_DEBUG KBUILD_MODNAME ": %s(): " fmt, \ - __func__, ##arg); \ + if ((level) & budget_debug) \ + pr_info("%s(): " fmt, __func__, ##arg); \ } while (0) #define TS_SIZE 188 @@ -83,13 +88,13 @@ struct budget { void *priv; }; -#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \ +#define MAKE_BUDGET_INFO(x_var, x_name, x_type) \ static struct budget_info x_var ## _info = { \ - .name=x_name, \ - .type=x_type }; \ + .name = x_name, \ + .type = x_type }; \ static struct saa7146_pci_extension_data x_var = { \ .ext_priv = &x_var ## _info, \ - .ext = &budget_extension }; + .ext = &budget_extension } #define BUDGET_TT 0 #define BUDGET_TT_HW_DISEQC 1 @@ -119,7 +124,7 @@ extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, struct module *owner, short *adapter_nums); extern void ttpci_budget_init_hooks(struct budget *budget); extern int ttpci_budget_deinit(struct budget *budget); -extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); +extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 *isr); extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, int uselocks, int nobusyloop); diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 2d7b0508cc9afa..6f7d27a48eff04 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -239,10 +239,6 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG); - ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true); - if (ret) - goto err_disable_pclk; - /* Enable DPHY clk and data lanes. */ if (csi2rx->dphy) { reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST; @@ -252,6 +248,13 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) } writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); + + ret = csi2rx_configure_ext_dphy(csi2rx); + if (ret) { + dev_err(csi2rx->dev, + "Failed to configure external DPHY: %d\n", ret); + goto err_disable_pclk; + } } /* @@ -291,14 +294,9 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) reset_control_deassert(csi2rx->sys_rst); - if (csi2rx->dphy) { - ret = csi2rx_configure_ext_dphy(csi2rx); - if (ret) { - dev_err(csi2rx->dev, - "Failed to configure external DPHY: %d\n", ret); - goto err_disable_sysclk; - } - } + ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true); + if (ret) + goto err_disable_sysclk; clk_disable_unprepare(csi2rx->p_clk); @@ -312,6 +310,10 @@ err_disable_pixclk: clk_disable_unprepare(csi2rx->pixel_clk[i - 1]); } + if (csi2rx->dphy) { + writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG); + phy_power_off(csi2rx->dphy); + } err_disable_pclk: clk_disable_unprepare(csi2rx->p_clk); diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index 9ce34a3b5ee67d..c60e4c193b2562 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -49,7 +49,6 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; - unsigned long size = mem->size; int id; if (inst_type == MTK_INST_ENCODER) { @@ -64,15 +63,15 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) id = dec_ctx->id; } - mem->va = dma_alloc_coherent(&plat_dev->dev, size, &mem->dma_addr, GFP_KERNEL); + mem->va = dma_alloc_coherent(&plat_dev->dev, mem->size, &mem->dma_addr, GFP_KERNEL); if (!mem->va) { - mtk_v4l2_err(plat_dev, "%s dma_alloc size=%ld failed!", - dev_name(&plat_dev->dev), size); + mtk_v4l2_err(plat_dev, "%s dma_alloc size=0x%zx failed!", + __func__, mem->size); return -ENOMEM; } - mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, - (unsigned long)mem->dma_addr, size); + mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%zx", id, mem->va, + (unsigned long)mem->dma_addr, mem->size); return 0; } @@ -82,7 +81,6 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; - unsigned long size = mem->size; int id; if (inst_type == MTK_INST_ENCODER) { @@ -98,15 +96,16 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) } if (!mem->va) { - mtk_v4l2_err(plat_dev, "%s dma_free size=%ld failed!", - dev_name(&plat_dev->dev), size); + mtk_v4l2_err(plat_dev, "%s: Tried to free a NULL VA", __func__); + if (mem->size) + mtk_v4l2_err(plat_dev, "Failed to free %zu bytes", mem->size); return; } - mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%lx", id, mem->va, - (unsigned long)mem->dma_addr, size); + mtk_v4l2_debug(plat_dev, 3, "[%d] - va = %p dma = 0x%lx size = 0x%zx", id, mem->va, + (unsigned long)mem->dma_addr, mem->size); - dma_free_coherent(&plat_dev->dev, size, mem->va, mem->dma_addr); + dma_free_coherent(&plat_dev->dev, mem->size, mem->va, mem->dma_addr); mem->va = NULL; mem->dma_addr = 0; mem->size = 0; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c index a081e12d67d613..bf21f2467a0fcd 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c @@ -1023,18 +1023,26 @@ static void vdec_av1_slice_free_working_buffer(struct vdec_av1_slice_instance *i int i; for (i = 0; i < ARRAY_SIZE(instance->mv); i++) - mtk_vcodec_mem_free(ctx, &instance->mv[i]); + if (instance->mv[i].va) + mtk_vcodec_mem_free(ctx, &instance->mv[i]); for (i = 0; i < ARRAY_SIZE(instance->seg); i++) - mtk_vcodec_mem_free(ctx, &instance->seg[i]); + if (instance->seg[i].va) + mtk_vcodec_mem_free(ctx, &instance->seg[i]); for (i = 0; i < ARRAY_SIZE(instance->cdf); i++) - mtk_vcodec_mem_free(ctx, &instance->cdf[i]); + if (instance->cdf[i].va) + mtk_vcodec_mem_free(ctx, &instance->cdf[i]); + - mtk_vcodec_mem_free(ctx, &instance->tile); - mtk_vcodec_mem_free(ctx, &instance->cdf_temp); - mtk_vcodec_mem_free(ctx, &instance->cdf_table); - mtk_vcodec_mem_free(ctx, &instance->iq_table); + if (instance->tile.va) + mtk_vcodec_mem_free(ctx, &instance->tile); + if (instance->cdf_temp.va) + mtk_vcodec_mem_free(ctx, &instance->cdf_temp); + if (instance->cdf_table.va) + mtk_vcodec_mem_free(ctx, &instance->cdf_table); + if (instance->iq_table.va) + mtk_vcodec_mem_free(ctx, &instance->iq_table); instance->level = AV1_RES_NONE; } diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c index a22b7dfc656e14..1a2b14a3e219c2 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c @@ -58,13 +58,15 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *mtkdev) return 0; } -void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm) { int ret; ret = pm_runtime_resume_and_get(pm->dev); if (ret) dev_err(pm->dev, "pm_runtime_resume_and_get fail: %d", ret); + + return ret; } void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm) diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h index 157ea08ba9e36a..2e28f25e36cc42 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h @@ -10,7 +10,7 @@ #include "mtk_vcodec_enc_drv.h" int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev); -void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm); +int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm); diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c index a68dac72c4e426..f8145998fcaf78 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c @@ -301,11 +301,12 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst) * other buffers need to be freed by AP. */ for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) { - if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME) + if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME && inst->work_bufs[i].va) mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]); } - mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf); + if (inst->pps_buf.va) + mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf); } static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c index c402a686f3cb2d..e83747b8d69ab3 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c @@ -64,7 +64,9 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ctx->dev->curr_ctx = ctx; spin_unlock_irqrestore(&ctx->dev->irqlock, flags); - mtk_vcodec_enc_pw_on(&ctx->dev->pm); + ret = mtk_vcodec_enc_pw_on(&ctx->dev->pm); + if (ret) + goto venc_if_encode_pw_on_err; mtk_vcodec_enc_clock_on(&ctx->dev->pm); ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf, bs_buf, result); @@ -75,6 +77,7 @@ int venc_if_encode(struct mtk_vcodec_enc_ctx *ctx, ctx->dev->curr_ctx = NULL; spin_unlock_irqrestore(&ctx->dev->irqlock, flags); +venc_if_encode_pw_on_err: mtk_venc_unlock(ctx); return ret; } diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c index db8ff5f5c4d3cd..f49b06978f14d6 100644 --- a/drivers/media/platform/nxp/imx-mipi-csis.c +++ b/drivers/media/platform/nxp/imx-mipi-csis.c @@ -30,6 +30,7 @@ #include <media/v4l2-common.h> #include <media/v4l2-device.h> +#include <media/v4l2-event.h> #include <media/v4l2-fwnode.h> #include <media/v4l2-mc.h> #include <media/v4l2-subdev.h> @@ -742,6 +743,18 @@ static void mipi_csis_stop_stream(struct mipi_csis_device *csis) mipi_csis_system_enable(csis, false); } +static void mipi_csis_queue_event_sof(struct mipi_csis_device *csis) +{ + struct v4l2_event event = { + .type = V4L2_EVENT_FRAME_SYNC, + }; + u32 frame; + + frame = mipi_csis_read(csis, MIPI_CSIS_FRAME_COUNTER_CH(0)); + event.u.frame_sync.frame_sequence = frame; + v4l2_event_queue(csis->sd.devnode, &event); +} + static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) { struct mipi_csis_device *csis = dev_id; @@ -765,6 +778,10 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) event->counter++; } } + + if (status & MIPI_CSIS_INT_SRC_FRAME_START) + mipi_csis_queue_event_sof(csis); + spin_unlock_irqrestore(&csis->slock, flags); mipi_csis_write(csis, MIPI_CSIS_INT_SRC, status); @@ -1154,8 +1171,23 @@ static int mipi_csis_log_status(struct v4l2_subdev *sd) return 0; } +static int mipi_csis_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + if (sub->type != V4L2_EVENT_FRAME_SYNC) + return -EINVAL; + + /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */ + if (sub->id != 0) + return -EINVAL; + + return v4l2_event_subscribe(fh, sub, 0, NULL); +} + static const struct v4l2_subdev_core_ops mipi_csis_core_ops = { .log_status = mipi_csis_log_status, + .subscribe_event = mipi_csis_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, }; static const struct v4l2_subdev_video_ops mipi_csis_video_ops = { @@ -1358,7 +1390,7 @@ static int mipi_csis_subdev_init(struct mipi_csis_device *csis) snprintf(sd->name, sizeof(sd->name), "csis-%s", dev_name(csis->dev)); - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; sd->ctrl_handler = NULL; sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; diff --git a/drivers/media/platform/st/sti/c8sectpfe/Kconfig b/drivers/media/platform/st/sti/c8sectpfe/Kconfig index 702b910509c9c9..01c33d9c9ec37d 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/Kconfig +++ b/drivers/media/platform/st/sti/c8sectpfe/Kconfig @@ -5,7 +5,6 @@ config DVB_C8SECTPFE depends on PINCTRL && DVB_CORE && I2C depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST select FW_LOADER - select DEBUG_FS select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/platform/st/sti/c8sectpfe/Makefile b/drivers/media/platform/st/sti/c8sectpfe/Makefile index aedfc725cc19d8..99425137ee0a9e 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/Makefile +++ b/drivers/media/platform/st/sti/c8sectpfe/Makefile @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -c8sectpfe-y += c8sectpfe-core.o c8sectpfe-common.o c8sectpfe-dvb.o \ - c8sectpfe-debugfs.o +c8sectpfe-y += c8sectpfe-core.o c8sectpfe-common.o c8sectpfe-dvb.o + +ifneq ($(CONFIG_DEBUG_FS),) +c8sectpfe-y += c8sectpfe-debugfs.o +endif obj-$(CONFIG_DVB_C8SECTPFE) += c8sectpfe.o diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c index 0df2a1b4974b23..2f58a0d0df8556 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c @@ -1096,7 +1096,6 @@ static int load_slim_core_fw(const struct firmware *fw, struct c8sectpfei *fei) } } - release_firmware(fw); return err; } @@ -1120,6 +1119,7 @@ static int load_c8sectpfe_fw(struct c8sectpfei *fei) } err = load_slim_core_fw(fw, fei); + release_firmware(fw); if (err) { dev_err(fei->dev, "load_slim_core_fw failed err=(%d)\n", err); return err; diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.h b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.h index d2c35fb32d7ef0..8e1bfd86052476 100644 --- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.h +++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-debugfs.h @@ -12,7 +12,12 @@ #include "c8sectpfe-core.h" +#if defined(CONFIG_DEBUG_FS) void c8sectpfe_debugfs_init(struct c8sectpfei *); void c8sectpfe_debugfs_exit(struct c8sectpfei *); +#else +static inline void c8sectpfe_debugfs_init(struct c8sectpfei *) {}; +static inline void c8sectpfe_debugfs_exit(struct c8sectpfei *) {}; +#endif #endif /* __C8SECTPFE_DEBUG_H */ diff --git a/drivers/media/platform/st/sti/hva/hva-hw.c b/drivers/media/platform/st/sti/hva/hva-hw.c index fe4ea2e7f37e3f..fcb18fb52fdd7e 100644 --- a/drivers/media/platform/st/sti/hva/hva-hw.c +++ b/drivers/media/platform/st/sti/hva/hva-hw.c @@ -406,8 +406,7 @@ err_pm: err_disable: pm_runtime_disable(dev); err_clk: - if (hva->clk) - clk_unprepare(hva->clk); + clk_unprepare(hva->clk); return ret; } diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 6da83d0cffaaed..22442fce760785 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -786,15 +786,14 @@ static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb) dev_warn(csi->dev, "Failed to drain DMA. Next frame might be bogus\n"); + spin_lock_irqsave(&dma->lock, flags); ret = ti_csi2rx_start_dma(csi, buf); if (ret) { - dev_err(csi->dev, "Failed to start DMA: %d\n", ret); - spin_lock_irqsave(&dma->lock, flags); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); dma->state = TI_CSI2RX_DMA_IDLE; spin_unlock_irqrestore(&dma->lock, flags); + dev_err(csi->dev, "Failed to start DMA: %d\n", ret); } else { - spin_lock_irqsave(&dma->lock, flags); list_add_tail(&buf->list, &dma->submitted); spin_unlock_irqrestore(&dma->lock, flags); } diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index 6be4e5528879fb..65fa7f857fcaf9 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -388,7 +388,7 @@ static int cxd2880_start_feed(struct dvb_demux_feed *feed) if (dvb_spi->feed_count == 0) { dvb_spi->ts_buf = - kmalloc(MAX_TRANS_PKT * 188, + kzalloc(MAX_TRANS_PKT * 188, GFP_KERNEL | GFP_DMA); if (!dvb_spi->ts_buf) { pr_err("ts buffer allocate failed\n"); diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 2182e5b7b6064c..30aa4ee958bdea 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -58,7 +58,7 @@ struct xc5000_priv { struct dvb_frontend *fe; struct delayed_work timer_sleep; - const struct firmware *firmware; + bool inited; }; /* Misc Defines */ @@ -1110,23 +1110,19 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) if (!force && xc5000_is_firmware_loaded(fe) == 0) return 0; - if (!priv->firmware) { - ret = request_firmware(&fw, desired_fw->name, - priv->i2c_props.adap->dev.parent); - if (ret) { - pr_err("xc5000: Upload failed. rc %d\n", ret); - return ret; - } - dprintk(1, "firmware read %zu bytes.\n", fw->size); + ret = request_firmware(&fw, desired_fw->name, + priv->i2c_props.adap->dev.parent); + if (ret) { + pr_err("xc5000: Upload failed. rc %d\n", ret); + return ret; + } + dprintk(1, "firmware read %zu bytes.\n", fw->size); - if (fw->size != desired_fw->size) { - pr_err("xc5000: Firmware file with incorrect size\n"); - release_firmware(fw); - return -EINVAL; - } - priv->firmware = fw; - } else - fw = priv->firmware; + if (fw->size != desired_fw->size) { + pr_err("xc5000: Firmware file with incorrect size\n"); + release_firmware(fw); + return -EINVAL; + } /* Try up to 5 times to load firmware */ for (i = 0; i < 5; i++) { @@ -1204,6 +1200,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) } err: + release_firmware(fw); if (!ret) printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n", desired_fw->name); @@ -1274,7 +1271,7 @@ static int xc5000_resume(struct dvb_frontend *fe) /* suspended before firmware is loaded. Avoid firmware load in resume path. */ - if (!priv->firmware) + if (!priv->inited) return 0; return xc5000_set_params(fe); @@ -1293,6 +1290,8 @@ static int xc5000_init(struct dvb_frontend *fe) if (debug) xc_debug_dump(priv); + priv->inited = true; + return 0; } @@ -1306,10 +1305,6 @@ static void xc5000_release(struct dvb_frontend *fe) if (priv) { cancel_delayed_work(&priv->timer_sleep); - if (priv->firmware) { - release_firmware(priv->firmware); - priv->firmware = NULL; - } hybrid_tuner_release_state(priv); } diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 3af594134a6de9..6ddc2051339396 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -2412,7 +2412,12 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); - return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; + if (!adap->fe_adap[0].fe) { + release_firmware(state->frontend_firmware); + return -ENODEV; + } + + return 0; } static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) @@ -2485,8 +2490,10 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80); adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); - if (adap->fe_adap[0].fe == NULL) + if (!adap->fe_adap[0].fe) { + release_firmware(state->frontend_firmware); return -ENODEV; + } i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82); @@ -2494,7 +2501,12 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]); dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); - return fe_slave == NULL ? -ENODEV : 0; + if (!fe_slave) { + release_firmware(state->frontend_firmware); + return -ENODEV; + } + + return 0; } static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index b3bb1805829adb..03b411ad64bbce 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -36,7 +36,6 @@ /* Max transfer size done by I2C transfer functions */ #define MAX_XFER_SIZE 64 - #define DW210X_READ_MSG 0 #define DW210X_WRITE_MSG 1 @@ -53,10 +52,10 @@ #define DW2102_FIRMWARE "dvb-usb-dw2102.fw" #define DW2104_FIRMWARE "dvb-usb-dw2104.fw" #define DW3101_FIRMWARE "dvb-usb-dw3101.fw" -#define S630_FIRMWARE "dvb-usb-s630.fw" -#define S660_FIRMWARE "dvb-usb-s660.fw" -#define P1100_FIRMWARE "dvb-usb-p1100.fw" -#define P7500_FIRMWARE "dvb-usb-p7500.fw" +#define S630_FIRMWARE "dvb-usb-s630.fw" +#define S660_FIRMWARE "dvb-usb-s660.fw" +#define P1100_FIRMWARE "dvb-usb-p1100.fw" +#define P7500_FIRMWARE "dvb-usb-p7500.fw" #define err_str "did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware" @@ -87,7 +86,7 @@ MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+s DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, - u16 index, u8 * data, u16 len, int flags) + u16 index, u8 *data, u16 len, int flags) { int ret; u8 *u8buf; @@ -99,11 +98,10 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, if (!u8buf) return -ENOMEM; - if (flags == DW210X_WRITE_MSG) memcpy(u8buf, data, len); ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, - value, index , u8buf, len, 2000); + value, index, u8buf, len, 2000); if (flags == DW210X_READ_MSG) memcpy(data, u8buf, len); @@ -114,7 +112,7 @@ static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, /* I2C */ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i = 0; @@ -136,7 +134,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], value = msg[0].buf[0];/* register */ for (i = 0; i < msg[1].len; i++) { dw210x_op_rw(d->udev, 0xb5, value + i, 0, - buf6, 2, DW210X_READ_MSG); + buf6, 2, DW210X_READ_MSG); msg[1].buf[i] = buf6[0]; } break; @@ -152,7 +150,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], buf6[1] = msg[0].buf[0]; buf6[2] = msg[0].buf[1]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 3, DW210X_WRITE_MSG); + buf6, 3, DW210X_WRITE_MSG); break; case 0x60: if (msg[0].flags == 0) { @@ -169,7 +167,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], buf6[5] = msg[0].buf[2]; buf6[6] = msg[0].buf[3]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 7, DW210X_WRITE_MSG); + buf6, 7, DW210X_WRITE_MSG); } else { if (msg[0].len < 1) { num = -EOPNOTSUPP; @@ -177,7 +175,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], } /* read from tuner */ dw210x_op_rw(d->udev, 0xb5, 0, 0, - buf6, 1, DW210X_READ_MSG); + buf6, 1, DW210X_READ_MSG); msg[0].buf[0] = buf6[0]; } break; @@ -187,7 +185,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], break; } dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); + buf6, 2, DW210X_READ_MSG); msg[0].buf[0] = buf6[0]; msg[0].buf[1] = buf6[1]; break; @@ -199,7 +197,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], buf6[0] = 0x30; buf6[1] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); + buf6, 2, DW210X_WRITE_MSG); break; } @@ -211,7 +209,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], } static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, - struct i2c_msg msg[], int num) + struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; @@ -242,10 +240,10 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, buf6[1] = msg[0].len; buf6[2] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xc2, 0, 0, - buf6, msg[0].len + 2, DW210X_WRITE_MSG); + buf6, msg[0].len + 2, DW210X_WRITE_MSG); /* read si2109 register */ dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, - buf6, msg[1].len + 2, DW210X_READ_MSG); + buf6, msg[1].len + 2, DW210X_READ_MSG); memcpy(msg[1].buf, buf6 + 2, msg[1].len); break; @@ -264,11 +262,11 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, buf6[1] = msg[0].len; memcpy(buf6 + 2, msg[0].buf, msg[0].len); dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, - msg[0].len + 2, DW210X_WRITE_MSG); + msg[0].len + 2, DW210X_WRITE_MSG); break; case(DW2102_RC_QUERY): dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); + buf6, 2, DW210X_READ_MSG); msg[0].buf[0] = buf6[0]; msg[0].buf[1] = buf6[1]; break; @@ -276,7 +274,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, buf6[0] = 0x30; buf6[1] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); + buf6, 2, DW210X_WRITE_MSG); break; } break; @@ -320,10 +318,10 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms obuf[1] = msg[0].len; obuf[2] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); + obuf, msg[0].len + 2, DW210X_WRITE_MSG); /* second read registers */ - dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); + dw210x_op_rw(d->udev, 0xc3, 0xd1, 0, + ibuf, msg[1].len + 2, DW210X_READ_MSG); memcpy(msg[1].buf, ibuf + 2, msg[1].len); break; @@ -345,7 +343,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms obuf[1] = msg[0].len; memcpy(obuf + 2, msg[0].buf, msg[0].len); dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); + obuf, msg[0].len + 2, DW210X_WRITE_MSG); break; } case 0x61: { @@ -363,22 +361,24 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms obuf[1] = msg[0].len; memcpy(obuf + 2, msg[0].buf, msg[0].len); dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); + obuf, msg[0].len + 2, DW210X_WRITE_MSG); break; } case(DW2102_RC_QUERY): { u8 ibuf[2]; + dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); + ibuf, 2, DW210X_READ_MSG); + memcpy(msg[0].buf, ibuf, 2); break; } case(DW2102_VOLTAGE_CTRL): { u8 obuf[2]; + obuf[0] = 0x30; obuf[1] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); + obuf, 2, DW210X_WRITE_MSG); break; } } @@ -406,23 +406,26 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i switch (msg[j].addr) { case(DW2102_RC_QUERY): { u8 ibuf[2]; + dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[j].buf, ibuf , 2); + ibuf, 2, DW210X_READ_MSG); + memcpy(msg[j].buf, ibuf, 2); break; } case(DW2102_VOLTAGE_CTRL): { u8 obuf[2]; + obuf[0] = 0x30; obuf[1] = msg[j].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); + obuf, 2, DW210X_WRITE_MSG); break; } - /*case 0x55: cx24116 - case 0x6a: stv0903 - case 0x68: ds3000, stv0903 - case 0x60: ts2020, stv6110, stb6100 */ + /* case 0x55: cx24116 + * case 0x6a: stv0903 + * case 0x68: ds3000, stv0903 + * case 0x60: ts2020, stv6110, stb6100 + */ default: { if (msg[j].flags == I2C_M_RD) { /* read registers */ @@ -436,17 +439,16 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i } dw210x_op_rw(d->udev, 0xc3, - (msg[j].addr << 1) + 1, 0, - ibuf, msg[j].len + 2, - DW210X_READ_MSG); + (msg[j].addr << 1) + 1, 0, + ibuf, msg[j].len + 2, + DW210X_READ_MSG); memcpy(msg[j].buf, ibuf + 2, msg[j].len); mdelay(10); - } else if (((msg[j].buf[0] == 0xb0) && - (msg[j].addr == 0x68)) || - ((msg[j].buf[0] == 0xf7) && - (msg[j].addr == 0x55))) { + } else if (((msg[j].buf[0] == 0xb0) && (msg[j].addr == 0x68)) || + ((msg[j].buf[0] == 0xf7) && (msg[j].addr == 0x55))) { /* write firmware */ u8 obuf[19]; + obuf[0] = msg[j].addr << 1; obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len); obuf[2] = msg[j].buf[0]; @@ -454,10 +456,10 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i i = 1; do { memcpy(obuf + 3, msg[j].buf + i, - (len > 16 ? 16 : len)); + (len > 16 ? 16 : len)); dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, (len > 16 ? 16 : len) + 3, - DW210X_WRITE_MSG); + obuf, (len > 16 ? 16 : len) + 3, + DW210X_WRITE_MSG); i += 16; len -= 16; } while (len > 0); @@ -476,13 +478,12 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i obuf[1] = msg[j].len; memcpy(obuf + 2, msg[j].buf, msg[j].len); dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[j].len + 2, - DW210X_WRITE_MSG); + obuf, msg[j].len + 2, + DW210X_WRITE_MSG); } break; } } - } ret = num; @@ -492,7 +493,7 @@ unlock: } static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int ret; @@ -525,10 +526,10 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[1] = msg[0].len; obuf[2] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); + obuf, msg[0].len + 2, DW210X_WRITE_MSG); /* second read registers */ - dw210x_op_rw(d->udev, 0xc3, 0x19 , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); + dw210x_op_rw(d->udev, 0xc3, 0x19, 0, + ibuf, msg[1].len + 2, DW210X_READ_MSG); memcpy(msg[1].buf, ibuf + 2, msg[1].len); break; @@ -550,14 +551,15 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[1] = msg[0].len; memcpy(obuf + 2, msg[0].buf, msg[0].len); dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); + obuf, msg[0].len + 2, DW210X_WRITE_MSG); break; } case(DW2102_RC_QUERY): { u8 ibuf[2]; + dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); + ibuf, 2, DW210X_READ_MSG); + memcpy(msg[0].buf, ibuf, 2); break; } } @@ -567,7 +569,7 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], for (i = 0; i < num; i++) { deb_xfer("%02x:%02x: %s ", i, msg[i].addr, - msg[i].flags == 0 ? ">>>" : "<<<"); + msg[i].flags == 0 ? ">>>" : "<<<"); debug_dump(msg[i].buf, msg[i].len, deb_xfer); } ret = num; @@ -578,7 +580,7 @@ unlock: } static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct usb_device *udev; @@ -594,8 +596,9 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], switch (msg[j].addr) { case (DW2102_RC_QUERY): { u8 ibuf[5]; + dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 5, DW210X_READ_MSG); + ibuf, 5, DW210X_READ_MSG); memcpy(msg[j].buf, ibuf + 3, 2); break; } @@ -605,11 +608,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[0] = 1; obuf[1] = msg[j].buf[1];/* off-on */ dw210x_op_rw(d->udev, 0x8a, 0, 0, - obuf, 2, DW210X_WRITE_MSG); + obuf, 2, DW210X_WRITE_MSG); obuf[0] = 3; obuf[1] = msg[j].buf[0];/* 13v-18v */ dw210x_op_rw(d->udev, 0x8a, 0, 0, - obuf, 2, DW210X_WRITE_MSG); + obuf, 2, DW210X_WRITE_MSG); break; } case (DW2102_LED_CTRL): { @@ -618,14 +621,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[0] = 5; obuf[1] = msg[j].buf[0]; dw210x_op_rw(d->udev, 0x8a, 0, 0, - obuf, 2, DW210X_WRITE_MSG); + obuf, 2, DW210X_WRITE_MSG); break; } - /*case 0x55: cx24116 - case 0x6a: stv0903 - case 0x68: ds3000, stv0903, rs2000 - case 0x60: ts2020, stv6110, stb6100 - case 0xa0: eeprom */ + /* case 0x55: cx24116 + * case 0x6a: stv0903 + * case 0x68: ds3000, stv0903, rs2000 + * case 0x60: ts2020, stv6110, stb6100 + * case 0xa0: eeprom + */ default: { if (msg[j].flags == I2C_M_RD) { /* read registers */ @@ -639,14 +643,14 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], } dw210x_op_rw(d->udev, 0x91, 0, 0, - ibuf, msg[j].len, + ibuf, msg[j].len, DW210X_READ_MSG); memcpy(msg[j].buf, ibuf, msg[j].len); break; - } else if ((msg[j].buf[0] == 0xb0) && - (msg[j].addr == 0x68)) { + } else if ((msg[j].buf[0] == 0xb0) && (msg[j].addr == 0x68)) { /* write firmware */ u8 obuf[19]; + obuf[0] = (msg[j].len > 16 ? 18 : msg[j].len + 1); obuf[1] = msg[j].addr << 1; @@ -655,10 +659,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i = 1; do { memcpy(obuf + 3, msg[j].buf + i, - (len > 16 ? 16 : len)); + (len > 16 ? 16 : len)); dw210x_op_rw(d->udev, 0x80, 0, 0, - obuf, (len > 16 ? 16 : len) + 3, - DW210X_WRITE_MSG); + obuf, (len > 16 ? 16 : len) + 3, + DW210X_WRITE_MSG); i += 16; len -= 16; } while (len > 0); @@ -677,10 +681,9 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[1] = (msg[j].addr << 1); memcpy(obuf + 2, msg[j].buf, msg[j].len); dw210x_op_rw(d->udev, - le16_to_cpu(udev->descriptor.idProduct) == - 0x7500 ? 0x92 : 0x90, 0, 0, - obuf, msg[j].len + 2, - DW210X_WRITE_MSG); + le16_to_cpu(udev->descriptor.idProduct) == 0x7500 ? 0x92 : 0x90, + 0, 0, obuf, msg[j].len + 2, + DW210X_WRITE_MSG); break; } else { /* write registers */ @@ -696,8 +699,8 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf[1] = (msg[j].addr << 1); memcpy(obuf + 2, msg[j].buf, msg[j].len); dw210x_op_rw(d->udev, 0x80, 0, 0, - obuf, msg[j].len + 2, - DW210X_WRITE_MSG); + obuf, msg[j].len + 2, + DW210X_WRITE_MSG); break; } break; @@ -712,10 +715,11 @@ unlock: } static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct dw2102_state *state; + int j; if (!d) return -ENODEV; @@ -729,77 +733,102 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], return -EAGAIN; } - switch (num) { - case 1: - switch (msg[0].addr) { + j = 0; + while (j < num) { + switch (msg[j].addr) { case SU3000_STREAM_CTRL: - state->data[0] = msg[0].buf[0] + 0x36; + state->data[0] = msg[j].buf[0] + 0x36; state->data[1] = 3; state->data[2] = 0; if (dvb_usb_generic_rw(d, state->data, 3, - state->data, 0, 0) < 0) + state->data, 0, 0) < 0) err("i2c transfer failed."); break; case DW2102_RC_QUERY: state->data[0] = 0x10; if (dvb_usb_generic_rw(d, state->data, 1, - state->data, 2, 0) < 0) + state->data, 2, 0) < 0) err("i2c transfer failed."); - msg[0].buf[1] = state->data[0]; - msg[0].buf[0] = state->data[1]; + msg[j].buf[1] = state->data[0]; + msg[j].buf[0] = state->data[1]; break; default: - if (3 + msg[0].len > sizeof(state->data)) { - warn("i2c wr: len=%d is too big!\n", - msg[0].len); - num = -EOPNOTSUPP; + /* if the current write msg is followed by a another + * read msg to/from the same address + */ + if ((j + 1 < num) && (msg[j + 1].flags & I2C_M_RD) && + (msg[j].addr == msg[j + 1].addr)) { + /* join both i2c msgs to one usb read command */ + if (4 + msg[j].len > sizeof(state->data)) { + warn("i2c combined wr/rd: write len=%d is too big!\n", + msg[j].len); + num = -EOPNOTSUPP; + break; + } + if (1 + msg[j + 1].len > sizeof(state->data)) { + warn("i2c combined wr/rd: read len=%d is too big!\n", + msg[j + 1].len); + num = -EOPNOTSUPP; + break; + } + + state->data[0] = 0x09; + state->data[1] = msg[j].len; + state->data[2] = msg[j + 1].len; + state->data[3] = msg[j].addr; + memcpy(&state->data[4], msg[j].buf, msg[j].len); + + if (dvb_usb_generic_rw(d, state->data, msg[j].len + 4, + state->data, msg[j + 1].len + 1, 0) < 0) + err("i2c transfer failed."); + + memcpy(msg[j + 1].buf, &state->data[1], msg[j + 1].len); + j++; break; } - /* always i2c write*/ - state->data[0] = 0x08; - state->data[1] = msg[0].addr; - state->data[2] = msg[0].len; + if (msg[j].flags & I2C_M_RD) { + /* single read */ + if (1 + msg[j].len > sizeof(state->data)) { + warn("i2c rd: len=%d is too big!\n", msg[j].len); + num = -EOPNOTSUPP; + break; + } - memcpy(&state->data[3], msg[0].buf, msg[0].len); + state->data[0] = 0x09; + state->data[1] = 0; + state->data[2] = msg[j].len; + state->data[3] = msg[j].addr; + memcpy(&state->data[4], msg[j].buf, msg[j].len); - if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3, - state->data, 1, 0) < 0) - err("i2c transfer failed."); + if (dvb_usb_generic_rw(d, state->data, 4, + state->data, msg[j].len + 1, 0) < 0) + err("i2c transfer failed."); - } - break; - case 2: - /* always i2c read */ - if (4 + msg[0].len > sizeof(state->data)) { - warn("i2c rd: len=%d is too big!\n", - msg[0].len); - num = -EOPNOTSUPP; - break; - } - if (1 + msg[1].len > sizeof(state->data)) { - warn("i2c rd: len=%d is too big!\n", - msg[1].len); - num = -EOPNOTSUPP; - break; - } + memcpy(msg[j].buf, &state->data[1], msg[j].len); + break; + } - state->data[0] = 0x09; - state->data[1] = msg[0].len; - state->data[2] = msg[1].len; - state->data[3] = msg[0].addr; - memcpy(&state->data[4], msg[0].buf, msg[0].len); + /* single write */ + if (3 + msg[j].len > sizeof(state->data)) { + warn("i2c wr: len=%d is too big!\n", msg[j].len); + num = -EOPNOTSUPP; + break; + } - if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4, - state->data, msg[1].len + 1, 0) < 0) - err("i2c transfer failed."); + state->data[0] = 0x08; + state->data[1] = msg[j].addr; + state->data[2] = msg[j].len; - memcpy(msg[1].buf, &state->data[1], msg[1].len); - break; - default: - warn("more than 2 i2c messages at a time is not handled yet."); - break; - } + memcpy(&state->data[3], msg[j].buf, msg[j].len); + + if (dvb_usb_generic_rw(d, state->data, msg[j].len + 3, + state->data, 1, 0) < 0) + err("i2c transfer failed."); + } // switch + j++; + + } // while mutex_unlock(&d->data_mutex); mutex_unlock(&d->i2c_mutex); return num; @@ -852,11 +881,11 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) u8 eeprom[256], eepromline[16]; for (i = 0; i < 256; i++) { - if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { + if (dw210x_op_rw(d->udev, 0xb6, 0xa0, i, ibuf, 2, DW210X_READ_MSG) < 0) { err("read eeprom failed."); return -EIO; } else { - eepromline[i%16] = ibuf[0]; + eepromline[i % 16] = ibuf[0]; eeprom[i] = ibuf[0]; } if ((i % 16) == 15) { @@ -963,7 +992,6 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) .flags = I2C_M_RD, .buf = ibuf, .len = 1, - } }; @@ -983,8 +1011,6 @@ static int su3000_identify_state(struct usb_device *udev, const struct dvb_usb_device_description **desc, int *cold) { - info("%s", __func__); - *cold = 0; return 0; } @@ -1003,6 +1029,7 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, }; struct dvb_usb_adapter *udev_adap = fe->dvb->priv; + if (voltage == SEC_VOLTAGE_18) msg.buf = command_18v; else if (voltage == SEC_VOLTAGE_13) @@ -1206,11 +1233,11 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) if (demod_probe & 4) { d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, - &d->dev->i2c_adap, 0); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap, 0); + if (d->fe_adap[0].fe) { if (dvb_attach(stb6100_attach, d->fe_adap[0].fe, - &dw2104a_stb6100_config, - &d->dev->i2c_adap)) { + &dw2104a_stb6100_config, + &d->dev->i2c_adap)) { tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops; tuner_ops->set_frequency = stb6100_set_freq; tuner_ops->get_frequency = stb6100_get_freq; @@ -1225,11 +1252,11 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) if (demod_probe & 2) { d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, - &d->dev->i2c_adap, 0); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap, 0); + if (d->fe_adap[0].fe) { if (dvb_attach(stv6110_attach, d->fe_adap[0].fe, - &dw2104_stv6110_config, - &d->dev->i2c_adap)) { + &dw2104_stv6110_config, + &d->dev->i2c_adap)) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached STV0900+STV6110A!"); return 0; @@ -1239,8 +1266,8 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) if (demod_probe & 1) { d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached cx24116!"); return 0; @@ -1248,10 +1275,10 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) } d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { dvb_attach(ts2020_attach, d->fe_adap[0].fe, - &dw2104_ts2020_config, &d->dev->i2c_adap); + &dw2104_ts2020_config, &d->dev->i2c_adap); d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached DS3000!"); return 0; @@ -1269,8 +1296,8 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) { /*dw2102_properties.adapter->tuner_attach = NULL;*/ d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached si21xx!"); return 0; @@ -1279,10 +1306,10 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, - &d->dev->i2c_adap)) { + &d->dev->i2c_adap)) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached stv0288!"); return 0; @@ -1293,8 +1320,8 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached stv0299!"); return 0; @@ -1306,8 +1333,8 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) static int dw3101_frontend_attach(struct dvb_usb_adapter *d) { d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, - &d->dev->i2c_adap, 0x48); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap, 0x48); + if (d->fe_adap[0].fe) { info("Attached tda10023!"); return 0; } @@ -1317,10 +1344,10 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) static int zl100313_frontend_attach(struct dvb_usb_adapter *d) { d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config, - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { + &d->dev->i2c_adap); + if (d->fe_adap[0].fe) { if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60, - &d->dev->i2c_adap)) { + &d->dev->i2c_adap)) { d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached zl100313+zl10039!"); return 0; @@ -1335,12 +1362,12 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) u8 obuf[] = {7, 1}; d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, - &d->dev->i2c_adap); + &d->dev->i2c_adap); - if (d->fe_adap[0].fe == NULL) + if (!d->fe_adap[0].fe) return -EIO; - if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap)) + if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap) == NULL) return -EIO; d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; @@ -1350,7 +1377,6 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) info("Attached stv0288+stb6000!"); return 0; - } static int ds3000_frontend_attach(struct dvb_usb_adapter *d) @@ -1359,13 +1385,13 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) u8 obuf[] = {7, 1}; d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config, - &d->dev->i2c_adap); + &d->dev->i2c_adap); - if (d->fe_adap[0].fe == NULL) + if (!d->fe_adap[0].fe) return -EIO; dvb_attach(ts2020_attach, d->fe_adap[0].fe, &s660_ts2020_config, - &d->dev->i2c_adap); + &d->dev->i2c_adap); st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage; @@ -1382,8 +1408,8 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) u8 obuf[] = {7, 1}; d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, - &d->dev->i2c_adap, 0); - if (d->fe_adap[0].fe == NULL) + &d->dev->i2c_adap, 0); + if (!d->fe_adap[0].fe) return -EIO; d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; @@ -1439,12 +1465,12 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *adap) mutex_unlock(&d->data_mutex); adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, - &d->i2c_adap); - if (adap->fe_adap[0].fe == NULL) + &d->i2c_adap); + if (!adap->fe_adap[0].fe) return -EIO; if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, - &dw2104_ts2020_config, + &dw2104_ts2020_config, &d->i2c_adap)) { info("Attached DS3000/TS2020!"); return 0; @@ -1499,10 +1525,10 @@ static int t220_frontend_attach(struct dvb_usb_adapter *adap) mutex_unlock(&d->data_mutex); adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, - &d->i2c_adap, NULL); - if (adap->fe_adap[0].fe != NULL) { + &d->i2c_adap, NULL); + if (adap->fe_adap[0].fe) { if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60, - &d->i2c_adap, &tda18271_config)) { + &d->i2c_adap, &tda18271_config)) { info("Attached TDA18271HD/CXD2820R!"); return 0; } @@ -1527,14 +1553,14 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap) mutex_unlock(&d->data_mutex); adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach, - &s421_m88rs2000_config, - &d->i2c_adap); + &s421_m88rs2000_config, + &d->i2c_adap); - if (adap->fe_adap[0].fe == NULL) + if (!adap->fe_adap[0].fe) return -EIO; if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, - &dw2104_ts2020_config, + &dw2104_ts2020_config, &d->i2c_adap)) { info("Attached RS2000/TS2020!"); return 0; @@ -1701,14 +1727,14 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) { dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, - &adap->dev->i2c_adap, DVB_PLL_OPERA1); + &adap->dev->i2c_adap, DVB_PLL_OPERA1); return 0; } static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) { dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, - &adap->dev->i2c_adap, DVB_PLL_TUA6034); + &adap->dev->i2c_adap, DVB_PLL_TUA6034); return 0; } @@ -1726,7 +1752,7 @@ static int dw2102_rc_query(struct dvb_usb_device *d) if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", - __func__, key[0], key[1]); + __func__, key[0], key[1]); rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0], 0); } } @@ -1747,7 +1773,7 @@ static int prof_rc_query(struct dvb_usb_device *d) if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", - __func__, key[0], key[1]); + __func__, key[0], key[1]); rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, key[0] ^ 0xff, 0); } @@ -1769,7 +1795,7 @@ static int su3000_rc_query(struct dvb_usb_device *d) if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { if (msg.buf[0] != 0xff) { deb_rc("%s: rc code: %x, %x\n", - __func__, key[0], key[1]); + __func__, key[0], key[1]); rc_keydown(d->rc_dev, RC_PROTO_RC5, RC_SCANCODE_RC5(key[1], key[0]), 0); } @@ -1807,7 +1833,6 @@ enum dw2102_table_entry { TECHNOTREND_CONNECT_S2_4600, TEVII_S482_1, TEVII_S482_2, - TERRATEC_CINERGY_S2_BOX, TEVII_S662 }; @@ -1840,7 +1865,6 @@ static struct usb_device_id dw2102_table[] = { DVB_USB_DEV(TECHNOTREND, TECHNOTREND_CONNECT_S2_4600), DVB_USB_DEV(TEVII, TEVII_S482_1), DVB_USB_DEV(TEVII, TEVII_S482_2), - DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_S2_BOX), DVB_USB_DEV(TEVII, TEVII_S662), { } }; @@ -1848,7 +1872,7 @@ static struct usb_device_id dw2102_table[] = { MODULE_DEVICE_TABLE(usb, dw2102_table); static int dw2102_load_firmware(struct usb_device *dev, - const struct firmware *frmwr) + const struct firmware *frmwr) { u8 *b, *p; int ret = 0, i; @@ -1875,12 +1899,12 @@ static int dw2102_load_firmware(struct usb_device *dev, dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG); dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG); - if (p != NULL) { + if (p) { memcpy(p, fw->data, fw->size); for (i = 0; i < fw->size; i += 0x40) { - b = (u8 *) p + i; - if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40, - DW210X_WRITE_MSG) != 0x40) { + b = (u8 *)p + i; + if (dw210x_op_rw(dev, 0xa0, i, 0, b, 0x40, + DW210X_WRITE_MSG) != 0x40) { err("error while transferring firmware"); ret = -EINVAL; break; @@ -1906,50 +1930,49 @@ static int dw2102_load_firmware(struct usb_device *dev, case USB_PID_CYPRESS_DW2104: reset = 1; dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, - DW210X_WRITE_MSG); + DW210X_WRITE_MSG); fallthrough; case USB_PID_CYPRESS_DW3101: reset = 0; dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); + DW210X_WRITE_MSG); break; case USB_PID_TERRATEC_CINERGY_S: case USB_PID_CYPRESS_DW2102: dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); + DW210X_WRITE_MSG); dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); + DW210X_READ_MSG); /* check STV0299 frontend */ dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, - DW210X_READ_MSG); + DW210X_READ_MSG); if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) { dw2102_properties.i2c_algo = &dw2102_i2c_algo; dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach; break; - } else { - /* check STV0288 frontend */ - reset16[0] = 0xd0; - reset16[1] = 1; - reset16[2] = 0; - dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, - DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, - DW210X_READ_MSG); - if (reset16[2] == 0x11) { - dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; - break; - } + } + /* check STV0288 frontend */ + reset16[0] = 0xd0; + reset16[1] = 1; + reset16[2] = 0; + dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, + DW210X_WRITE_MSG); + dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, + DW210X_READ_MSG); + if (reset16[2] == 0x11) { + dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; + break; } fallthrough; case 0x2101: dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, - DW210X_READ_MSG); + DW210X_READ_MSG); dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); + DW210X_READ_MSG); dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); + DW210X_READ_MSG); dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); + DW210X_READ_MSG); break; } @@ -2551,7 +2574,7 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { { NULL }, }, { "Terratec Cinergy S2 USB BOX", - { &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL }, + { &dw2102_table[TERRATEC_CINERGY_S2_R4], NULL }, { NULL }, }, { "TeVii S662", @@ -2562,18 +2585,18 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { }; static int dw2102_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { if (!(dvb_usb_device_init(intf, &dw2102_properties, - THIS_MODULE, NULL, adapter_nr) && + THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &dw2104_properties, THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &dw3101_properties, - THIS_MODULE, NULL, adapter_nr) && + THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &s6x0_properties, - THIS_MODULE, NULL, adapter_nr) && + THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &p1100_properties, - THIS_MODULE, NULL, adapter_nr) && + THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &s660_properties, THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &p7500_properties, @@ -2586,7 +2609,6 @@ static int dw2102_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) && dvb_usb_device_init(intf, &tt_s2_4600_properties, THIS_MODULE, NULL, adapter_nr))) { - return 0; } diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 723510520d092b..2c8179a84991e7 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -40,7 +40,7 @@ struct smsusb_urb_t { struct smscore_buffer_t *cb; struct smsusb_device_t *dev; - struct urb urb; + struct urb *urb; /* For the bottom half */ struct work_struct wq; @@ -160,7 +160,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, } usb_fill_bulk_urb( - &surb->urb, + surb->urb, dev->udev, usb_rcvbulkpipe(dev->udev, dev->in_ep), surb->cb->p, @@ -168,9 +168,9 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, smsusb_onresponse, surb ); - surb->urb.transfer_flags |= URB_FREE_BUFFER; + surb->urb->transfer_flags |= URB_FREE_BUFFER; - return usb_submit_urb(&surb->urb, GFP_ATOMIC); + return usb_submit_urb(surb->urb, GFP_ATOMIC); } static void smsusb_stop_streaming(struct smsusb_device_t *dev) @@ -178,7 +178,7 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev) int i; for (i = 0; i < MAX_URBS; i++) { - usb_kill_urb(&dev->surbs[i].urb); + usb_kill_urb(dev->surbs[i].urb); if (dev->surbs[i].wq.func) cancel_work_sync(&dev->surbs[i].wq); @@ -338,6 +338,8 @@ static void smsusb_term_device(struct usb_interface *intf) struct smsusb_device_t *dev = usb_get_intfdata(intf); if (dev) { + int i; + dev->state = SMSUSB_DISCONNECTED; smsusb_stop_streaming(dev); @@ -346,6 +348,9 @@ static void smsusb_term_device(struct usb_interface *intf) if (dev->coredev) smscore_unregister_device(dev->coredev); + for (i = 0; i < MAX_URBS; i++) + usb_free_urb(dev->surbs[i].urb); + pr_debug("device 0x%p destroyed\n", dev); kfree(dev); } @@ -463,7 +468,9 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) /* initialize urbs */ for (i = 0; i < MAX_URBS; i++) { dev->surbs[i].dev = dev; - usb_init_urb(&dev->surbs[i].urb); + dev->surbs[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->surbs[i].urb) + goto err_unregister_device; } pr_debug("smsusb_start_streaming(...).\n"); @@ -486,6 +493,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) return rc; err_unregister_device: + /* smsusb_term_device() frees any allocated urb. */ smsusb_term_device(intf); #ifdef CONFIG_MEDIA_CONTROLLER_DVB media_device_unregister(mdev); diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index 366f0e4a5dc0d8..e79c45db60ab56 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c @@ -99,7 +99,7 @@ void stk1160_buffer_done(struct stk1160 *dev) static inline void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) { - int linesdone, lineoff, lencopy; + int linesdone, lineoff, lencopy, offset; int bytesperline = dev->width * 2; struct stk1160_buffer *buf = dev->isoc_ctl.buf; u8 *dst = buf->mem; @@ -139,8 +139,13 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "out of bounds offset\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } @@ -182,8 +187,13 @@ void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "offset out of bounds\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index bbd90123a4e76d..8fe24c98087e63 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/usb.h> +#include <linux/usb/quirks.h> #include <linux/usb/uvc.h> #include <linux/videodev2.h> #include <linux/vmalloc.h> @@ -2232,8 +2233,14 @@ static int uvc_probe(struct usb_interface *intf, goto error; } + if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME) + udev->quirks &= ~USB_QUIRK_RESET_RESUME; + + if (!(dev->quirks & UVC_QUIRK_DISABLE_AUTOSUSPEND)) + usb_enable_autosuspend(udev); + uvc_dbg(dev, PROBE, "UVC device initialized\n"); - usb_enable_autosuspend(udev); + return 0; error: @@ -2574,6 +2581,33 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) }, + /* Logitech Rally Bar Huddle */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x087c, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) }, + /* Logitech Rally Bar */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x089b, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) }, + /* Logitech Rally Bar Mini */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x08d3, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) }, /* Chicony CNF7129 (Asus EEE 100HE) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -3012,6 +3046,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = UVC_PC_PROTOCOL_15, .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, + /* Insta360 Link */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x2e1a, + .idProduct = 0x4c01, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) }, /* Lenovo Integrated Camera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -3030,6 +3073,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, + /* Shine-Optics Integrated Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x3277, + .idProduct = 0x009e, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, /* Acer EasyCamera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 6fb0a78b1b0097..3653b2c8a86cbe 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -73,6 +73,8 @@ #define UVC_QUIRK_FORCE_Y8 0x00000800 #define UVC_QUIRK_FORCE_BPP 0x00001000 #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 +#define UVC_QUIRK_NO_RESET_RESUME 0x00004000 +#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 4bb073587817c9..3a22da443a223b 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -341,7 +341,7 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, int ret; if (list_empty(&sd->asc_list)) { - ret = v4l2_device_register_subdev(v4l2_dev, sd); + ret = __v4l2_device_register_subdev(v4l2_dev, sd, sd->owner); if (ret < 0) return ret; registered = true; @@ -783,7 +783,7 @@ v4l2_async_connection_unique(struct v4l2_subdev *sd) } EXPORT_SYMBOL_GPL(v4l2_async_connection_unique); -int v4l2_async_register_subdev(struct v4l2_subdev *sd) +int __v4l2_async_register_subdev(struct v4l2_subdev *sd, struct module *module) { struct v4l2_async_notifier *subdev_notifier; struct v4l2_async_notifier *notifier; @@ -807,6 +807,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) return -EINVAL; } + sd->owner = module; + mutex_lock(&list_lock); list_for_each_entry(notifier, ¬ifier_list, notifier_entry) { @@ -849,9 +851,11 @@ err_unbind: mutex_unlock(&list_lock); + sd->owner = NULL; + return ret; } -EXPORT_SYMBOL(v4l2_async_register_subdev); +EXPORT_SYMBOL(__v4l2_async_register_subdev); void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) { diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index d9a422017bd9d0..e5a364efd5e668 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -1052,35 +1052,40 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr if (id >= node2id(hdl->ctrl_refs.prev)) { ref = NULL; /* Yes, so there is no next control */ } else if (ref) { + struct v4l2_ctrl_ref *pos = ref; + /* * We found a control with the given ID, so just get * the next valid one in the list. */ - list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) { - is_compound = ref->ctrl->is_array || - ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; - if (id < ref->ctrl->id && - (is_compound & mask) == match) + ref = NULL; + list_for_each_entry_continue(pos, &hdl->ctrl_refs, node) { + is_compound = pos->ctrl->is_array || + pos->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; + if (id < pos->ctrl->id && + (is_compound & mask) == match) { + ref = pos; break; + } } - if (&ref->node == &hdl->ctrl_refs) - ref = NULL; } else { + struct v4l2_ctrl_ref *pos; + /* * No control with the given ID exists, so start * searching for the next largest ID. We know there * is one, otherwise the first 'if' above would have * been true. */ - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - is_compound = ref->ctrl->is_array || - ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; - if (id < ref->ctrl->id && - (is_compound & mask) == match) + list_for_each_entry(pos, &hdl->ctrl_refs, node) { + is_compound = pos->ctrl->is_array || + pos->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; + if (id < pos->ctrl->id && + (is_compound & mask) == match) { + ref = pos; break; + } } - if (&ref->node == &hdl->ctrl_refs) - ref = NULL; } } mutex_unlock(hdl->lock); diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index 9a09a981e1d961..c59dd691f79f62 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -2567,6 +2567,9 @@ int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ctrl_ops, const struct v4l2_fwnode_device_properties *p) { + if (hdl->error) + return hdl->error; + if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { u32 orientation_ctrl; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index e39e9742fdb5a2..be2ba7ca5de205 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -1039,8 +1039,10 @@ int __video_register_device(struct video_device *vdev, vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); vdev->dev.parent = vdev->dev_parent; dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); + mutex_lock(&videodev_lock); ret = device_register(&vdev->dev); if (ret < 0) { + mutex_unlock(&videodev_lock); pr_err("%s: device_register failed\n", __func__); goto cleanup; } @@ -1060,6 +1062,7 @@ int __video_register_device(struct video_device *vdev, /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags); + mutex_unlock(&videodev_lock); return 0; diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index d2e58ae91f9b44..5e537454f5cd71 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -108,8 +108,8 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) } EXPORT_SYMBOL_GPL(v4l2_device_unregister); -int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, - struct v4l2_subdev *sd) +int __v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd, struct module *module) { int err; @@ -125,9 +125,9 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, * try_module_get() such sub-device owners. */ sd->owner_v4l2_dev = v4l2_dev->dev && v4l2_dev->dev->driver && - sd->owner == v4l2_dev->dev->driver->owner; + module == v4l2_dev->dev->driver->owner; - if (!sd->owner_v4l2_dev && !try_module_get(sd->owner)) + if (!sd->owner_v4l2_dev && !try_module_get(module)) return -ENODEV; sd->v4l2_dev = v4l2_dev; @@ -152,6 +152,8 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, goto error_unregister; } + sd->owner = module; + spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -168,7 +170,7 @@ error_module: sd->v4l2_dev = NULL; return err; } -EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); +EXPORT_SYMBOL_GPL(__v4l2_device_register_subdev); static void v4l2_subdev_release(struct v4l2_subdev *sd) { diff --git a/drivers/media/v4l2-core/v4l2-i2c.c b/drivers/media/v4l2-core/v4l2-i2c.c index b4acca75644beb..586c46544255d6 100644 --- a/drivers/media/v4l2-core/v4l2-i2c.c +++ b/drivers/media/v4l2-core/v4l2-i2c.c @@ -100,7 +100,7 @@ struct v4l2_subdev * Register with the v4l2_device which increases the module's * use count as well. */ - if (v4l2_device_register_subdev(v4l2_dev, sd)) + if (__v4l2_device_register_subdev(v4l2_dev, sd, sd->owner)) sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(client->dev.driver->owner); diff --git a/drivers/media/v4l2-core/v4l2-spi.c b/drivers/media/v4l2-core/v4l2-spi.c index a7092c3930d627..1baf8e63f19e04 100644 --- a/drivers/media/v4l2-core/v4l2-spi.c +++ b/drivers/media/v4l2-core/v4l2-spi.c @@ -59,7 +59,7 @@ struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, * Register with the v4l2_device which increases the module's * use count as well. */ - if (v4l2_device_register_subdev(v4l2_dev, sd)) + if (__v4l2_device_register_subdev(v4l2_dev, sd, sd->owner)) sd = NULL; /* Decrease the module use count to match the first try_module_get. */ diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 0f590c9dc6caa0..2d67ec54569aad 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -442,15 +442,6 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable) if (WARN_ON(!!sd->enabled_streams == !!enable)) return 0; -#if IS_REACHABLE(CONFIG_LEDS_CLASS) - if (!IS_ERR_OR_NULL(sd->privacy_led)) { - if (enable) - led_set_brightness(sd->privacy_led, - sd->privacy_led->max_brightness); - else - led_set_brightness(sd->privacy_led, 0); - } -#endif ret = sd->ops->video->s_stream(sd, enable); if (!enable && ret < 0) { @@ -458,9 +449,20 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable) ret = 0; } - if (!ret) + if (!ret) { sd->enabled_streams = enable ? BIT(0) : 0; +#if IS_REACHABLE(CONFIG_LEDS_CLASS) + if (!IS_ERR_OR_NULL(sd->privacy_led)) { + if (enable) + led_set_brightness(sd->privacy_led, + sd->privacy_led->max_brightness); + else + led_set_brightness(sd->privacy_led, 0); + } +#endif + } + return ret; } diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile index fcd3e51ae9ce92..43116c74781d08 100644 --- a/drivers/staging/media/atomisp/Makefile +++ b/drivers/staging/media/atomisp/Makefile @@ -21,7 +21,6 @@ atomisp-objs += \ pci/atomisp_fops.o \ pci/atomisp_ioctl.o \ pci/atomisp_subdev.o \ - pci/atomisp_tpg.o \ pci/atomisp_v4l2.o \ pci/sh_css_firmware.o \ pci/sh_css_host_data.o \ diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig index f62d183b787f59..8710c483015c69 100644 --- a/drivers/staging/media/atomisp/i2c/Kconfig +++ b/drivers/staging/media/atomisp/i2c/Kconfig @@ -56,18 +56,3 @@ config VIDEO_ATOMISP_GC0310 help This is a Video4Linux2 sensor-level driver for the Galaxycore GC0310 0.3MP sensor. - -# -# Kconfig for flash drivers -# - -config VIDEO_ATOMISP_LM3554 - tristate "LM3554 flash light driver" - depends on ACPI - depends on VIDEO_DEV && I2C - help - This is a Video4Linux2 sub-dev driver for the LM3554 - flash light driver. - - To compile this driver as a module, choose M here: the - module will be called lm3554 diff --git a/drivers/staging/media/atomisp/i2c/Makefile b/drivers/staging/media/atomisp/i2c/Makefile index e946cc91e5ff29..3073cfa75ecfa9 100644 --- a/drivers/staging/media/atomisp/i2c/Makefile +++ b/drivers/staging/media/atomisp/i2c/Makefile @@ -9,8 +9,3 @@ obj-$(CONFIG_VIDEO_ATOMISP_OV2722) += atomisp-ov2722.o obj-$(CONFIG_VIDEO_ATOMISP_GC0310) += atomisp-gc0310.o obj-$(CONFIG_VIDEO_ATOMISP_MSRLIST_HELPER) += atomisp-libmsrlisthelper.o - -# Makefile for flash drivers -# - -obj-$(CONFIG_VIDEO_ATOMISP_LM3554) += atomisp-lm3554.o diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index bec4c561586409..994b8bceb4f5fe 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -852,7 +852,7 @@ static int gc2235_probe(struct i2c_client *client) if (ret) gc2235_remove(client); - return atomisp_register_i2c_module(&dev->sd, gcpdev, RAW_CAMERA); + return atomisp_register_i2c_module(&dev->sd, gcpdev); out_free: v4l2_device_unregister_subdev(&dev->sd); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c deleted file mode 100644 index cf5d9317b11aba..00000000000000 --- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +++ /dev/null @@ -1,955 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * LED flash driver for LM3554 - * - * Copyright (c) 2010-2012 Intel Corporation. All Rights Reserved. - * - * 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 <linux/module.h> -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <linux/delay.h> -#include <linux/gpio/consumer.h> -#include <linux/slab.h> - -#include "../include/media/lm3554.h" -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include <linux/acpi.h> -#include "../include/linux/atomisp_gmin_platform.h" -#include "../include/linux/atomisp.h" - -/* Registers */ - -#define LM3554_TORCH_BRIGHTNESS_REG 0xA0 -#define LM3554_TORCH_MODE_SHIFT 0 -#define LM3554_TORCH_CURRENT_SHIFT 3 -#define LM3554_INDICATOR_CURRENT_SHIFT 6 - -#define LM3554_FLASH_BRIGHTNESS_REG 0xB0 -#define LM3554_FLASH_MODE_SHIFT 0 -#define LM3554_FLASH_CURRENT_SHIFT 3 -#define LM3554_STROBE_SENSITIVITY_SHIFT 7 - -#define LM3554_FLASH_DURATION_REG 0xC0 -#define LM3554_FLASH_TIMEOUT_SHIFT 0 -#define LM3554_CURRENT_LIMIT_SHIFT 5 - -#define LM3554_FLAGS_REG 0xD0 -#define LM3554_FLAG_TIMEOUT BIT(0) -#define LM3554_FLAG_THERMAL_SHUTDOWN BIT(1) -#define LM3554_FLAG_LED_FAULT BIT(2) -#define LM3554_FLAG_TX1_INTERRUPT BIT(3) -#define LM3554_FLAG_TX2_INTERRUPT BIT(4) -#define LM3554_FLAG_LED_THERMAL_FAULT BIT(5) -#define LM3554_FLAG_UNUSED BIT(6) -#define LM3554_FLAG_INPUT_VOLTAGE_LOW BIT(7) - -#define LM3554_CONFIG_REG_1 0xE0 -#define LM3554_ENVM_TX2_SHIFT 5 -#define LM3554_TX2_POLARITY_SHIFT 6 - -struct lm3554 { - struct v4l2_subdev sd; - - struct mutex power_lock; - struct v4l2_ctrl_handler ctrl_handler; - int power_count; - - unsigned int mode; - int timeout; - u8 torch_current; - u8 indicator_current; - u8 flash_current; - - struct timer_list flash_off_delay; - struct lm3554_platform_data *pdata; -}; - -#define to_lm3554(p_sd) container_of(p_sd, struct lm3554, sd) - -/* Return negative errno else zero on success */ -static int lm3554_write(struct lm3554 *flash, u8 addr, u8 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&flash->sd); - int ret; - - ret = i2c_smbus_write_byte_data(client, addr, val); - - dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val, - ret < 0 ? "fail" : "ok"); - - return ret; -} - -/* Return negative errno else a data byte received from the device. */ -static int lm3554_read(struct lm3554 *flash, u8 addr) -{ - struct i2c_client *client = v4l2_get_subdevdata(&flash->sd); - int ret; - - ret = i2c_smbus_read_byte_data(client, addr); - - dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, ret, - ret < 0 ? "fail" : "ok"); - - return ret; -} - -/* ----------------------------------------------------------------------------- - * Hardware configuration - */ - -static int lm3554_set_mode(struct lm3554 *flash, unsigned int mode) -{ - u8 val; - int ret; - - val = (mode << LM3554_FLASH_MODE_SHIFT) | - (flash->flash_current << LM3554_FLASH_CURRENT_SHIFT); - - ret = lm3554_write(flash, LM3554_FLASH_BRIGHTNESS_REG, val); - if (ret == 0) - flash->mode = mode; - return ret; -} - -static int lm3554_set_torch(struct lm3554 *flash) -{ - u8 val; - - val = (flash->mode << LM3554_TORCH_MODE_SHIFT) | - (flash->torch_current << LM3554_TORCH_CURRENT_SHIFT) | - (flash->indicator_current << LM3554_INDICATOR_CURRENT_SHIFT); - - return lm3554_write(flash, LM3554_TORCH_BRIGHTNESS_REG, val); -} - -static int lm3554_set_flash(struct lm3554 *flash) -{ - u8 val; - - val = (flash->mode << LM3554_FLASH_MODE_SHIFT) | - (flash->flash_current << LM3554_FLASH_CURRENT_SHIFT); - - return lm3554_write(flash, LM3554_FLASH_BRIGHTNESS_REG, val); -} - -static int lm3554_set_duration(struct lm3554 *flash) -{ - u8 val; - - val = (flash->timeout << LM3554_FLASH_TIMEOUT_SHIFT) | - (flash->pdata->current_limit << LM3554_CURRENT_LIMIT_SHIFT); - - return lm3554_write(flash, LM3554_FLASH_DURATION_REG, val); -} - -static int lm3554_set_config1(struct lm3554 *flash) -{ - u8 val; - - val = (flash->pdata->envm_tx2 << LM3554_ENVM_TX2_SHIFT) | - (flash->pdata->tx2_polarity << LM3554_TX2_POLARITY_SHIFT); - return lm3554_write(flash, LM3554_CONFIG_REG_1, val); -} - -/* ----------------------------------------------------------------------------- - * Hardware trigger - */ -static void lm3554_flash_off_delay(struct timer_list *t) -{ - struct lm3554 *flash = from_timer(flash, t, flash_off_delay); - struct lm3554_platform_data *pdata = flash->pdata; - - gpiod_set_value(pdata->gpio_strobe, 0); -} - -static int lm3554_hw_strobe(struct i2c_client *client, bool strobe) -{ - int ret, timer_pending; - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(sd); - struct lm3554_platform_data *pdata = flash->pdata; - - /* - * An abnormal high flash current is observed when strobe off the - * flash. Workaround here is firstly set flash current to lower level, - * wait a short moment, and then strobe off the flash. - */ - - timer_pending = del_timer_sync(&flash->flash_off_delay); - - /* Flash off */ - if (!strobe) { - /* set current to 70mA and wait a while */ - ret = lm3554_write(flash, LM3554_FLASH_BRIGHTNESS_REG, 0); - if (ret < 0) - goto err; - mod_timer(&flash->flash_off_delay, - jiffies + msecs_to_jiffies(LM3554_TIMER_DELAY)); - return 0; - } - - /* Flash on */ - - /* - * If timer is killed before run, flash is not strobe off, - * so must strobe off here - */ - if (timer_pending) - gpiod_set_value(pdata->gpio_strobe, 0); - - /* Restore flash current settings */ - ret = lm3554_set_flash(flash); - if (ret < 0) - goto err; - - /* Strobe on Flash */ - gpiod_set_value(pdata->gpio_strobe, 1); - - return 0; -err: - dev_err(&client->dev, "failed to %s flash strobe (%d)\n", - strobe ? "on" : "off", ret); - return ret; -} - -/* ----------------------------------------------------------------------------- - * V4L2 controls - */ - -static int lm3554_read_status(struct lm3554 *flash) -{ - int ret; - struct i2c_client *client = v4l2_get_subdevdata(&flash->sd); - - /* NOTE: reading register clear fault status */ - ret = lm3554_read(flash, LM3554_FLAGS_REG); - if (ret < 0) - return ret; - - /* - * Accordingly to datasheet we read back '1' in bit 6. - * Clear it first. - */ - ret &= ~LM3554_FLAG_UNUSED; - - /* - * Do not take TX1/TX2 signal as an error - * because MSIC will not turn off flash, but turn to - * torch mode according to gsm modem signal by hardware. - */ - ret &= ~(LM3554_FLAG_TX1_INTERRUPT | LM3554_FLAG_TX2_INTERRUPT); - - if (ret > 0) - dev_dbg(&client->dev, "LM3554 flag status: %02x\n", ret); - - return ret; -} - -static int lm3554_s_flash_timeout(struct v4l2_subdev *sd, u32 val) -{ - struct lm3554 *flash = to_lm3554(sd); - - val = clamp(val, LM3554_MIN_TIMEOUT, LM3554_MAX_TIMEOUT); - val = val / LM3554_TIMEOUT_STEPSIZE - 1; - - flash->timeout = val; - - return lm3554_set_duration(flash); -} - -static int lm3554_g_flash_timeout(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - - *val = (u32)(flash->timeout + 1) * LM3554_TIMEOUT_STEPSIZE; - - return 0; -} - -static int lm3554_s_flash_intensity(struct v4l2_subdev *sd, u32 intensity) -{ - struct lm3554 *flash = to_lm3554(sd); - - intensity = LM3554_CLAMP_PERCENTAGE(intensity); - intensity = LM3554_PERCENT_TO_VALUE(intensity, LM3554_FLASH_STEP); - - flash->flash_current = intensity; - - return lm3554_set_flash(flash); -} - -static int lm3554_g_flash_intensity(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - - *val = LM3554_VALUE_TO_PERCENT((u32)flash->flash_current, - LM3554_FLASH_STEP); - - return 0; -} - -static int lm3554_s_torch_intensity(struct v4l2_subdev *sd, u32 intensity) -{ - struct lm3554 *flash = to_lm3554(sd); - - intensity = LM3554_CLAMP_PERCENTAGE(intensity); - intensity = LM3554_PERCENT_TO_VALUE(intensity, LM3554_TORCH_STEP); - - flash->torch_current = intensity; - - return lm3554_set_torch(flash); -} - -static int lm3554_g_torch_intensity(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - - *val = LM3554_VALUE_TO_PERCENT((u32)flash->torch_current, - LM3554_TORCH_STEP); - - return 0; -} - -static int lm3554_s_indicator_intensity(struct v4l2_subdev *sd, u32 intensity) -{ - struct lm3554 *flash = to_lm3554(sd); - - intensity = LM3554_CLAMP_PERCENTAGE(intensity); - intensity = LM3554_PERCENT_TO_VALUE(intensity, LM3554_INDICATOR_STEP); - - flash->indicator_current = intensity; - - return lm3554_set_torch(flash); -} - -static int lm3554_g_indicator_intensity(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - - *val = LM3554_VALUE_TO_PERCENT((u32)flash->indicator_current, - LM3554_INDICATOR_STEP); - - return 0; -} - -static int lm3554_s_flash_strobe(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return lm3554_hw_strobe(client, val); -} - -static int lm3554_s_flash_mode(struct v4l2_subdev *sd, u32 new_mode) -{ - struct lm3554 *flash = to_lm3554(sd); - unsigned int mode; - - switch (new_mode) { - case ATOMISP_FLASH_MODE_OFF: - mode = LM3554_MODE_SHUTDOWN; - break; - case ATOMISP_FLASH_MODE_FLASH: - mode = LM3554_MODE_FLASH; - break; - case ATOMISP_FLASH_MODE_INDICATOR: - mode = LM3554_MODE_INDICATOR; - break; - case ATOMISP_FLASH_MODE_TORCH: - mode = LM3554_MODE_TORCH; - break; - default: - return -EINVAL; - } - - return lm3554_set_mode(flash, mode); -} - -static int lm3554_g_flash_mode(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - *val = flash->mode; - return 0; -} - -static int lm3554_g_flash_status(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - int value; - - value = lm3554_read_status(flash); - if (value < 0) - return value; - - if (value & LM3554_FLAG_TIMEOUT) - *val = ATOMISP_FLASH_STATUS_TIMEOUT; - else if (value > 0) - *val = ATOMISP_FLASH_STATUS_HW_ERROR; - else - *val = ATOMISP_FLASH_STATUS_OK; - - return 0; -} - -static int lm3554_g_flash_status_register(struct v4l2_subdev *sd, s32 *val) -{ - struct lm3554 *flash = to_lm3554(sd); - int ret; - - ret = lm3554_read(flash, LM3554_FLAGS_REG); - - if (ret < 0) - return ret; - - *val = ret; - return 0; -} - -static int lm3554_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct lm3554 *dev = - container_of(ctrl->handler, struct lm3554, ctrl_handler); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_FLASH_TIMEOUT: - ret = lm3554_s_flash_timeout(&dev->sd, ctrl->val); - break; - case V4L2_CID_FLASH_INTENSITY: - ret = lm3554_s_flash_intensity(&dev->sd, ctrl->val); - break; - case V4L2_CID_FLASH_TORCH_INTENSITY: - ret = lm3554_s_torch_intensity(&dev->sd, ctrl->val); - break; - case V4L2_CID_FLASH_INDICATOR_INTENSITY: - ret = lm3554_s_indicator_intensity(&dev->sd, ctrl->val); - break; - case V4L2_CID_FLASH_STROBE: - ret = lm3554_s_flash_strobe(&dev->sd, ctrl->val); - break; - case V4L2_CID_FLASH_MODE: - ret = lm3554_s_flash_mode(&dev->sd, ctrl->val); - break; - default: - ret = -EINVAL; - } - return ret; -} - -static int lm3554_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct lm3554 *dev = - container_of(ctrl->handler, struct lm3554, ctrl_handler); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_FLASH_TIMEOUT: - ret = lm3554_g_flash_timeout(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_INTENSITY: - ret = lm3554_g_flash_intensity(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_TORCH_INTENSITY: - ret = lm3554_g_torch_intensity(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_INDICATOR_INTENSITY: - ret = lm3554_g_indicator_intensity(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_MODE: - ret = lm3554_g_flash_mode(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_STATUS: - ret = lm3554_g_flash_status(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FLASH_STATUS_REGISTER: - ret = lm3554_g_flash_status_register(&dev->sd, &ctrl->val); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static const struct v4l2_ctrl_ops ctrl_ops = { - .s_ctrl = lm3554_s_ctrl, - .g_volatile_ctrl = lm3554_g_volatile_ctrl -}; - -static const struct v4l2_ctrl_config lm3554_controls[] = { - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_TIMEOUT, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Flash Timeout", - .min = 0x0, - .max = LM3554_MAX_TIMEOUT, - .step = 0x01, - .def = LM3554_DEFAULT_TIMEOUT, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_INTENSITY, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Flash Intensity", - .min = LM3554_MIN_PERCENT, - .max = LM3554_MAX_PERCENT, - .step = 0x01, - .def = LM3554_FLASH_DEFAULT_BRIGHTNESS, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_TORCH_INTENSITY, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Torch Intensity", - .min = LM3554_MIN_PERCENT, - .max = LM3554_MAX_PERCENT, - .step = 0x01, - .def = LM3554_TORCH_DEFAULT_BRIGHTNESS, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_INDICATOR_INTENSITY, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Indicator Intensity", - .min = LM3554_MIN_PERCENT, - .max = LM3554_MAX_PERCENT, - .step = 0x01, - .def = LM3554_INDICATOR_DEFAULT_BRIGHTNESS, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_STROBE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flash Strobe", - .min = 0, - .max = 1, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_MODE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Flash Mode", - .min = 0, - .max = 100, - .step = 1, - .def = ATOMISP_FLASH_MODE_OFF, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_STATUS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Flash Status", - .min = ATOMISP_FLASH_STATUS_OK, - .max = ATOMISP_FLASH_STATUS_TIMEOUT, - .step = 1, - .def = ATOMISP_FLASH_STATUS_OK, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FLASH_STATUS_REGISTER, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Flash Status Register", - .min = 0, - .max = 255, - .step = 1, - .def = 0, - .flags = 0, - }, -}; - -/* ----------------------------------------------------------------------------- - * V4L2 subdev core operations - */ - -/* Put device into known state. */ -static int lm3554_setup(struct lm3554 *flash) -{ - struct i2c_client *client = v4l2_get_subdevdata(&flash->sd); - int ret; - - /* clear the flags register */ - ret = lm3554_read(flash, LM3554_FLAGS_REG); - if (ret < 0) - return ret; - - dev_dbg(&client->dev, "Fault info: %02x\n", ret); - - ret = lm3554_set_config1(flash); - if (ret < 0) - return ret; - - ret = lm3554_set_duration(flash); - if (ret < 0) - return ret; - - ret = lm3554_set_torch(flash); - if (ret < 0) - return ret; - - ret = lm3554_set_flash(flash); - if (ret < 0) - return ret; - - /* read status */ - ret = lm3554_read_status(flash); - if (ret < 0) - return ret; - - return ret ? -EIO : 0; -} - -static int __lm3554_s_power(struct lm3554 *flash, int power) -{ - struct lm3554_platform_data *pdata = flash->pdata; - int ret; - - /*initialize flash driver*/ - gpiod_set_value(pdata->gpio_reset, power); - usleep_range(100, 100 + 1); - - if (power) { - /* Setup default values. This makes sure that the chip - * is in a known state. - */ - ret = lm3554_setup(flash); - if (ret < 0) { - __lm3554_s_power(flash, 0); - return ret; - } - } - - return 0; -} - -static int lm3554_s_power(struct v4l2_subdev *sd, int power) -{ - struct lm3554 *flash = to_lm3554(sd); - int ret = 0; - - mutex_lock(&flash->power_lock); - - if (flash->power_count == !power) { - ret = __lm3554_s_power(flash, !!power); - if (ret < 0) - goto done; - } - - flash->power_count += power ? 1 : -1; - WARN_ON(flash->power_count < 0); - -done: - mutex_unlock(&flash->power_lock); - return ret; -} - -static const struct v4l2_subdev_core_ops lm3554_core_ops = { - .s_power = lm3554_s_power, -}; - -static const struct v4l2_subdev_ops lm3554_ops = { - .core = &lm3554_core_ops, -}; - -static int lm3554_detect(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct i2c_adapter *adapter = client->adapter; - struct lm3554 *flash = to_lm3554(sd); - int ret; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "lm3554_detect i2c error\n"); - return -ENODEV; - } - - /* Power up the flash driver and reset it */ - ret = lm3554_s_power(&flash->sd, 1); - if (ret < 0) { - dev_err(&client->dev, "Failed to power on lm3554 LED flash\n"); - } else { - dev_dbg(&client->dev, "Successfully detected lm3554 LED flash\n"); - lm3554_s_power(&flash->sd, 0); - } - - return ret; -} - -static int lm3554_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - return lm3554_s_power(sd, 1); -} - -static int lm3554_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - return lm3554_s_power(sd, 0); -} - -static const struct v4l2_subdev_internal_ops lm3554_internal_ops = { - .registered = lm3554_detect, - .open = lm3554_open, - .close = lm3554_close, -}; - -/* ----------------------------------------------------------------------------- - * I2C driver - */ -#ifdef CONFIG_PM - -static int lm3554_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *subdev = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(subdev); - int rval; - - if (flash->power_count == 0) - return 0; - - rval = __lm3554_s_power(flash, 0); - - dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok"); - - return rval; -} - -static int lm3554_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *subdev = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(subdev); - int rval; - - if (flash->power_count == 0) - return 0; - - rval = __lm3554_s_power(flash, 1); - - dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok"); - - return rval; -} - -#else - -#define lm3554_suspend NULL -#define lm3554_resume NULL - -#endif /* CONFIG_PM */ - -static int lm3554_gpio_init(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(sd); - struct lm3554_platform_data *pdata = flash->pdata; - int ret; - - if (!pdata->gpio_reset) - return -EINVAL; - - ret = gpiod_direction_output(pdata->gpio_reset, 0); - if (ret < 0) - return ret; - - if (!pdata->gpio_strobe) - return -EINVAL; - - ret = gpiod_direction_output(pdata->gpio_strobe, 0); - if (ret < 0) - return ret; - - return 0; -} - -static void lm3554_gpio_uninit(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(sd); - struct lm3554_platform_data *pdata = flash->pdata; - int ret; - - ret = gpiod_direction_output(pdata->gpio_strobe, 0); - if (ret < 0) - dev_err(&client->dev, - "gpio request/direction_output fail for gpio_strobe"); - - ret = gpiod_direction_output(pdata->gpio_reset, 0); - if (ret < 0) - dev_err(&client->dev, - "gpio request/direction_output fail for gpio_reset"); -} - -static void *lm3554_platform_data_func(struct i2c_client *client) -{ - static struct lm3554_platform_data platform_data; - - platform_data.gpio_reset = gpiod_get_index(&client->dev, - NULL, 2, GPIOD_OUT_LOW); - if (IS_ERR(platform_data.gpio_reset)) - return ERR_CAST(platform_data.gpio_reset); - platform_data.gpio_strobe = gpiod_get_index(&client->dev, - NULL, 0, GPIOD_OUT_LOW); - if (IS_ERR(platform_data.gpio_strobe)) - return ERR_CAST(platform_data.gpio_strobe); - platform_data.gpio_torch = gpiod_get_index(&client->dev, - NULL, 1, GPIOD_OUT_LOW); - if (IS_ERR(platform_data.gpio_torch)) - return ERR_CAST(platform_data.gpio_torch); - - /* Set to TX2 mode, then ENVM/TX2 pin is a power amplifier sync input: - * ENVM/TX pin asserted, flash forced into torch; - * ENVM/TX pin desserted, flash set back; - */ - platform_data.envm_tx2 = 1; - platform_data.tx2_polarity = 0; - - /* set peak current limit to be 1000mA */ - platform_data.current_limit = 0; - - return &platform_data; -} - -static int lm3554_probe(struct i2c_client *client) -{ - int err = 0; - struct lm3554 *flash; - unsigned int i; - - flash = kzalloc(sizeof(*flash), GFP_KERNEL); - if (!flash) - return -ENOMEM; - - flash->pdata = lm3554_platform_data_func(client); - if (IS_ERR(flash->pdata)) { - err = PTR_ERR(flash->pdata); - goto free_flash; - } - - v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); - flash->sd.internal_ops = &lm3554_internal_ops; - flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - flash->mode = ATOMISP_FLASH_MODE_OFF; - flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1; - err = - v4l2_ctrl_handler_init(&flash->ctrl_handler, - ARRAY_SIZE(lm3554_controls)); - if (err) { - dev_err(&client->dev, "error initialize a ctrl_handler.\n"); - goto unregister_subdev; - } - - for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++) - v4l2_ctrl_new_custom(&flash->ctrl_handler, &lm3554_controls[i], - NULL); - - if (flash->ctrl_handler.error) { - dev_err(&client->dev, "ctrl_handler error.\n"); - err = flash->ctrl_handler.error; - goto free_handler; - } - - flash->sd.ctrl_handler = &flash->ctrl_handler; - err = media_entity_pads_init(&flash->sd.entity, 0, NULL); - if (err) { - dev_err(&client->dev, "error initialize a media entity.\n"); - goto free_handler; - } - - flash->sd.entity.function = MEDIA_ENT_F_FLASH; - - mutex_init(&flash->power_lock); - - timer_setup(&flash->flash_off_delay, lm3554_flash_off_delay, 0); - - err = lm3554_gpio_init(client); - if (err) { - dev_err(&client->dev, "gpio request/direction_output fail.\n"); - goto cleanup_media; - } - - err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); - if (err) { - dev_err(&client->dev, "fail to register atomisp i2c module.\n"); - goto uninit_gpio; - } - - return 0; - -uninit_gpio: - lm3554_gpio_uninit(client); -cleanup_media: - media_entity_cleanup(&flash->sd.entity); -free_handler: - v4l2_ctrl_handler_free(&flash->ctrl_handler); -unregister_subdev: - v4l2_device_unregister_subdev(&flash->sd); -free_flash: - kfree(flash); - - return err; -} - -static void lm3554_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct lm3554 *flash = to_lm3554(sd); - - media_entity_cleanup(&flash->sd.entity); - v4l2_ctrl_handler_free(&flash->ctrl_handler); - v4l2_device_unregister_subdev(sd); - - atomisp_gmin_remove_subdev(sd); - - timer_shutdown_sync(&flash->flash_off_delay); - - lm3554_gpio_uninit(client); - - kfree(flash); -} - -static const struct dev_pm_ops lm3554_pm_ops = { - .suspend = lm3554_suspend, - .resume = lm3554_resume, -}; - -static const struct acpi_device_id lm3554_acpi_match[] = { - { "INTCF1C" }, - {}, -}; -MODULE_DEVICE_TABLE(acpi, lm3554_acpi_match); - -static struct i2c_driver lm3554_driver = { - .driver = { - .name = "lm3554", - .pm = &lm3554_pm_ops, - .acpi_match_table = lm3554_acpi_match, - }, - .probe = lm3554_probe, - .remove = lm3554_remove, -}; -module_i2c_driver(lm3554_driver); - -MODULE_AUTHOR("Jing Tao <jing.tao@intel.com>"); -MODULE_DESCRIPTION("LED flash driver for LM3554"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index 20f02d18a8de14..03ebee976d5b42 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -1552,7 +1552,7 @@ static int mt9m114_probe(struct i2c_client *client) return ret; } - ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA); + ret = atomisp_register_i2c_module(&dev->sd, pdata); if (ret) { v4l2_device_unregister_subdev(&dev->sd); kfree(dev); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 133e346ae51b08..c31a81d64950f1 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -528,9 +528,6 @@ static int power_up(struct v4l2_subdev *sd) return -ENODEV; } - if (dev->power_on == 1) - return 0; /* Already on */ - /* power control */ ret = power_ctrl(sd, 1); if (ret) @@ -555,7 +552,6 @@ static int power_up(struct v4l2_subdev *sd) /* according to DS, 20ms is needed between PWDN and i2c access */ msleep(20); - dev->power_on = 1; return 0; fail_clk: @@ -579,9 +575,6 @@ static int power_down(struct v4l2_subdev *sd) return -ENODEV; } - if (dev->power_on == 0) - return 0; /* Already off */ - ret = dev->platform_data->flisclk_ctrl(sd, 0); if (ret) dev_err(&client->dev, "flisclk failed\n"); @@ -599,7 +592,6 @@ static int power_down(struct v4l2_subdev *sd) if (ret) dev_err(&client->dev, "vprog failed.\n"); - dev->power_on = 0; return ret; } @@ -677,9 +669,6 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd, mutex_lock(&dev->input_lock); - /* s_power has not been called yet for std v4l2 clients (camorama) */ - power_up(sd); - dev->pixels_per_line = dev->res->pixels_per_line; dev->lines_per_frame = dev->res->lines_per_frame; @@ -978,7 +967,6 @@ static int ov2722_probe(struct i2c_client *client) return -ENOMEM; mutex_init(&dev->input_lock); - dev->power_on = -1; dev->res = &ov2722_res_preview[0]; v4l2_i2c_subdev_init(&dev->sd, client, &ov2722_ops); @@ -1004,7 +992,7 @@ static int ov2722_probe(struct i2c_client *client) if (ret) ov2722_remove(client); - return atomisp_register_i2c_module(&dev->sd, ovpdev, RAW_CAMERA); + return atomisp_register_i2c_module(&dev->sd, ovpdev); out_ctrl_handler_free: v4l2_ctrl_handler_free(&dev->ctrl_handler); diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h index 640d3ffcaa5c21..5920a4d45d06e4 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.h +++ b/drivers/staging/media/atomisp/i2c/ov2722.h @@ -198,7 +198,6 @@ struct ov2722_device { struct ov2722_resolution *res; struct camera_sensor_platform_data *platform_data; - int power_on; u16 pixels_per_line; u16 lines_per_frame; u8 type; diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h index b2735a008052f1..16c9da172c0317 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h @@ -614,41 +614,6 @@ enum atomisp_camera_port { ATOMISP_CAMERA_NR_PORTS }; -/* Flash modes. Default is off. - * Setting a flash to TORCH or INDICATOR mode will automatically - * turn it on. Setting it to FLASH mode will not turn on the flash - * until the FLASH_STROBE command is sent. */ -enum atomisp_flash_mode { - ATOMISP_FLASH_MODE_OFF, - ATOMISP_FLASH_MODE_FLASH, - ATOMISP_FLASH_MODE_TORCH, - ATOMISP_FLASH_MODE_INDICATOR, -}; - -/* Flash statuses, used by atomisp driver to check before starting - * flash and after having started flash. */ -enum atomisp_flash_status { - ATOMISP_FLASH_STATUS_OK, - ATOMISP_FLASH_STATUS_HW_ERROR, - ATOMISP_FLASH_STATUS_INTERRUPTED, - ATOMISP_FLASH_STATUS_TIMEOUT, -}; - -/* Frame status. This is used to detect corrupted frames and flash - * exposed frames. Usually, the first 2 frames coming out of the sensor - * are corrupted. When using flash, the frame before and the frame after - * the flash exposed frame may be partially exposed by flash. The ISP - * statistics for these frames should not be used by the 3A library. - * The frame status value can be found in the "reserved" field in the - * v4l2_buffer struct. */ -enum atomisp_frame_status { - ATOMISP_FRAME_STATUS_OK, - ATOMISP_FRAME_STATUS_CORRUPTED, - ATOMISP_FRAME_STATUS_FLASH_EXPOSED, - ATOMISP_FRAME_STATUS_FLASH_PARTIAL, - ATOMISP_FRAME_STATUS_FLASH_FAILED, -}; - enum atomisp_ext_isp_id { EXT_ISP_CID_ISO = 0, EXT_ISP_CID_CAPTURE_HDR, @@ -661,7 +626,6 @@ enum atomisp_ext_isp_id { EXT_ISP_CID_AF_STATUS, EXT_ISP_CID_GET_AF_MODE, EXT_ISP_CID_CAPTURE_BURST, - EXT_ISP_CID_FLASH_MODE, EXT_ISP_CID_ZOOM, EXT_ISP_CID_SHOT_MODE }; @@ -694,12 +658,6 @@ enum atomisp_burst_capture_options { EXT_ISP_BURST_CAPTURE_CTRL_STOP }; -#define EXT_ISP_FLASH_MODE_OFF 0 -#define EXT_ISP_FLASH_MODE_ON 1 -#define EXT_ISP_FLASH_MODE_AUTO 2 -#define EXT_ISP_LED_TORCH_OFF 3 -#define EXT_ISP_LED_TORCH_ON 4 - #define EXT_ISP_SHOT_MODE_AUTO 0 #define EXT_ISP_SHOT_MODE_BEAUTY_FACE 1 #define EXT_ISP_SHOT_MODE_BEST_PHOTO 2 @@ -894,18 +852,6 @@ enum atomisp_burst_capture_options { * Exposure, Flash and privacy (indicator) light controls, to be upstreamed */ #define V4L2_CID_CAMERA_LASTP1 (V4L2_CID_CAMERA_CLASS_BASE + 1024) -/* Flash related CIDs, see also: - * http://linuxtv.org/downloads/v4l-dvb-apis/extended-controls.html\ - * #flash-controls */ - -/* Request a number of flash-exposed frames. The frame status can be - * found in the reserved field in the v4l2_buffer struct. */ -#define V4L2_CID_REQUEST_FLASH (V4L2_CID_CAMERA_LASTP1 + 3) -/* Query flash driver status. See enum atomisp_flash_status above. */ -#define V4L2_CID_FLASH_STATUS (V4L2_CID_CAMERA_LASTP1 + 5) -/* Set the flash mode (see enum atomisp_flash_mode) */ -#define V4L2_CID_FLASH_MODE (V4L2_CID_CAMERA_LASTP1 + 10) - #define V4L2_CID_RUN_MODE (V4L2_CID_CAMERA_LASTP1 + 20) #define ATOMISP_RUN_MODE_VIDEO 1 #define ATOMISP_RUN_MODE_STILL_CAPTURE 2 @@ -925,9 +871,6 @@ enum atomisp_burst_capture_options { #define ATOMISP_VFPP_DISABLE_SCALER 1 #define ATOMISP_VFPP_DISABLE_LOWLAT 2 -/* Query real flash status register value */ -#define V4L2_CID_FLASH_STATUS_REGISTER (V4L2_CID_CAMERA_LASTP1 + 26) - #define V4L2_CID_START_ZSL_CAPTURE (V4L2_CID_CAMERA_LASTP1 + 28) /* Lock and unlock raw buffer */ #define V4L2_CID_ENABLE_RAW_BUFFER_LOCK (V4L2_CID_CAMERA_LASTP1 + 29) diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h index 64bd54835c32f3..ecd82220f04a99 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h @@ -19,8 +19,7 @@ #include "atomisp_platform.h" int atomisp_register_i2c_module(struct v4l2_subdev *subdev, - struct camera_sensor_platform_data *plat_data, - enum intel_v4l2_subdev_type type); + struct camera_sensor_platform_data *plat_data); int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd); int gmin_get_var_int(struct device *dev, bool is_gmin, const char *var, int def); @@ -29,7 +28,4 @@ gmin_camera_platform_data( struct v4l2_subdev *subdev, enum atomisp_input_format csi_format, enum atomisp_bayer_order csi_bayer); - -int atomisp_gmin_register_vcm_control(struct camera_vcm_control *); - #endif diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h index 2535402afd734d..0e3f6fb784839b 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h @@ -109,29 +109,12 @@ enum atomisp_input_format { #define N_ATOMISP_INPUT_FORMAT (ATOMISP_INPUT_FORMAT_USER_DEF8 + 1) -enum intel_v4l2_subdev_type { - RAW_CAMERA = 1, - LED_FLASH = 2, - TEST_PATTERN = 3, -}; - -struct intel_v4l2_subdev_id { - char name[17]; - enum intel_v4l2_subdev_type type; - enum atomisp_camera_port port; -}; - struct intel_v4l2_subdev_table { - enum intel_v4l2_subdev_type type; enum atomisp_camera_port port; unsigned int lanes; struct v4l2_subdev *subdev; }; -struct atomisp_platform_data { - struct intel_v4l2_subdev_table *subdevs; -}; - /* * Sensor of external ISP can send multiple steams with different mipi data * type in the same virtual channel. This information needs to come from the @@ -160,25 +143,6 @@ struct atomisp_input_stream_info { struct atomisp_isys_config_info isys_info[MAX_STREAMS_PER_CHANNEL]; }; -struct camera_vcm_control; -struct camera_vcm_ops { - int (*power_up)(struct v4l2_subdev *sd, struct camera_vcm_control *vcm); - int (*power_down)(struct v4l2_subdev *sd, - struct camera_vcm_control *vcm); - int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc, - struct camera_vcm_control *vcm); - int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl, - struct camera_vcm_control *vcm); - int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl, - struct camera_vcm_control *vcm); -}; - -struct camera_vcm_control { - char camera_module[CAMERA_MODULE_ID_LEN]; - struct camera_vcm_ops *ops; - struct list_head list; -}; - struct camera_sensor_platform_data { int (*flisclk_ctrl)(struct v4l2_subdev *subdev, int flag); int (*csi_cfg)(struct v4l2_subdev *subdev, int flag); @@ -192,8 +156,6 @@ struct camera_sensor_platform_data { int (*v1p8_ctrl)(struct v4l2_subdev *subdev, int on); int (*v2p8_ctrl)(struct v4l2_subdev *subdev, int on); int (*v1p2_ctrl)(struct v4l2_subdev *subdev, int on); - struct camera_vcm_control *(*get_vcm_ctrl)(struct v4l2_subdev *subdev, - char *module_id); }; struct camera_mipi_info { @@ -207,7 +169,7 @@ struct camera_mipi_info { const u32 *metadata_effective_width; }; -const struct atomisp_platform_data *atomisp_get_platform_data(void); +const struct intel_v4l2_subdev_table *atomisp_platform_get_subdevs(void); int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes, enum atomisp_input_format format, enum atomisp_bayer_order bayer_order); diff --git a/drivers/staging/media/atomisp/include/media/lm3554.h b/drivers/staging/media/atomisp/include/media/lm3554.h deleted file mode 100644 index 711b7d7c995089..00000000000000 --- a/drivers/staging/media/atomisp/include/media/lm3554.h +++ /dev/null @@ -1,132 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * include/media/lm3554.h - * - * Copyright (c) 2010-2012 Intel Corporation. All Rights Reserved. - * - * 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. - * - * - */ -#ifndef _LM3554_H_ -#define _LM3554_H_ - -#include <linux/gpio/consumer.h> -#include <linux/videodev2.h> -#include <media/v4l2-subdev.h> - -#define LM3554_ID 3554 - -#define v4l2_queryctrl_entry_integer(_id, _name,\ - _minimum, _maximum, _step, \ - _default_value, _flags) \ - {\ - .id = (_id), \ - .type = V4L2_CTRL_TYPE_INTEGER, \ - .name = _name, \ - .minimum = (_minimum), \ - .maximum = (_maximum), \ - .step = (_step), \ - .default_value = (_default_value),\ - .flags = (_flags),\ - } -#define v4l2_queryctrl_entry_boolean(_id, _name,\ - _default_value, _flags) \ - {\ - .id = (_id), \ - .type = V4L2_CTRL_TYPE_BOOLEAN, \ - .name = _name, \ - .minimum = 0, \ - .maximum = 1, \ - .step = 1, \ - .default_value = (_default_value),\ - .flags = (_flags),\ - } - -#define s_ctrl_id_entry_integer(_id, _name, \ - _minimum, _maximum, _step, \ - _default_value, _flags, \ - _s_ctrl, _g_ctrl) \ - {\ - .qc = v4l2_queryctrl_entry_integer(_id, _name,\ - _minimum, _maximum, _step,\ - _default_value, _flags), \ - .s_ctrl = _s_ctrl, \ - .g_ctrl = _g_ctrl, \ - } - -#define s_ctrl_id_entry_boolean(_id, _name, \ - _default_value, _flags, \ - _s_ctrl, _g_ctrl) \ - {\ - .qc = v4l2_queryctrl_entry_boolean(_id, _name,\ - _default_value, _flags), \ - .s_ctrl = _s_ctrl, \ - .g_ctrl = _g_ctrl, \ - } - -/* Value settings for Flash Time-out Duration*/ -#define LM3554_DEFAULT_TIMEOUT 512U -#define LM3554_MIN_TIMEOUT 32U -#define LM3554_MAX_TIMEOUT 1024U -#define LM3554_TIMEOUT_STEPSIZE 32U - -/* Flash modes */ -#define LM3554_MODE_SHUTDOWN 0 -#define LM3554_MODE_INDICATOR 1 -#define LM3554_MODE_TORCH 2 -#define LM3554_MODE_FLASH 3 - -/* timer delay time */ -#define LM3554_TIMER_DELAY 5 - -/* Percentage <-> value macros */ -#define LM3554_MIN_PERCENT 0U -#define LM3554_MAX_PERCENT 100U -#define LM3554_CLAMP_PERCENTAGE(val) \ - clamp(val, LM3554_MIN_PERCENT, LM3554_MAX_PERCENT) - -#define LM3554_VALUE_TO_PERCENT(v, step) (((((unsigned long)(v)) * (step)) + 50) / 100) -#define LM3554_PERCENT_TO_VALUE(p, step) (((((unsigned long)(p)) * 100) + (step >> 1)) / (step)) - -/* Product specific limits - * TODO: get these from platform data */ -#define LM3554_FLASH_MAX_LVL 0x0F /* 1191mA */ - -/* Flash brightness, input is percentage, output is [0..15] */ -#define LM3554_FLASH_STEP \ - ((100ul * (LM3554_MAX_PERCENT) + ((LM3554_FLASH_MAX_LVL) >> 1)) / ((LM3554_FLASH_MAX_LVL))) -#define LM3554_FLASH_DEFAULT_BRIGHTNESS \ - LM3554_VALUE_TO_PERCENT(13, LM3554_FLASH_STEP) - -/* Torch brightness, input is percentage, output is [0..7] */ -#define LM3554_TORCH_STEP 1250 -#define LM3554_TORCH_DEFAULT_BRIGHTNESS \ - LM3554_VALUE_TO_PERCENT(2, LM3554_TORCH_STEP) - -/* Indicator brightness, input is percentage, output is [0..3] */ -#define LM3554_INDICATOR_STEP 2500 -#define LM3554_INDICATOR_DEFAULT_BRIGHTNESS \ - LM3554_VALUE_TO_PERCENT(1, LM3554_INDICATOR_STEP) - -/* - * lm3554_platform_data - Flash controller platform data - */ -struct lm3554_platform_data { - struct gpio_desc *gpio_torch; - struct gpio_desc *gpio_strobe; - struct gpio_desc *gpio_reset; - - unsigned int current_limit; - unsigned int envm_tx2; - unsigned int tx2_polarity; -}; - -#endif /* _LM3554_H_ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index eb37bb6e41f977..102d39a45c9c03 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -61,13 +61,6 @@ #include "ia_css_debug.h" #include "bits.h" -/* We should never need to run the flash for more than 2 frames. - * At 15fps this means 133ms. We set the timeout a bit longer. - * Each flash driver is supposed to set its own timeout, but - * just in case someone else changed the timeout, we set it - * here to make sure we don't damage the flash hardware. */ -#define FLASH_TIMEOUT 800 /* ms */ - union host { struct { void *kernel_ptr; @@ -676,7 +669,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, struct atomisp_metadata_buf *md_buf = NULL, *_md_buf_tmp, *md_iter; enum atomisp_metadata_type md_type; struct atomisp_device *isp = asd->isp; - struct v4l2_control ctrl; int i, err; lockdep_assert_held(&isp->mutex); @@ -791,19 +783,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, dev_dbg(isp->dev, "%s: vf frame with exp_id %d is ready\n", __func__, frame->exp_id); - if (asd->params.flash_state == ATOMISP_FLASH_ONGOING) { - if (frame->flash_state - == IA_CSS_FRAME_FLASH_STATE_PARTIAL) - dev_dbg(isp->dev, "%s thumb partially flashed\n", - __func__); - else if (frame->flash_state - == IA_CSS_FRAME_FLASH_STATE_FULL) - dev_dbg(isp->dev, "%s thumb completely flashed\n", - __func__); - else - dev_dbg(isp->dev, "%s thumb no flash in this frame\n", - __func__); - } pipe->frame_config_id[frame->vb.vb2_buf.index] = frame->isp_config_id; break; case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME: @@ -834,40 +813,6 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, } pipe->frame_config_id[i] = frame->isp_config_id; - ctrl.id = V4L2_CID_FLASH_MODE; - if (asd->params.flash_state == ATOMISP_FLASH_ONGOING) { - if (frame->flash_state == IA_CSS_FRAME_FLASH_STATE_PARTIAL) { - asd->frame_status[i] = ATOMISP_FRAME_STATUS_FLASH_PARTIAL; - dev_dbg(isp->dev, "%s partially flashed\n", __func__); - } else if (frame->flash_state == IA_CSS_FRAME_FLASH_STATE_FULL) { - asd->frame_status[i] = ATOMISP_FRAME_STATUS_FLASH_EXPOSED; - asd->params.num_flash_frames--; - dev_dbg(isp->dev, "%s completely flashed\n", __func__); - } else { - asd->frame_status[i] = ATOMISP_FRAME_STATUS_OK; - dev_dbg(isp->dev, "%s no flash in this frame\n", __func__); - } - - /* Check if flashing sequence is done */ - if (asd->frame_status[i] == ATOMISP_FRAME_STATUS_FLASH_EXPOSED) - asd->params.flash_state = ATOMISP_FLASH_DONE; - } else if (isp->flash) { - if (v4l2_g_ctrl(isp->flash->ctrl_handler, &ctrl) == 0 && - ctrl.value == ATOMISP_FLASH_MODE_TORCH) { - ctrl.id = V4L2_CID_FLASH_TORCH_INTENSITY; - if (v4l2_g_ctrl(isp->flash->ctrl_handler, &ctrl) == 0 && - ctrl.value > 0) - asd->frame_status[i] = ATOMISP_FRAME_STATUS_FLASH_EXPOSED; - else - asd->frame_status[i] = ATOMISP_FRAME_STATUS_OK; - } else { - asd->frame_status[i] = ATOMISP_FRAME_STATUS_OK; - } - } else { - asd->frame_status[i] = ATOMISP_FRAME_STATUS_OK; - } - - asd->params.last_frame_status = asd->frame_status[i]; if (asd->params.css_update_params_needed) { atomisp_apply_css_parameters(asd, @@ -1010,51 +955,18 @@ out_unlock: mutex_unlock(&isp->mutex); } -void atomisp_setup_flash(struct atomisp_sub_device *asd) -{ - struct atomisp_device *isp = asd->isp; - struct v4l2_control ctrl; - - if (!isp->flash) - return; - - if (asd->params.flash_state != ATOMISP_FLASH_REQUESTED && - asd->params.flash_state != ATOMISP_FLASH_DONE) - return; - - if (asd->params.num_flash_frames) { - /* make sure the timeout is set before setting flash mode */ - ctrl.id = V4L2_CID_FLASH_TIMEOUT; - ctrl.value = FLASH_TIMEOUT; - - if (v4l2_s_ctrl(NULL, isp->flash->ctrl_handler, &ctrl)) { - dev_err(isp->dev, "flash timeout configure failed\n"); - return; - } - - ia_css_stream_request_flash(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream); - - asd->params.flash_state = ATOMISP_FLASH_ONGOING; - } else { - asd->params.flash_state = ATOMISP_FLASH_IDLE; - } -} - irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr) { struct atomisp_device *isp = isp_ptr; unsigned long flags; - - dev_dbg(isp->dev, ">%s\n", __func__); + bool streaming; spin_lock_irqsave(&isp->lock, flags); + streaming = isp->asd.streaming; + spin_unlock_irqrestore(&isp->lock, flags); - if (!isp->asd.streaming) { - spin_unlock_irqrestore(&isp->lock, flags); + if (!streaming) return IRQ_HANDLED; - } - - spin_unlock_irqrestore(&isp->lock, flags); /* * The standard CSS2.0 API tells the following calling sequence of @@ -1082,14 +994,8 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr) * time, instead, dequue one and process one, then another */ mutex_lock(&isp->mutex); - if (atomisp_css_isr_thread(isp)) - goto out; - - if (isp->asd.streaming) - atomisp_setup_flash(&isp->asd); -out: + atomisp_css_isr_thread(isp); mutex_unlock(&isp->mutex); - dev_dbg(isp->dev, "<%s\n", __func__); return IRQ_HANDLED; } @@ -1123,7 +1029,7 @@ v4l2_fmt_to_sh_fmt(u32 fmt) return IA_CSS_FRAME_FORMAT_YUYV; case V4L2_PIX_FMT_RGB24: return IA_CSS_FRAME_FORMAT_PLANAR_RGB888; - case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGBX32: return IA_CSS_FRAME_FORMAT_RGBA888; case V4L2_PIX_FMT_RGB565: return IA_CSS_FRAME_FORMAT_RGB565; @@ -1210,7 +1116,7 @@ u32 atomisp_get_pixel_depth(u32 pixelformat) case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_YUV444: return 24; - case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGBX32: return 32; case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_CUSTOM_M10MO_RAW: @@ -1261,11 +1167,11 @@ int atomisp_gdc_cac(struct atomisp_sub_device *asd, int flag, } asd->params.gdc_cac_en = !!*value; - if (asd->params.gdc_cac_en) { + if (asd->params.gdc_cac_en) asd->params.config.morph_table = asd->params.css_param.morph_table; - } else { + else asd->params.config.morph_table = NULL; - } + asd->params.css_update_params_needed = true; atomisp_update_capture_mode(asd); return 0; @@ -3035,8 +2941,8 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe) } /* -* Function to configure ISP parameters -*/ + * Function to configure ISP parameters + */ int atomisp_set_parameters(struct video_device *vdev, struct atomisp_parameters *arg) { @@ -3367,7 +3273,7 @@ int atomisp_fixed_pattern(struct atomisp_sub_device *asd, int flag, return 0; } - /* Add function to get black from from sensor with shutter off */ + /* Add function to get black from sensor with shutter off */ return 0; } @@ -3721,6 +3627,76 @@ apply_min_padding: *padding_h = max_t(u32, *padding_h, min_pad_h); } +int atomisp_s_sensor_power(struct atomisp_device *isp, unsigned int input, bool on) +{ + int ret; + + if (isp->inputs[input].camera_on == on) + return 0; + + ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, on); + if (ret && ret != -ENOIOCTLCMD) { + dev_err(isp->dev, "Error setting sensor power %d: %d\n", on, ret); + return ret; + } + + isp->inputs[input].camera_on = on; + return 0; +} + +int atomisp_select_input(struct atomisp_device *isp, unsigned int input) +{ + unsigned int input_orig = isp->asd.input_curr; + int ret; + + /* Power on new sensor */ + ret = atomisp_s_sensor_power(isp, input, 1); + if (ret) + return ret; + + isp->asd.input_curr = input; + + /* Power off previous sensor */ + if (input != input_orig) + atomisp_s_sensor_power(isp, input_orig, 0); + + atomisp_setup_input_links(isp); + return 0; +} + +/* + * Ensure the CSI-receiver -> ISP link for input_curr is marked as enabled and + * the other CSI-receiver -> ISP links are disabled. + */ +void atomisp_setup_input_links(struct atomisp_device *isp) +{ + struct media_link *link; + + lockdep_assert_held(&isp->media_dev.graph_mutex); + + for (int i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { + link = media_entity_find_link( + &isp->csi2_port[i].subdev.entity.pads[CSI2_PAD_SOURCE], + &isp->asd.subdev.entity.pads[ATOMISP_SUBDEV_PAD_SINK]); + if (!link) { + dev_err(isp->dev, "Error cannot find CSI2-port[%d] -> ISP link\n", i); + continue; /* Should never happen */ + } + + /* + * Modify the flags directly, calling media_entity_setup_link() + * will end up calling atomisp_link_setup() which calls this + * function again leading to endless recursion. + */ + if (isp->sensor_subdevs[i] == isp->inputs[isp->asd.input_curr].camera) + link->flags |= MEDIA_LNK_FL_ENABLED; + else + link->flags &= ~MEDIA_LNK_FL_ENABLED; + + link->reverse->flags = link->flags; + } +} + static int atomisp_set_sensor_crop_and_fmt(struct atomisp_device *isp, struct v4l2_mbus_framefmt *ffmt, int which) @@ -3742,6 +3718,17 @@ static int atomisp_set_sensor_crop_and_fmt(struct atomisp_device *isp, if (!input->camera) return -EINVAL; + /* + * Some old sensor drivers already write the registers on set_fmt + * instead of on stream on, power on the sensor now (on newer + * sensor drivers the s_power op is a no-op). + */ + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { + ret = atomisp_s_sensor_power(isp, isp->asd.input_curr, 1); + if (ret) + return ret; + } + sd_state = (which == V4L2_SUBDEV_FORMAT_TRY) ? input->try_sd_state : input->camera->active_state; if (sd_state) @@ -3776,6 +3763,13 @@ set_fmt: if (sd_state) v4l2_subdev_unlock_state(sd_state); + /* Propagate new fmt to CSI port */ + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { + ret = v4l2_subdev_call(input->csi_port, pad, set_fmt, NULL, &format); + if (ret) + return ret; + } + *ffmt = format.format; return ret; } @@ -4044,6 +4038,7 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, unsigned int width, unsigned int height) = configure_pp_input_nop; const struct atomisp_in_fmt_conv *fc = NULL; + struct v4l2_mbus_framefmt *ffmt; int ret, i; isp_sink_crop = atomisp_subdev_get_rect( @@ -4054,28 +4049,26 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, if (!format) return -EINVAL; - if (input->type != TEST_PATTERN) { - mipi_info = atomisp_to_sensor_mipi_info(input->camera); + mipi_info = atomisp_to_sensor_mipi_info(input->camera); - if (atomisp_set_sensor_mipi_to_isp(asd, ATOMISP_INPUT_STREAM_GENERAL, - mipi_info)) - return -EINVAL; - - if (mipi_info) - fc = atomisp_find_in_fmt_conv_by_atomisp_in_fmt(mipi_info->input_format); + if (atomisp_set_sensor_mipi_to_isp(asd, ATOMISP_INPUT_STREAM_GENERAL, + mipi_info)) + return -EINVAL; - if (!fc) - fc = atomisp_find_in_fmt_conv( - atomisp_subdev_get_ffmt(&asd->subdev, - NULL, V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK)->code); - if (!fc) - return -EINVAL; - if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW && - raw_output_format_match_input(fc->atomisp_in_fmt, - pix->pixelformat)) - return -EINVAL; + if (mipi_info) + fc = atomisp_find_in_fmt_conv_by_atomisp_in_fmt(mipi_info->input_format); + if (!fc) { + ffmt = atomisp_subdev_get_ffmt(&asd->subdev, NULL, + V4L2_SUBDEV_FORMAT_ACTIVE, + ATOMISP_SUBDEV_PAD_SINK); + fc = atomisp_find_in_fmt_conv(ffmt->code); } + if (!fc) + return -EINVAL; + + if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW && + raw_output_format_match_input(fc->atomisp_in_fmt, pix->pixelformat)) + return -EINVAL; /* * Configure viewfinder also when vfpp is disabled: the @@ -4420,8 +4413,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) atomisp_fill_pix_format(&pipe->pix, f->fmt.pix.width, f->fmt.pix.height, format_bridge); f->fmt.pix = pipe->pix; - f->fmt.pix.priv = PAGE_ALIGN(pipe->pix.width * - pipe->pix.height * 2); dev_dbg(isp->dev, "%s: %dx%d, image size: %d, %d bytes per line\n", __func__, @@ -4493,28 +4484,6 @@ out: return ret; } -int atomisp_flash_enable(struct atomisp_sub_device *asd, int num_frames) -{ - struct atomisp_device *isp = asd->isp; - - if (num_frames < 0) { - dev_dbg(isp->dev, "%s ERROR: num_frames: %d\n", __func__, - num_frames); - return -EINVAL; - } - /* a requested flash is still in progress. */ - if (num_frames && asd->params.flash_state != ATOMISP_FLASH_IDLE) { - dev_dbg(isp->dev, "%s flash busy: %d frames left: %d\n", - __func__, asd->params.flash_state, - asd->params.num_flash_frames); - return -EBUSY; - } - - asd->params.num_flash_frames = num_frames; - asd->params.flash_state = ATOMISP_FLASH_REQUESTED; - return 0; -} - static int __checking_exp_id(struct atomisp_sub_device *asd, int exp_id) { struct atomisp_device *isp = asd->isp; diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h index b8cd957eebdc21..e69ca14645b9f0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h @@ -58,7 +58,6 @@ void atomisp_clear_css_buffer_counters(struct atomisp_sub_device *asd); void atomisp_msi_irq_init(struct atomisp_device *isp); void atomisp_msi_irq_uninit(struct atomisp_device *isp); void atomisp_assert_recovery_work(struct work_struct *work); -void atomisp_setup_flash(struct atomisp_sub_device *asd); irqreturn_t atomisp_isr(int irq, void *dev); irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr); const struct atomisp_format_bridge *get_atomisp_format_bridge_from_mbus( @@ -241,6 +240,15 @@ int atomisp_compare_grid(struct atomisp_sub_device *asd, void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height, u32 *padding_w, u32 *padding_h); +/* Set sensor power (no-op if already on/off) */ +int atomisp_s_sensor_power(struct atomisp_device *isp, unsigned int input, bool on); + +/* Select which sensor to use, must be called with a valid input */ +int atomisp_select_input(struct atomisp_device *isp, unsigned int input); + +/* Setup media-controller links to reflect input_curr setting */ +void atomisp_setup_input_links(struct atomisp_device *isp); + /* This function looks up the closest available resolution. */ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, const struct atomisp_format_bridge **fmt_ret, @@ -253,9 +261,6 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd, void atomisp_free_internal_buffers(struct atomisp_sub_device *asd); -int atomisp_flash_enable(struct atomisp_sub_device *asd, - int num_frames); - int atomisp_freq_scaling(struct atomisp_device *vdev, enum atomisp_dfs_mode mode, bool force); diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index 6fe8b0b7467a78..a62a5c0b3c002f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -302,21 +302,6 @@ static void __dump_stream_config(struct atomisp_sub_device *asd, "stream_config.source.port.compression.uncompressed_bits_per_pixel=%d.\n", s_config->source.port.compression. uncompressed_bits_per_pixel); - } else if (s_config->mode == IA_CSS_INPUT_MODE_TPG) { - dev_dbg(isp->dev, "stream_config.source.tpg.id=%d.\n", - s_config->source.tpg.id); - dev_dbg(isp->dev, "stream_config.source.tpg.mode=%d.\n", - s_config->source.tpg.mode); - dev_dbg(isp->dev, "stream_config.source.tpg.x_mask=%d.\n", - s_config->source.tpg.x_mask); - dev_dbg(isp->dev, "stream_config.source.tpg.x_delta=%d.\n", - s_config->source.tpg.x_delta); - dev_dbg(isp->dev, "stream_config.source.tpg.y_mask=%d.\n", - s_config->source.tpg.y_mask); - dev_dbg(isp->dev, "stream_config.source.tpg.y_delta=%d.\n", - s_config->source.tpg.y_delta); - dev_dbg(isp->dev, "stream_config.source.tpg.xy_mask=%d.\n", - s_config->source.tpg.xy_mask); } else if (s_config->mode == IA_CSS_INPUT_MODE_PRBS) { dev_dbg(isp->dev, "stream_config.source.prbs.id=%d.\n", s_config->source.prbs.id); @@ -1672,26 +1657,12 @@ void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd, void atomisp_css_input_set_mode(struct atomisp_sub_device *asd, enum ia_css_input_mode mode) { - int i; - struct atomisp_device *isp = asd->isp; unsigned int size_mem_words; + int i; for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) asd->stream_env[i].stream_config.mode = mode; - if (isp->inputs[asd->input_curr].type == TEST_PATTERN) { - struct ia_css_stream_config *s_config = - &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_config; - s_config->mode = IA_CSS_INPUT_MODE_TPG; - s_config->source.tpg.mode = IA_CSS_TPG_MODE_CHECKERBOARD; - s_config->source.tpg.x_mask = (1 << 4) - 1; - s_config->source.tpg.x_delta = -2; - s_config->source.tpg.y_mask = (1 << 4) - 1; - s_config->source.tpg.y_delta = 3; - s_config->source.tpg.xy_mask = (1 << 8) - 1; - return; - } - if (mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) return; diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp_csi2.c index 89118438a3b679..9288910eeb6c06 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c @@ -107,9 +107,12 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, actual_ffmt->height = clamp_t(u32, ffmt->height, ATOM_ISP_MIN_HEIGHT, ATOM_ISP_MAX_HEIGHT); + actual_ffmt->field = ffmt->field; tmp_ffmt = *ffmt = *actual_ffmt; + /* Always use V4L2_FIELD_ANY to match the ISP sink pad */ + tmp_ffmt.field = V4L2_FIELD_ANY; return atomisp_csi2_set_ffmt(sd, sd_state, which, CSI2_PAD_SOURCE, &tmp_ffmt); @@ -138,27 +141,6 @@ static int csi2_set_format(struct v4l2_subdev *sd, &fmt->format); } -/* - * csi2_set_stream - Enable/Disable streaming on the CSI2 module - * @sd: ISP CSI2 V4L2 subdevice - * @enable: Enable/disable stream (1/0) - * - * Return 0 on success or a negative error code otherwise. - */ -static int csi2_set_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - -/* subdev core operations */ -static const struct v4l2_subdev_core_ops csi2_core_ops = { -}; - -/* subdev video operations */ -static const struct v4l2_subdev_video_ops csi2_video_ops = { - .s_stream = csi2_set_stream, -}; - /* subdev pad operations */ static const struct v4l2_subdev_pad_ops csi2_pad_ops = { .enum_mbus_code = csi2_enum_mbus_code, @@ -169,8 +151,6 @@ static const struct v4l2_subdev_pad_ops csi2_pad_ops = { /* subdev operations */ static const struct v4l2_subdev_ops csi2_ops = { - .core = &csi2_core_ops, - .video = &csi2_video_ops, .pad = &csi2_pad_ops, }; diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 4dba6120af391f..50c4123ba00664 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -445,12 +445,8 @@ const struct vb2_ops atomisp_vb2_ops = { static void atomisp_dev_init_struct(struct atomisp_device *isp) { - unsigned int i; - isp->isp_fatal_error = false; - for (i = 0; i < isp->input_cnt; i++) - isp->inputs[i].asd = NULL; /* * For Merrifield, frequency is scalable. * After boot-up, the default frequency is 200MHz. @@ -524,21 +520,12 @@ static int atomisp_open(struct file *file) } atomisp_dev_init_struct(isp); - - ret = v4l2_subdev_call(isp->flash, core, s_power, 1); - if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) { - dev_err(isp->dev, "Failed to power-on flash\n"); - goto css_error; - } - atomisp_subdev_init_struct(asd); pipe->users++; mutex_unlock(&isp->mutex); return 0; -css_error: - pm_runtime_put(vdev->v4l2_dev->dev); error: mutex_unlock(&isp->mutex); v4l2_fh_release(file); @@ -552,8 +539,6 @@ static int atomisp_release(struct file *file) struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); struct atomisp_sub_device *asd = pipe->asd; struct v4l2_subdev_fh fh; - struct v4l2_rect clear_compose = {0}; - int ret; v4l2_fh_init(&fh.vfh, vdev); @@ -566,48 +551,16 @@ static int atomisp_release(struct file *file) pipe->users--; - /* - * A little trick here: - * file injection input resolution is recorded in the sink pad, - * therefore can not be cleared when releaseing one device node. - * The sink pad setting can only be cleared when all device nodes - * get released. - */ - { - struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; - - atomisp_subdev_set_ffmt(&asd->subdev, fh.state, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); - } - atomisp_css_free_stat_buffers(asd); atomisp_free_internal_buffers(asd); - if (isp->inputs[asd->input_curr].asd == asd) { - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - core, s_power, 0); - if (ret && ret != -ENOIOCTLCMD) - dev_warn(isp->dev, "Failed to power-off sensor\n"); - - /* clear the asd field to show this camera is not used */ - isp->inputs[asd->input_curr].asd = NULL; - } + atomisp_s_sensor_power(isp, asd->input_curr, 0); atomisp_destroy_pipes_stream(asd); - ret = v4l2_subdev_call(isp->flash, core, s_power, 0); - if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) - dev_warn(isp->dev, "Failed to power-off flash\n"); - if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0) dev_err(isp->dev, "Failed to power off device\n"); - atomisp_subdev_set_selection(&asd->subdev, fh.state, - V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SOURCE, - V4L2_SEL_TGT_COMPOSE, 0, - &clear_compose); mutex_unlock(&isp->mutex); return 0; } diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index 139ad7ad1dcf6e..e176483df301f5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -75,7 +75,6 @@ struct gmin_subdev { struct regulator *v1p8_reg; struct regulator *v2p8_reg; struct regulator *v1p2_reg; - struct regulator *v2p8_vcm_reg; enum atomisp_camera_port csi_port; unsigned int csi_lanes; enum atomisp_input_format csi_fmt; @@ -85,7 +84,6 @@ struct gmin_subdev { bool v1p8_on; bool v2p8_on; bool v1p2_on; - bool v2p8_vcm_on; int v1p8_gpio; int v2p8_gpio; @@ -126,35 +124,25 @@ static DEFINE_MUTEX(gmin_regulator_mutex); static int gmin_v1p8_enable_count; static int gmin_v2p8_enable_count; -/* The atomisp uses type==0 for the end-of-list marker, so leave space. */ +/* The atomisp uses subdev==NULL for the end-of-list marker, so leave space. */ static struct intel_v4l2_subdev_table pdata_subdevs[MAX_SUBDEVS + 1]; -static const struct atomisp_platform_data pdata = { - .subdevs = pdata_subdevs, -}; - -static LIST_HEAD(vcm_devices); -static DEFINE_MUTEX(vcm_lock); - static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev); -const struct atomisp_platform_data *atomisp_get_platform_data(void) +const struct intel_v4l2_subdev_table *atomisp_platform_get_subdevs(void) { - return &pdata; + return pdata_subdevs; } -EXPORT_SYMBOL_GPL(atomisp_get_platform_data); +EXPORT_SYMBOL_GPL(atomisp_platform_get_subdevs); int atomisp_register_i2c_module(struct v4l2_subdev *subdev, - struct camera_sensor_platform_data *plat_data, - enum intel_v4l2_subdev_type type) + struct camera_sensor_platform_data *plat_data) { int i; struct gmin_subdev *gs; struct i2c_client *client = v4l2_get_subdevdata(subdev); struct acpi_device *adev = ACPI_COMPANION(&client->dev); - dev_info(&client->dev, "register atomisp i2c module type %d\n", type); - /* The windows driver model (and thus most BIOSes by default) * uses ACPI runtime power management for camera devices, but * we don't. Disable it, or else the rails will be needlessly @@ -172,10 +160,10 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev, adev->power.flags.power_resources = 0; for (i = 0; i < MAX_SUBDEVS; i++) - if (!pdata.subdevs[i].type) + if (!pdata_subdevs[i].subdev) break; - if (pdata.subdevs[i].type) + if (i == MAX_SUBDEVS) return -ENOMEM; /* Note subtlety of initialization order: at the point where @@ -187,10 +175,9 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev, if (!gs) return -ENODEV; - pdata.subdevs[i].type = type; - pdata.subdevs[i].port = gs->csi_port; - pdata.subdevs[i].lanes = gs->csi_lanes; - pdata.subdevs[i].subdev = subdev; + pdata_subdevs[i].port = gs->csi_port; + pdata_subdevs[i].lanes = gs->csi_lanes; + pdata_subdevs[i].subdev = subdev; return 0; } EXPORT_SYMBOL_GPL(atomisp_register_i2c_module); @@ -203,9 +190,9 @@ int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd) return 0; for (i = 0; i < MAX_SUBDEVS; i++) { - if (pdata.subdevs[i].subdev == sd) { + if (pdata_subdevs[i].subdev == sd) { for (j = i + 1; j <= MAX_SUBDEVS; j++) - pdata.subdevs[j - 1] = pdata.subdevs[j]; + pdata_subdevs[j - 1] = pdata_subdevs[j]; } if (gmin_subdevs[i].subdev == sd) { if (gmin_subdevs[i].gpio0) @@ -218,7 +205,6 @@ int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd) regulator_put(gmin_subdevs[i].v1p8_reg); regulator_put(gmin_subdevs[i].v2p8_reg); regulator_put(gmin_subdevs[i].v1p2_reg); - regulator_put(gmin_subdevs[i].v2p8_vcm_reg); } gmin_subdevs[i].subdev = NULL; } @@ -388,20 +374,16 @@ static struct i2c_client *gmin_i2c_dev_exists(struct device *dev, char *name, struct i2c_client **client) { struct acpi_device *adev; - struct device *d; adev = acpi_dev_get_first_match_dev(name, NULL, -1); if (!adev) return NULL; - d = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); + *client = i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); acpi_dev_put(adev); - if (!d) + if (!*client) return NULL; - *client = i2c_verify_client(d); - put_device(d); - dev_dbg(dev, "found '%s' at address 0x%02x, adapter %d\n", (*client)->name, (*client)->addr, (*client)->adapter->nr); return *client; @@ -497,16 +479,19 @@ static u8 gmin_get_pmic_id_and_addr(struct device *dev) if (pmic_id) return pmic_i2c_addr; - if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power)) + if (gmin_i2c_dev_exists(dev, PMIC_ACPI_TI, &power)) { pmic_id = PMIC_TI; - else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power)) + } else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_AXP, &power)) { pmic_id = PMIC_AXP; - else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power)) + } else if (gmin_i2c_dev_exists(dev, PMIC_ACPI_CRYSTALCOVE, &power)) { pmic_id = PMIC_CRYSTALCOVE; - else + } else { pmic_id = PMIC_REGULATOR; + return 0; + } - pmic_i2c_addr = power ? power->addr : 0; + pmic_i2c_addr = power->addr; + put_device(&power->dev); return pmic_i2c_addr; } @@ -669,7 +654,6 @@ static int gmin_subdev_add(struct gmin_subdev *gs) gs->v2p8_reg = regulator_get(dev, "V2P8SX"); gs->v1p2_reg = regulator_get(dev, "V1P2A"); - gs->v2p8_vcm_reg = regulator_get(dev, "VPROG4B"); /* Note: ideally we would initialize v[12]p8_on to the * output of regulator_is_enabled(), but sadly that @@ -1137,7 +1121,7 @@ int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes, } for (i = 0; i < MAX_SUBDEVS; i++) - if (!pdata.subdevs[i].type) + if (!pdata_subdevs[i].subdev) break; if (i >= MAX_SUBDEVS) { @@ -1149,10 +1133,9 @@ int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes, if (ret) return ret; - pdata.subdevs[i].type = RAW_CAMERA; - pdata.subdevs[i].port = port; - pdata.subdevs[i].lanes = lanes; - pdata.subdevs[i].subdev = subdev; + pdata_subdevs[i].port = port; + pdata_subdevs[i].lanes = lanes; + pdata_subdevs[i].subdev = subdev; return 0; } EXPORT_SYMBOL_GPL(atomisp_register_sensor_no_gmin); @@ -1162,43 +1145,17 @@ void atomisp_unregister_subdev(struct v4l2_subdev *subdev) int i; for (i = 0; i < MAX_SUBDEVS; i++) { - if (pdata.subdevs[i].subdev != subdev) + if (pdata_subdevs[i].subdev != subdev) continue; camera_sensor_csi_free(subdev); - pdata.subdevs[i].subdev = NULL; - pdata.subdevs[i].type = 0; - pdata.subdevs[i].port = 0; + pdata_subdevs[i].subdev = NULL; + pdata_subdevs[i].port = 0; break; } } EXPORT_SYMBOL_GPL(atomisp_unregister_subdev); -static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev, - char *camera_module) -{ - struct i2c_client *client = v4l2_get_subdevdata(subdev); - struct gmin_subdev *gs = find_gmin_subdev(subdev); - struct camera_vcm_control *vcm; - - if (!client || !gs) - return NULL; - - if (!camera_module) - return NULL; - - mutex_lock(&vcm_lock); - list_for_each_entry(vcm, &vcm_devices, list) { - if (!strcmp(camera_module, vcm->camera_module)) { - mutex_unlock(&vcm_lock); - return vcm; - } - } - - mutex_unlock(&vcm_lock); - return NULL; -} - static struct camera_sensor_platform_data pmic_gmin_plat = { .gpio0_ctrl = gmin_gpio0_ctrl, .gpio1_ctrl = gmin_gpio1_ctrl, @@ -1207,7 +1164,6 @@ static struct camera_sensor_platform_data pmic_gmin_plat = { .v1p2_ctrl = gmin_v1p2_ctrl, .flisclk_ctrl = gmin_flisclk_ctrl, .csi_cfg = gmin_csi_cfg, - .get_vcm_ctrl = gmin_get_vcm_ctrl, }; static struct camera_sensor_platform_data acpi_gmin_plat = { @@ -1218,7 +1174,6 @@ static struct camera_sensor_platform_data acpi_gmin_plat = { .v1p2_ctrl = gmin_acpi_pm_ctrl, .flisclk_ctrl = gmin_acpi_pm_ctrl, .csi_cfg = gmin_csi_cfg, - .get_vcm_ctrl = gmin_get_vcm_ctrl, }; struct camera_sensor_platform_data * @@ -1243,19 +1198,6 @@ gmin_camera_platform_data(struct v4l2_subdev *subdev, } EXPORT_SYMBOL_GPL(gmin_camera_platform_data); -int atomisp_gmin_register_vcm_control(struct camera_vcm_control *vcmCtrl) -{ - if (!vcmCtrl) - return -EINVAL; - - mutex_lock(&vcm_lock); - list_add_tail(&vcmCtrl->list, &vcm_devices); - mutex_unlock(&vcm_lock); - - return 0; -} -EXPORT_SYMBOL_GPL(atomisp_gmin_register_vcm_control); - static int gmin_get_hardcoded_var(struct device *dev, struct gmin_cfg_var *varlist, const char *var8, char *out, size_t *out_len) @@ -1416,13 +1358,12 @@ static int gmin_get_config_var(struct device *maindev, if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) status = efi.get_variable(var16, &GMIN_CFG_VAR_EFI_GUID, NULL, (unsigned long *)out_len, out); - if (status == EFI_SUCCESS) { + if (status == EFI_SUCCESS) dev_info(maindev, "found EFI entry for '%s'\n", var8); - } else if (is_gmin) { + else if (is_gmin) dev_info(maindev, "Failed to find EFI gmin variable %s\n", var8); - } else { + else dev_info(maindev, "Failed to find EFI variable %s\n", var8); - } return ret; } diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index ca8ed3a6b9b8ee..9c2bc5332fa4e7 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -36,7 +36,6 @@ #include "atomisp_csi2.h" #include "atomisp_subdev.h" -#include "atomisp_tpg.h" #include "atomisp_compat.h" #include "gp_device.h" @@ -49,14 +48,13 @@ (((isp)->media_dev.hw_revision & ATOMISP_HW_REVISION_MASK) == \ ((rev) << ATOMISP_HW_REVISION_SHIFT)) -#define ATOMISP_PCI_DEVICE_SOC_MASK 0xfff8 +#define ATOMISP_PCI_DEVICE_SOC_BYT 0x0f38 /* MRFLD with 0x1178: ISP freq can burst to 457MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD 0x1178 /* MRFLD with 0x1179: max ISP freq limited to 400MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD_1179 0x1179 /* MRFLD with 0x117a: max ISP freq is 400MHz and max freq at Vmin is 200MHz */ #define ATOMISP_PCI_DEVICE_SOC_MRFLD_117A 0x117a -#define ATOMISP_PCI_DEVICE_SOC_BYT 0x0f38 #define ATOMISP_PCI_DEVICE_SOC_ANN 0x1478 #define ATOMISP_PCI_DEVICE_SOC_CHT 0x22b8 @@ -123,22 +121,18 @@ round_down((2 * (n) + (d) * (step)) / (2 * (d)), (step)) struct atomisp_input_subdev { - unsigned int type; enum atomisp_camera_port port; u32 code; /* MEDIA_BUS_FMT_* */ bool binning_support; bool crop_support; + bool camera_on; struct v4l2_subdev *camera; + struct v4l2_subdev *csi_port; /* Sensor rects for sensors which support crop */ struct v4l2_rect native_rect; struct v4l2_rect active_rect; /* Sensor state for which == V4L2_SUBDEV_FORMAT_TRY calls */ struct v4l2_subdev_state *try_sd_state; - /* - * To show this resource is used by - * which stream, in ISP multiple stream mode - */ - struct atomisp_sub_device *asd; }; enum atomisp_dfs_mode { @@ -181,7 +175,6 @@ struct atomisp_device { struct media_device media_dev; struct atomisp_sub_device asd; struct v4l2_async_notifier notifier; - struct atomisp_platform_data *pdata; void *mmu_l1_base; void __iomem *base; const struct firmware *firmware; @@ -192,7 +185,6 @@ struct atomisp_device { bool pm_only; struct atomisp_mipi_csi2_device csi2_port[ATOMISP_CAMERA_NR_PORTS]; - struct atomisp_tpg_device tpg; /* Purpose of mutex is to protect and serialize use of isp data * structures and css API calls. */ @@ -206,7 +198,6 @@ struct atomisp_device { struct v4l2_subdev *sensor_subdevs[ATOMISP_CAMERA_NR_PORTS]; unsigned int input_cnt; struct atomisp_input_subdev inputs[ATOM_ISP_MAX_INPUTS]; - struct v4l2_subdev *flash; struct atomisp_regs saved_regs; struct atomisp_css_env css_env; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index fa6c9f0ea6eb79..effc71b5a4397f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -137,15 +137,6 @@ static struct v4l2_queryctrl ci_v4l2_controls[] = { .default_value = 0, }, { - .id = V4L2_CID_REQUEST_FLASH, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Request flash frames", - .minimum = 0, - .maximum = 10, - .step = 1, - .default_value = 1, - }, - { .id = V4L2_CID_ATOMISP_LOW_LIGHT, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Low light mode", @@ -222,12 +213,6 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = { .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY, .description = "UYVY, interleaved" - }, { /* This one is for parallel sensors! DO NOT USE! */ - .pixelformat = V4L2_PIX_FMT_UYVY, - .depth = 16, - .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, - .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY, - .description = "UYVY, interleaved" }, { .pixelformat = V4L2_PIX_FMT_SBGGR16, .depth = 16, @@ -307,12 +292,6 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = { .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, .description = "Bayer 12" }, { - .pixelformat = V4L2_PIX_FMT_RGB32, - .depth = 32, - .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32, - .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888, - .description = "32 RGB 8-8-8-8" - }, { .pixelformat = V4L2_PIX_FMT_RGB565, .depth = 16, .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE, @@ -320,6 +299,17 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = { .description = "16 RGB 5-6-5" #if 0 }, { + /* + * Broken, showing vertical columns with random data. + * For each 128 pixels in a row the last 28 (32?) or so pixels + * contain random data. + */ + .pixelformat = V4L2_PIX_FMT_RGBX32, + .depth = 32, + .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32, + .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888, + .description = "32 RGB 8-8-8-8" + }, { .pixelformat = V4L2_PIX_FMT_JPEG, .depth = 8, .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, @@ -416,7 +406,6 @@ static int atomisp_enum_input(struct file *file, void *fh, input->type = V4L2_INPUT_TYPE_CAMERA; input->index = index; - input->reserved[0] = isp->inputs[index].type; input->reserved[1] = isp->inputs[index].port; return 0; @@ -450,49 +439,23 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input) struct video_device *vdev = video_devdata(file); struct atomisp_device *isp = video_get_drvdata(vdev); struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); - struct atomisp_sub_device *asd = pipe->asd; - struct v4l2_subdev *camera = NULL; int ret; - ret = atomisp_pipe_check(pipe, true); - if (ret) - return ret; - - if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) { - dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt); + if (input >= isp->input_cnt) return -EINVAL; - } - camera = isp->inputs[input].camera; - if (!camera) { - dev_err(isp->dev, "%s, no camera\n", __func__); + if (!isp->inputs[input].camera) return -EINVAL; - } - /* power off the current owned sensor, as it is not used this time */ - if (isp->inputs[asd->input_curr].asd == asd && - asd->input_curr != input) { - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - core, s_power, 0); - if (ret && ret != -ENOIOCTLCMD) - dev_warn(isp->dev, - "Failed to power-off sensor\n"); - /* clear the asd field to show this camera is not used */ - isp->inputs[asd->input_curr].asd = NULL; - } - - /* powe on the new sensor */ - ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1); - if (ret && ret != -ENOIOCTLCMD) { - dev_err(isp->dev, "Failed to power-on sensor\n"); + ret = atomisp_pipe_check(pipe, true); + if (ret) return ret; - } - asd->input_curr = input; - /* mark this camera is used by the current stream */ - isp->inputs[input].asd = asd; + mutex_lock(&isp->media_dev.graph_mutex); + ret = atomisp_select_input(isp, input); + mutex_unlock(&isp->media_dev.graph_mutex); - return 0; + return ret; } /* @@ -862,7 +825,6 @@ static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer { struct video_device *vdev = video_devdata(file); struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); - struct atomisp_sub_device *asd = pipe->asd; struct atomisp_device *isp = video_get_drvdata(vdev); struct ia_css_frame *frame; struct vb2_buffer *vb; @@ -875,15 +837,8 @@ static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer vb = vb2_get_buffer(&pipe->vb_queue, buf->index); frame = vb_to_frame(vb); - buf->reserved = asd->frame_status[buf->index]; - - /* - * Hack: - * Currently frame_status in the enum type which takes no more lower - * 8 bit. - * use bit[31:16] for exp_id as it is only in the range of 1~255 - */ - buf->reserved &= 0x0000ffff; + /* reserved bit[31:16] is used for exp_id */ + buf->reserved = 0; if (!(buf->flags & V4L2_BUF_FLAG_ERROR)) buf->reserved |= frame->exp_id; buf->reserved2 = pipe->frame_config_id[buf->index]; @@ -929,6 +884,20 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) if (ret) goto out_unlock; + /* + * When running a classic v4l2 app after a media-controller aware + * app, the CSI-receiver -> ISP link for the current sensor may be + * disabled. Fix this up before marking the pipeline as started. + */ + mutex_lock(&isp->media_dev.graph_mutex); + atomisp_setup_input_links(isp); + ret = __media_pipeline_start(&asd->video_out.vdev.entity.pads[0], &asd->video_out.pipe); + mutex_unlock(&isp->media_dev.graph_mutex); + if (ret) { + dev_err(isp->dev, "Error starting mc pipline: %d\n", ret); + goto out_unlock; + } + /* Input system HW workaround */ atomisp_dma_burst_len_cfg(asd); @@ -955,9 +924,9 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) spin_lock_irqsave(&isp->lock, irqflags); asd->streaming = true; spin_unlock_irqrestore(&isp->lock, irqflags); - atomic_set(&asd->sof_count, -1); - atomic_set(&asd->sequence, -1); - atomic_set(&asd->sequence_temp, -1); + atomic_set(&asd->sof_count, 0); + atomic_set(&asd->sequence, 0); + atomic_set(&asd->sequence_temp, 0); asd->params.dis_proj_data_valid = false; asd->latest_preview_exp_id = 0; @@ -969,12 +938,6 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) atomisp_qbuffers_to_css(asd); - if (isp->flash) { - asd->params.num_flash_frames = 0; - asd->params.flash_state = ATOMISP_FLASH_IDLE; - atomisp_setup_flash(asd); - } - atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, atomisp_css_valid_sof(isp)); atomisp_csi2_configure(asd); @@ -1052,11 +1015,6 @@ void atomisp_stop_streaming(struct vb2_queue *vq) if (ret) dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret); - if (isp->flash) { - asd->params.num_flash_frames = 0; - asd->params.flash_state = ATOMISP_FLASH_IDLE; - } - /* Disable the CSI interface on ANN B0/K0 */ if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { @@ -1081,6 +1039,7 @@ void atomisp_stop_streaming(struct vb2_queue *vq) if (ret) dev_warn(isp->dev, "Recreating streams failed: %d\n", ret); + media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]); mutex_unlock(&isp->mutex); } @@ -1177,9 +1136,6 @@ static int atomisp_s_ctrl(struct file *file, void *fh, case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION: ret = atomisp_false_color(asd, 1, &control->value); break; - case V4L2_CID_REQUEST_FLASH: - ret = atomisp_flash_enable(asd, control->value); - break; case V4L2_CID_ATOMISP_LOW_LIGHT: ret = atomisp_low_light(asd, 1, &control->value); break; @@ -1224,7 +1180,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh, { struct video_device *vdev = video_devdata(file); struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; - struct atomisp_device *isp = video_get_drvdata(vdev); struct v4l2_control ctrl; int i; int ret = 0; @@ -1233,19 +1188,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh, ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; switch (ctrl.id) { - case V4L2_CID_FLASH_STATUS: - case V4L2_CID_FLASH_INTENSITY: - case V4L2_CID_FLASH_TORCH_INTENSITY: - case V4L2_CID_FLASH_INDICATOR_INTENSITY: - case V4L2_CID_FLASH_TIMEOUT: - case V4L2_CID_FLASH_STROBE: - case V4L2_CID_FLASH_MODE: - case V4L2_CID_FLASH_STATUS_REGISTER: - if (isp->flash) - ret = - v4l2_g_ctrl(isp->flash->ctrl_handler, - &ctrl); - break; case V4L2_CID_ZOOM_ABSOLUTE: ret = atomisp_digital_zoom(asd, 0, &ctrl.value); break; @@ -1295,7 +1237,6 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh, { struct video_device *vdev = video_devdata(file); struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; - struct atomisp_device *isp = video_get_drvdata(vdev); struct v4l2_control ctrl; int i; int ret = 0; @@ -1306,29 +1247,6 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh, ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; switch (ctrl.id) { - case V4L2_CID_FLASH_STATUS: - case V4L2_CID_FLASH_INTENSITY: - case V4L2_CID_FLASH_TORCH_INTENSITY: - case V4L2_CID_FLASH_INDICATOR_INTENSITY: - case V4L2_CID_FLASH_TIMEOUT: - case V4L2_CID_FLASH_STROBE: - case V4L2_CID_FLASH_MODE: - case V4L2_CID_FLASH_STATUS_REGISTER: - if (isp->flash) { - ret = - v4l2_s_ctrl(NULL, isp->flash->ctrl_handler, - &ctrl); - /* - * When flash mode is changed we need to reset - * flash state - */ - if (ctrl.id == V4L2_CID_FLASH_MODE) { - asd->params.flash_state = - ATOMISP_FLASH_IDLE; - asd->params.num_flash_frames = 0; - } - } - break; case V4L2_CID_ZOOM_ABSOLUTE: ret = atomisp_digital_zoom(asd, 1, &ctrl.value); break; diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c index 3b62341acc812b..3a3e84a035e262 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c @@ -149,18 +149,6 @@ static long isp_subdev_ioctl(struct v4l2_subdev *sd, return 0; } -/* - * isp_subdev_set_power - Power on/off the CCDC module - * @sd: ISP V4L2 subdevice - * @on: power on/off - * - * Return 0 on success or a negative error code otherwise. - */ -static int isp_subdev_set_power(struct v4l2_subdev *sd, int on) -{ - return 0; -} - static int isp_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) @@ -362,11 +350,12 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, if (isp_sd->params.video_dis_en && isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - /* This resolution contains 20 % of DVS slack + /* + * This resolution contains 20 % of DVS slack * (of the desired captured image before * scaling, or 1 / 6 of what we get from the - * sensor) in both width and height. Remove - * it. */ + * sensor) in both width and height. Remove it. + */ crop[pad]->width = roundup(crop[pad]->width * 5 / 6, ATOM_ISP_STEP_WIDTH); crop[pad]->height = roundup(crop[pad]->height * 5 / 6, @@ -595,7 +584,7 @@ static int isp_subdev_set_format(struct v4l2_subdev *sd, /* V4L2 subdev core operations */ static const struct v4l2_subdev_core_ops isp_subdev_v4l2_core_ops = { - .ioctl = isp_subdev_ioctl, .s_power = isp_subdev_set_power, + .ioctl = isp_subdev_ioctl, .subscribe_event = isp_subdev_subscribe_event, .unsubscribe_event = isp_subdev_unsubscribe_event, }; @@ -643,7 +632,7 @@ static int atomisp_link_setup(struct media_entity *entity, entity); struct atomisp_sub_device *asd = v4l2_get_subdevdata(sd); struct atomisp_device *isp = asd->isp; - int i, csi_idx, ret; + int i; /* ISP's source is immutable */ if (local != &asd->pads[ATOMISP_SUBDEV_PAD_SINK]) { @@ -652,37 +641,23 @@ static int atomisp_link_setup(struct media_entity *entity, return -EINVAL; } - for (csi_idx = 0; csi_idx < ATOMISP_CAMERA_NR_PORTS; csi_idx++) { - if (&isp->csi2_port[csi_idx].pads[CSI2_PAD_SOURCE] == remote) - break; - } - - if (csi_idx == ATOMISP_CAMERA_NR_PORTS) { - v4l2_err(sd, "Error cannot find CSI receiver for remote pad\n"); - return -EINVAL; - } - - /* Ignore disables, input_curr should only be updated on enables */ - if (!(flags & MEDIA_LNK_FL_ENABLED)) - return 0; - for (i = 0; i < isp->input_cnt; i++) { - if (isp->inputs[i].camera == isp->sensor_subdevs[csi_idx]) + if (&isp->inputs[i].csi_port->entity.pads[CSI2_PAD_SOURCE] == remote) break; } if (i == isp->input_cnt) { - v4l2_err(sd, "Error no sensor for CSI receiver %d\n", csi_idx); + v4l2_err(sd, "Error no sensor for selected CSI receiver\n"); return -EINVAL; } - mutex_lock(&isp->mutex); - ret = atomisp_pipe_check(&asd->video_out, true); - if (ret == 0) - asd->input_curr = i; - mutex_unlock(&isp->mutex); + /* Turn off the sensor on link disable */ + if (!(flags & MEDIA_LNK_FL_ENABLED)) { + atomisp_s_sensor_power(isp, i, 0); + return 0; + } - return ret; + return atomisp_select_input(isp, i); } static const struct media_entity_operations isp_subdev_media_ops = { diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h index 9c1703bf439cf1..b6c66a5d523c37 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h @@ -49,6 +49,7 @@ struct atomisp_video_pipe { struct video_device vdev; enum v4l2_buf_type type; struct media_pad pad; + struct media_pipeline pipe; struct vb2_queue vb_queue; /* Lock for vb_queue, when also taking isp->mutex this must be taken first! */ struct mutex vb_queue_mutex; @@ -107,14 +108,6 @@ struct atomisp_pad_format { struct v4l2_rect compose; }; -/* Internal states for flash process */ -enum atomisp_flash_state { - ATOMISP_FLASH_IDLE, - ATOMISP_FLASH_REQUESTED, - ATOMISP_FLASH_ONGOING, - ATOMISP_FLASH_DONE -}; - /* * This structure is used to cache the CSS parameters, it aligns to * struct ia_css_isp_config but without un-supported and deprecated parts. @@ -220,11 +213,6 @@ struct atomisp_subdev_params { int dvs_ver_proj_bytes; int dvs_hor_proj_bytes; - /* Flash */ - int num_flash_frames; - enum atomisp_flash_state flash_state; - enum atomisp_frame_status last_frame_status; - /* Flag to check if driver needs to update params to css */ bool css_update_params_needed; }; @@ -286,9 +274,6 @@ struct atomisp_sub_device { struct list_head dis_stats_in_css; spinlock_t dis_stats_lock; - struct ia_css_frame *vf_frame; /* TODO: needed? */ - enum atomisp_frame_status frame_status[VIDEO_MAX_FRAME]; - /* This field specifies which camera (v4l2 input) is selected. */ int input_curr; diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp_tpg.c deleted file mode 100644 index 92e61ee9099346..00000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_tpg.c +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Support for Medifield PNW Camera Imaging ISP subsystem. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * Copyright (c) 2010 Silicon Hive www.siliconhive.com. - * - * 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 <media/v4l2-event.h> -#include <media/v4l2-mediabus.h> -#include "atomisp_internal.h" -#include "atomisp_tpg.h" - -static int tpg_s_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - -static int tpg_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - /*to fake*/ - return 0; -} - -static int tpg_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - - if (format->pad) - return -EINVAL; - /* only raw8 grbg is supported by TPG */ - fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_state_get_format(sd_state, 0) = *fmt; - return 0; - } - return 0; -} - -static int tpg_log_status(struct v4l2_subdev *sd) -{ - /*to fake*/ - return 0; -} - -static int tpg_s_power(struct v4l2_subdev *sd, int on) -{ - return 0; -} - -static int tpg_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) -{ - /*to fake*/ - return 0; -} - -static int tpg_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) -{ - /*to fake*/ - return 0; -} - -static int tpg_enum_frame_ival(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval_enum *fie) -{ - /*to fake*/ - return 0; -} - -static const struct v4l2_subdev_video_ops tpg_video_ops = { - .s_stream = tpg_s_stream, -}; - -static const struct v4l2_subdev_core_ops tpg_core_ops = { - .log_status = tpg_log_status, - .s_power = tpg_s_power, -}; - -static const struct v4l2_subdev_pad_ops tpg_pad_ops = { - .enum_mbus_code = tpg_enum_mbus_code, - .enum_frame_size = tpg_enum_frame_size, - .enum_frame_interval = tpg_enum_frame_ival, - .get_fmt = tpg_get_fmt, - .set_fmt = tpg_set_fmt, -}; - -static const struct v4l2_subdev_ops tpg_ops = { - .core = &tpg_core_ops, - .video = &tpg_video_ops, - .pad = &tpg_pad_ops, -}; - -void atomisp_tpg_unregister_entities(struct atomisp_tpg_device *tpg) -{ - media_entity_cleanup(&tpg->sd.entity); - v4l2_device_unregister_subdev(&tpg->sd); -} - -int atomisp_tpg_register_entities(struct atomisp_tpg_device *tpg, - struct v4l2_device *vdev) -{ - int ret; - /* Register the subdev and video nodes. */ - ret = v4l2_device_register_subdev(vdev, &tpg->sd); - if (ret < 0) - goto error; - - return 0; - -error: - atomisp_tpg_unregister_entities(tpg); - return ret; -} - -void atomisp_tpg_cleanup(struct atomisp_device *isp) -{ -} - -int atomisp_tpg_init(struct atomisp_device *isp) -{ - struct atomisp_tpg_device *tpg = &isp->tpg; - struct v4l2_subdev *sd = &tpg->sd; - struct media_pad *pads = tpg->pads; - struct media_entity *me = &sd->entity; - int ret; - - tpg->isp = isp; - v4l2_subdev_init(sd, &tpg_ops); - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - strscpy(sd->name, "tpg_subdev", sizeof(sd->name)); - v4l2_set_subdevdata(sd, tpg); - - pads[0].flags = MEDIA_PAD_FL_SINK; - me->function = MEDIA_ENT_F_PROC_VIDEO_ISP; - - ret = media_entity_pads_init(me, 1, pads); - if (ret < 0) - goto fail; - return 0; -fail: - atomisp_tpg_cleanup(isp); - return ret; -} diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.h b/drivers/staging/media/atomisp/pci/atomisp_tpg.h deleted file mode 100644 index 4176e076f63df7..00000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_tpg.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for Medifield PNW Camera Imaging ISP subsystem. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * Copyright (c) 2010 Silicon Hive www.siliconhive.com. - * - * 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. - * - * - */ - -#ifndef __ATOMISP_TPG_H__ -#define __ATOMISP_TPG_H__ - -#include <media/media-entity.h> -#include <media/v4l2-subdev.h> - -struct atomisp_tpg_device { - struct v4l2_subdev sd; - struct atomisp_device *isp; - struct media_pad pads[1]; -}; - -void atomisp_tpg_cleanup(struct atomisp_device *isp); -int atomisp_tpg_init(struct atomisp_device *isp); -void atomisp_tpg_unregister_entities(struct atomisp_tpg_device *tpg); -int atomisp_tpg_register_entities(struct atomisp_tpg_device *tpg, - struct v4l2_device *vdev); - -#endif /* __ATOMISP_TPG_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 26020be69334a4..9df0eb7044b7a6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -74,13 +74,15 @@ static char firmware_name[256]; module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the default firmware name."); -/*set to 16x16 since this is the amount of lines and pixels the sensor -exports extra. If these are kept at the 10x8 that they were on, in yuv -downscaling modes incorrect resolutions where requested to the sensor -driver with strange outcomes as a result. The proper way tot do this -would be to have a list of tables the specify the sensor res, mipi rec, -output res, and isp output res. however since we do not have this yet, -the chosen solution is the next best thing. */ +/* + * Set to 16x16 since this is the amount of lines and pixels the sensor + * exports extra. If these are kept at the 10x8 that they were on, in yuv + * downscaling modes incorrect resolutions where requested to the sensor + * driver with strange outcomes as a result. The proper way tot do this + * would be to have a list of tables the specify the sensor res, mipi rec, + * output res, and isp output res. however since we do not have this yet, + * the chosen solution is the next best thing. + */ int pad_w = 16; module_param(pad_w, int, 0644); MODULE_PARM_DESC(pad_w, "extra data for ISP processing"); @@ -503,12 +505,12 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp) } done: /* - * MRFLD WORKAROUND: - * before powering off IUNIT, clear the pending interrupts - * and disable the interrupt. driver should avoid writing 0 - * to IIR. It could block subsequent interrupt messages. - * HW sighting:4568410. - */ + * MRFLD WORKAROUND: + * before powering off IUNIT, clear the pending interrupts + * and disable the interrupt. driver should avoid writing 0 + * to IIR. It could block subsequent interrupt messages. + * HW sighting:4568410. + */ pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); irq &= ~BIT(INTR_IER); pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); @@ -521,9 +523,9 @@ done: } /* -* WA for DDR DVFS enable/disable -* By default, ISP will force DDR DVFS 1600MHz before disable DVFS -*/ + * WA for DDR DVFS enable/disable + * By default, ISP will force DDR DVFS 1600MHz before disable DVFS + */ static void punit_ddr_dvfs_enable(bool enable) { int reg; @@ -781,59 +783,38 @@ int atomisp_csi_lane_config(struct atomisp_device *isp) static int atomisp_subdev_probe(struct atomisp_device *isp) { - const struct atomisp_platform_data *pdata; - struct intel_v4l2_subdev_table *subdevs; + const struct intel_v4l2_subdev_table *subdevs; int ret, mipi_port; ret = atomisp_csi2_bridge_parse_firmware(isp); if (ret) return ret; - pdata = atomisp_get_platform_data(); - if (!pdata) { - dev_err(isp->dev, "no platform data available\n"); - return 0; - } - /* * TODO: this is left here for now to allow testing atomisp-sensor * drivers which are still using the atomisp_gmin_platform infra before * converting them to standard v4l2 sensor drivers using runtime-pm + * ACPI for pm and v4l2_async_register_subdev_sensor() registration. */ - for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) { + for (subdevs = atomisp_platform_get_subdevs(); subdevs->subdev; subdevs++) { ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdevs->subdev); if (ret) continue; - switch (subdevs->type) { - case RAW_CAMERA: - if (subdevs->port >= ATOMISP_CAMERA_NR_PORTS) { - dev_err(isp->dev, "port %d not supported\n", subdevs->port); - break; - } - - if (isp->sensor_subdevs[subdevs->port]) { - dev_err(isp->dev, "port %d already has a sensor attached\n", - subdevs->port); - break; - } + if (subdevs->port >= ATOMISP_CAMERA_NR_PORTS) { + dev_err(isp->dev, "port %d not supported\n", subdevs->port); + continue; + } - mipi_port = atomisp_port_to_mipi_port(isp, subdevs->port); - isp->sensor_lanes[mipi_port] = subdevs->lanes; - isp->sensor_subdevs[subdevs->port] = subdevs->subdev; - break; - case LED_FLASH: - if (isp->flash) { - dev_warn(isp->dev, "too many atomisp flash devices\n"); - continue; - } - isp->flash = subdevs->subdev; - break; - default: - dev_dbg(isp->dev, "unknown subdev probed\n"); - break; + if (isp->sensor_subdevs[subdevs->port]) { + dev_err(isp->dev, "port %d already has a sensor attached\n", + subdevs->port); + continue; } + + mipi_port = atomisp_port_to_mipi_port(isp, subdevs->port); + isp->sensor_lanes[mipi_port] = subdevs->lanes; + isp->sensor_subdevs[subdevs->port] = subdevs->subdev; } return atomisp_csi_lane_config(isp); @@ -845,7 +826,6 @@ static void atomisp_unregister_entities(struct atomisp_device *isp) struct v4l2_subdev *sd, *next; atomisp_subdev_unregister_entities(&isp->asd); - atomisp_tpg_unregister_entities(&isp->tpg); for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); @@ -900,12 +880,6 @@ static int atomisp_register_entities(struct atomisp_device *isp) goto csi_and_subdev_probe_failed; } - ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev); - if (ret < 0) { - dev_err(isp->dev, "atomisp_tpg_register_entities\n"); - goto tpg_register_failed; - } - ret = atomisp_subdev_register_subdev(&isp->asd, &isp->v4l2_dev); if (ret < 0) { dev_err(isp->dev, "atomisp_subdev_register_subdev fail\n"); @@ -915,8 +889,6 @@ static int atomisp_register_entities(struct atomisp_device *isp) return 0; subdev_register_failed: - atomisp_tpg_unregister_entities(&isp->tpg); -tpg_register_failed: for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); csi_and_subdev_probe_failed: @@ -1053,9 +1025,9 @@ int atomisp_register_device_nodes(struct atomisp_device *isp) input = &isp->inputs[isp->input_cnt]; - input->type = RAW_CAMERA; input->port = i; input->camera = isp->sensor_subdevs[i]; + input->csi_port = &isp->csi2_port[i].subdev; atomisp_init_sensor(input); @@ -1074,14 +1046,9 @@ int atomisp_register_device_nodes(struct atomisp_device *isp) else dev_info(isp->dev, "detected %d camera sensors\n", isp->input_cnt); - if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) { - dev_dbg(isp->dev, "TPG detected, camera_cnt: %d\n", isp->input_cnt); - isp->inputs[isp->input_cnt].type = TEST_PATTERN; - isp->inputs[isp->input_cnt].port = -1; - isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd; - } else { - dev_warn(isp->dev, "too many atomisp inputs, TPG ignored.\n"); - } + mutex_lock(&isp->media_dev.graph_mutex); + atomisp_setup_input_links(isp); + mutex_unlock(&isp->media_dev.graph_mutex); isp->asd.video_out.vdev.v4l2_dev = &isp->v4l2_dev; isp->asd.video_out.vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; @@ -1112,12 +1079,6 @@ static int atomisp_initialize_modules(struct atomisp_device *isp) goto error_mipi_csi2; } - ret = atomisp_tpg_init(isp); - if (ret < 0) { - dev_err(isp->dev, "tpg initialization failed\n"); - goto error_tpg; - } - ret = atomisp_subdev_init(isp); if (ret < 0) { dev_err(isp->dev, "ISP subdev initialization failed\n"); @@ -1127,8 +1088,6 @@ static int atomisp_initialize_modules(struct atomisp_device *isp) return 0; error_isp_subdev: -error_tpg: - atomisp_tpg_cleanup(isp); error_mipi_csi2: atomisp_mipi_csi2_cleanup(isp); return ret; @@ -1136,7 +1095,6 @@ error_mipi_csi2: static void atomisp_uninitialize_modules(struct atomisp_device *isp) { - atomisp_tpg_cleanup(isp); atomisp_mipi_csi2_cleanup(isp); } @@ -1221,18 +1179,14 @@ static void atomisp_pm_uninit(struct atomisp_device *isp) static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - const struct atomisp_platform_data *pdata; struct atomisp_device *isp; unsigned int start; - int err, val; + u32 val; + int err; /* Pointer to struct device. */ atomisp_dev = &pdev->dev; - pdata = atomisp_get_platform_data(); - if (!pdata) - dev_warn(&pdev->dev, "no platform data available\n"); - start = pci_resource_start(pdev, ATOM_ISP_PCI_BAR); dev_dbg(&pdev->dev, "start: 0x%x\n", start); @@ -1252,8 +1206,10 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i pci_set_drvdata(pdev, isp); - switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { + switch (id->device) { case ATOMISP_PCI_DEVICE_SOC_MRFLD: + case ATOMISP_PCI_DEVICE_SOC_MRFLD_1179: + case ATOMISP_PCI_DEVICE_SOC_MRFLD_117A: isp->media_dev.hw_revision = (ATOMISP_HW_REVISION_ISP2400 << ATOMISP_HW_REVISION_SHIFT) | @@ -1311,7 +1267,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i pdev->d3cold_delay = 0; break; case ATOMISP_PCI_DEVICE_SOC_ANN: - isp->media_dev.hw_revision = ( ATOMISP_HW_REVISION_ISP2401 + isp->media_dev.hw_revision = (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT); isp->media_dev.hw_revision |= pdev->revision < 2 ? ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; @@ -1319,7 +1275,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->hpll_freq = HPLL_FREQ_1600MHZ; break; case ATOMISP_PCI_DEVICE_SOC_CHT: - isp->media_dev.hw_revision = ( ATOMISP_HW_REVISION_ISP2401 + isp->media_dev.hw_revision = (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT); isp->media_dev.hw_revision |= pdev->revision < 2 ? ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0; @@ -1406,28 +1362,25 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i */ atomisp_css2_hw_store_32(MRFLD_CSI_RECEIVER_SELECTION_REG, 1); - if ((id->device & ATOMISP_PCI_DEVICE_SOC_MASK) == - ATOMISP_PCI_DEVICE_SOC_MRFLD) { - u32 csi_afe_trim; - + switch (id->device) { + case ATOMISP_PCI_DEVICE_SOC_MRFLD: + case ATOMISP_PCI_DEVICE_SOC_MRFLD_1179: + case ATOMISP_PCI_DEVICE_SOC_MRFLD_117A: /* * Workaround for imbalance data eye issue which is observed * on TNG B0. */ - pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, &csi_afe_trim); - csi_afe_trim &= ~((MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << - MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | - (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << - MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | - (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << - MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT)); - csi_afe_trim |= (MRFLD_PCI_CSI1_HSRXCLKTRIM << - MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | - (MRFLD_PCI_CSI2_HSRXCLKTRIM << - MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | - (MRFLD_PCI_CSI3_HSRXCLKTRIM << - MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT); - pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, csi_afe_trim); + pci_read_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, &val); + val &= ~((MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | + (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | + (MRFLD_PCI_CSI_HSRXCLKTRIM_MASK << MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT)); + val |= (MRFLD_PCI_CSI1_HSRXCLKTRIM << MRFLD_PCI_CSI1_HSRXCLKTRIM_SHIFT) | + (MRFLD_PCI_CSI2_HSRXCLKTRIM << MRFLD_PCI_CSI2_HSRXCLKTRIM_SHIFT) | + (MRFLD_PCI_CSI3_HSRXCLKTRIM << MRFLD_PCI_CSI3_HSRXCLKTRIM_SHIFT); + pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, val); + break; + default: + break; } err = atomisp_initialize_modules(isp); diff --git a/drivers/staging/media/atomisp/pci/bits.h b/drivers/staging/media/atomisp/pci/bits.h index 9fab02ebddc5df..f7a66287d76388 100644 --- a/drivers/staging/media/atomisp/pci/bits.h +++ b/drivers/staging/media/atomisp/pci/bits.h @@ -16,9 +16,9 @@ #ifndef _HRT_BITS_H #define _HRT_BITS_H -#include "defs.h" +#include <linux/args.h> -#define _hrt_ones(n) HRTCAT(_hrt_ones_, n) +#define _hrt_ones(n) CONCATENATE(_hrt_ones_, n) #define _hrt_ones_0x0 0x00000000U #define _hrt_ones_0x1 0x00000001U #define _hrt_ones_0x2 0x00000003U diff --git a/drivers/staging/media/atomisp/pci/defs.h b/drivers/staging/media/atomisp/pci/defs.h deleted file mode 100644 index 785e7a670a00c4..00000000000000 --- a/drivers/staging/media/atomisp/pci/defs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for Intel Camera Imaging ISP subsystem. - * Copyright (c) 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. - */ - -#ifndef _HRT_DEFS_H_ -#define _HRT_DEFS_H_ - -#ifndef HRTCAT -#define _HRTCAT(m, n) m##n -#define HRTCAT(m, n) _HRTCAT(m, n) -#endif - -#ifndef HRTSTR -#define _HRTSTR(x) #x -#define HRTSTR(x) _HRTSTR(x) -#endif - -#ifndef HRTMIN -#define HRTMIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef HRTMAX -#define HRTMAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#endif /* _HRT_DEFS_H_ */ diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h index 48a1ace79897ca..1a71dbebbbe2cf 100644 --- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h +++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/dma_local.h @@ -19,7 +19,6 @@ #include <type_support.h> #include "dma_global.h" -#include <defs.h> /* HRTCAT() */ #include <bits.h> /* _hrt_get_bits() */ #include <hive_isp_css_defs.h> /* HIVE_DMA_NUM_CHANNELS */ #include <dma_v2_defs.h> diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c index ca1ce66890349a..8f2f4e8eddd9a4 100644 --- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c +++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c @@ -426,7 +426,6 @@ static input_system_err_t input_system_configure_channel( case INPUT_SYSTEM_SOURCE_SENSOR: error = input_system_configure_channel_sensor(channel); break; - case INPUT_SYSTEM_SOURCE_TPG: case INPUT_SYSTEM_SOURCE_PRBS: case INPUT_SYSTEM_SOURCE_FIFO: default: @@ -814,7 +813,6 @@ static input_system_err_t configuration_to_registers(void) //... break; - case INPUT_SYSTEM_SOURCE_TPG: case INPUT_SYSTEM_SOURCE_PRBS: case INPUT_SYSTEM_SOURCE_FIFO: break; @@ -1065,42 +1063,6 @@ input_system_err_t input_system_prbs_channel_cfg( return input_system_configure_channel(channel); } -input_system_err_t input_system_tpg_channel_cfg( - u32 ch_id, - u32 nof_frames,//not used yet - u32 x_mask, - u32 y_mask, - u32 x_delta, - u32 y_delta, - u32 xy_mask, - u32 sync_gen_width, - u32 sync_gen_height, - u32 sync_gen_hblank_cycles, - u32 sync_gen_vblank_cycles, - target_cfg2400_t target -) -{ - channel_cfg_t channel; - - (void)nof_frames; - - channel.ch_id = ch_id; - channel.source_type = INPUT_SYSTEM_SOURCE_TPG; - - channel.source_cfg.tpg_cfg.x_mask = x_mask; - channel.source_cfg.tpg_cfg.y_mask = y_mask; - channel.source_cfg.tpg_cfg.x_delta = x_delta; - channel.source_cfg.tpg_cfg.y_delta = y_delta; - channel.source_cfg.tpg_cfg.xy_mask = xy_mask; - channel.source_cfg.tpg_cfg.sync_gen_cfg.width = sync_gen_width; - channel.source_cfg.tpg_cfg.sync_gen_cfg.height = sync_gen_height; - channel.source_cfg.tpg_cfg.sync_gen_cfg.hblank_cycles = sync_gen_hblank_cycles; - channel.source_cfg.tpg_cfg.sync_gen_cfg.vblank_cycles = sync_gen_vblank_cycles; - - channel.target_cfg = target; - return input_system_configure_channel(channel); -} - // MW: Don't use system specific names, (even in system specific files) "cfg2400" -> cfg input_system_err_t input_system_gpfifo_channel_cfg( u32 ch_id, diff --git a/drivers/staging/media/atomisp/pci/hive_types.h b/drivers/staging/media/atomisp/pci/hive_types.h index 55d36931f07956..34f462c0c9f9e0 100644 --- a/drivers/staging/media/atomisp/pci/hive_types.h +++ b/drivers/staging/media/atomisp/pci/hive_types.h @@ -17,25 +17,6 @@ #define _HRT_HIVE_TYPES_H #include "version.h" -#include "defs.h" - -#ifndef HRTCAT3 -#define _HRTCAT3(m, n, o) m##n##o -#define HRTCAT3(m, n, o) _HRTCAT3(m, n, o) -#endif - -#ifndef HRTCAT4 -#define _HRTCAT4(m, n, o, p) m##n##o##p -#define HRTCAT4(m, n, o, p) _HRTCAT4(m, n, o, p) -#endif - -#ifndef HRTMIN -#define HRTMIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef HRTMAX -#define HRTMAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif /* boolean data type */ typedef unsigned int hive_bool; diff --git a/drivers/staging/media/atomisp/pci/ia_css.h b/drivers/staging/media/atomisp/pci/ia_css.h index d83e1ae5b0b30f..421056287853ed 100644 --- a/drivers/staging/media/atomisp/pci/ia_css.h +++ b/drivers/staging/media/atomisp/pci/ia_css.h @@ -42,7 +42,6 @@ #include "ia_css_properties.h" #include "ia_css_stream_format.h" #include "ia_css_stream_public.h" -#include "ia_css_tpg.h" #include "ia_css_version.h" #include "ia_css_mmu.h" #include "ia_css_morph.h" diff --git a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h index 7ba464abf4470c..a26d9598e40057 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h +++ b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h @@ -137,12 +137,6 @@ enum ia_css_frame_delay { IA_CSS_FRAME_DELAY_2 /** Frame delay = 2 */ }; -enum ia_css_frame_flash_state { - IA_CSS_FRAME_FLASH_STATE_NONE, - IA_CSS_FRAME_FLASH_STATE_PARTIAL, - IA_CSS_FRAME_FLASH_STATE_FULL -}; - /* Frame structure. This structure describes an image buffer or frame. * This is the main structure used for all input and output images. */ @@ -176,7 +170,6 @@ struct ia_css_frame { * binary, we use output port, but we expect VF_OUTPUT_DONE event */ enum ia_css_buffer_type buf_type; - enum ia_css_frame_flash_state flash_state; unsigned int exp_id; /** exposure id, see ia_css_event_public.h for more detail */ u32 isp_config_id; /** Unique ID to track which config was actually applied to a particular frame */ @@ -202,7 +195,6 @@ struct ia_css_frame { .frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ .dynamic_queue_id = SH_CSS_INVALID_QUEUE_ID, \ .buf_type = IA_CSS_BUFFER_TYPE_INVALID, \ - .flash_state = IA_CSS_FRAME_FLASH_STATE_NONE, \ } /* @brief Allocate a CSS frame structure diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h index 47846ece8d6408..961c612880833a 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h +++ b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h @@ -24,7 +24,6 @@ #include "ia_css_types.h" #include "ia_css_pipe_public.h" #include "ia_css_metadata.h" -#include "ia_css_tpg.h" #include "ia_css_prbs.h" #include "ia_css_input_port.h" @@ -34,7 +33,6 @@ enum ia_css_input_mode { IA_CSS_INPUT_MODE_SENSOR, /** data from sensor */ IA_CSS_INPUT_MODE_FIFO, /** data from input-fifo */ - IA_CSS_INPUT_MODE_TPG, /** data from test-pattern generator */ IA_CSS_INPUT_MODE_PRBS, /** data from pseudo-random bit stream */ IA_CSS_INPUT_MODE_MEMORY, /** data from a frame in memory */ IA_CSS_INPUT_MODE_BUFFERED_SENSOR /** data is sent through mipi buffer */ @@ -91,7 +89,6 @@ struct ia_css_stream_config { enum ia_css_input_mode mode; /** Input mode */ union { struct ia_css_input_port port; /** Port, for sensor only. */ - struct ia_css_tpg_config tpg; /** TPG configuration */ struct ia_css_prbs_config prbs; /** PRBS configuration */ } source; /** Source of input data */ unsigned int channel_id; /** Channel on which input data @@ -460,20 +457,6 @@ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream, void ia_css_stream_end_input_frame(const struct ia_css_stream *stream); -/* @brief send a request flash command to SP - * - * @param[in] stream The stream. - * @return None - * - * Driver needs to call this function to send a flash request command - * to SP, SP will be responsible for switching on/off the flash at proper - * time. Due to the SP multi-threading environment, this request may have - * one-frame delay, the driver needs to check the flashed flag in frame info - * to determine which frame is being flashed. - */ -void -ia_css_stream_request_flash(struct ia_css_stream *stream); - /* @brief Configure a stream with filter coefficients. * @deprecated {Replaced by * ia_css_pipe_set_isp_config_on_pipe()} diff --git a/drivers/staging/media/atomisp/pci/ia_css_tpg.h b/drivers/staging/media/atomisp/pci/ia_css_tpg.h deleted file mode 100644 index 8c744bedb0a601..00000000000000 --- a/drivers/staging/media/atomisp/pci/ia_css_tpg.h +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for Intel Camera Imaging ISP subsystem. - * Copyright (c) 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. - */ - -#ifndef __IA_CSS_TPG_H -#define __IA_CSS_TPG_H - -/* @file - * This file contains support for the test pattern generator (TPG) - */ - -/* Enumerate the TPG IDs. - */ -enum ia_css_tpg_id { - IA_CSS_TPG_ID0, - IA_CSS_TPG_ID1, - IA_CSS_TPG_ID2 -}; - -/** - * Maximum number of TPG IDs. - * - * Make sure the value of this define gets changed to reflect the correct - * number of ia_css_tpg_id enum if you add/delete an item in the enum. - */ -#define N_CSS_TPG_IDS (IA_CSS_TPG_ID2 + 1) - -/* Enumerate the TPG modes. - */ -enum ia_css_tpg_mode { - IA_CSS_TPG_MODE_RAMP, - IA_CSS_TPG_MODE_CHECKERBOARD, - IA_CSS_TPG_MODE_FRAME_BASED_COLOR, - IA_CSS_TPG_MODE_MONO -}; - -/* @brief Configure the test pattern generator. - * - * Configure the Test Pattern Generator, the way these values are used to - * generate the pattern can be seen in the HRT extension for the test pattern - * generator: - * devices/test_pat_gen/hrt/include/test_pat_gen.h: hrt_calc_tpg_data(). - * - * This interface is deprecated, it is not portable -> move to input system API - * -@code -unsigned int test_pattern_value(unsigned int x, unsigned int y) -{ - unsigned int x_val, y_val; - if (x_delta > 0) (x_val = (x << x_delta) & x_mask; - else (x_val = (x >> -x_delta) & x_mask; - if (y_delta > 0) (y_val = (y << y_delta) & y_mask; - else (y_val = (y >> -y_delta) & x_mask; - return (x_val + y_val) & xy_mask; -} -@endcode - */ -struct ia_css_tpg_config { - enum ia_css_tpg_id id; - enum ia_css_tpg_mode mode; - unsigned int x_mask; - int x_delta; - unsigned int y_mask; - int y_delta; - unsigned int xy_mask; -}; - -#endif /* __IA_CSS_TPG_H */ diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h index 3ff61faf0621a9..c00acf764b93ae 100644 --- a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h +++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h @@ -35,7 +35,6 @@ typedef enum { typedef enum { INPUT_SYSTEM_SOURCE_SENSOR = 0, INPUT_SYSTEM_SOURCE_FIFO, - INPUT_SYSTEM_SOURCE_TPG, INPUT_SYSTEM_SOURCE_PRBS, INPUT_SYSTEM_SOURCE_MEMORY, N_INPUT_SYSTEM_SOURCE diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h index 523c948923f315..03b7ab7a70d9b6 100644 --- a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h +++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h @@ -308,21 +308,6 @@ input_system_err_t input_system_prbs_channel_cfg( target_cfg2400_t target ); -input_system_err_t input_system_tpg_channel_cfg( - u32 ch_id, - u32 nof_frames,//not used yet - u32 x_mask, - u32 y_mask, - u32 x_delta, - u32 y_delta, - u32 xy_mask, - u32 sync_gen_width, - u32 sync_gen_height, - u32 sync_gen_hblank_cycles, - u32 sync_gen_vblank_cycles, - target_cfg2400_t target -); - input_system_err_t input_system_gpfifo_channel_cfg( u32 ch_id, u32 nof_frames, diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h index e3c86069b390c1..b116be41507458 100644 --- a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h +++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h @@ -39,7 +39,6 @@ typedef enum { INPUT_SYSTEM_SOURCE_TYPE_UNDEFINED = 0, INPUT_SYSTEM_SOURCE_TYPE_SENSOR, - INPUT_SYSTEM_SOURCE_TYPE_TPG, INPUT_SYSTEM_SOURCE_TYPE_PRBS, N_INPUT_SYSTEM_SOURCE_TYPE } input_system_source_type_t; diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c index 3e92794555ec7d..9982e77716a7f7 100644 --- a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c +++ b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c @@ -31,6 +31,7 @@ #define __INLINE_STREAM2MMIO__ #endif +#include <linux/args.h> #include <linux/string.h> /* for strscpy() */ #include "ia_css_debug.h" @@ -861,7 +862,7 @@ void ia_css_debug_wake_up_sp(void) } #define FIND_DMEM_PARAMS_TYPE(stream, kernel, type) \ - (struct HRTCAT(HRTCAT(sh_css_isp_, type), _params) *) \ + (struct CONCATENATE(CONCATENATE(sh_css_isp_, type), _params) *) \ findf_dmem_params(stream, offsetof(struct ia_css_memory_offsets, dmem.kernel)) #define FIND_DMEM_PARAMS(stream, kernel) FIND_DMEM_PARAMS_TYPE(stream, kernel, kernel) @@ -1548,23 +1549,6 @@ ia_css_debug_dump_stream_config_source( ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "compression: %d\n", config->source.port.compression.type); break; - case IA_CSS_INPUT_MODE_TPG: - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "source.tpg\n"); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "id: %d\n", - config->source.tpg.id); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "mode: %d\n", - config->source.tpg.mode); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "x_mask: 0x%x\n", - config->source.tpg.x_mask); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "x_delta: %d\n", - config->source.tpg.x_delta); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "y_mask: 0x%x\n", - config->source.tpg.y_mask); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "y_delta: %d\n", - config->source.tpg.y_delta); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "xy_mask: 0x%x\n", - config->source.tpg.xy_mask); - break; case IA_CSS_INPUT_MODE_PRBS: ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "source.prbs\n"); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "id: %d\n", diff --git a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c index 86254888f676aa..7b5603e4e1730d 100644 --- a/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c +++ b/drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c @@ -382,17 +382,6 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, vectors_per_buffer = buffer_height * buffer_width / ISP_VEC_NELEMS; - if (config->mode == IA_CSS_INPUT_MODE_TPG && - ((binary && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO) || - (!binary))) { - /* !binary -> sp raw copy pipe */ - /* workaround for TPG in video mode */ - start_line = 0; - start_column = 0; - cropped_height -= start_line; - width_a -= start_column; - } - if_a_config.start_line = start_line; if_a_config.start_column = start_column; if_a_config.left_padding = left_padding / deinterleaving; diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c index 269a8119057782..52483498239d2d 100644 --- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c +++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c @@ -96,12 +96,6 @@ static void release_be_lut_entry( csi_mipi_packet_type_t packet_type, csi_rx_backend_lut_entry_t *entry); -static bool calculate_tpg_cfg( - input_system_channel_t *channel, - input_system_input_port_t *input_port, - isp2401_input_system_cfg_t *isys_cfg, - pixelgen_tpg_cfg_t *cfg); - static bool calculate_prbs_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, @@ -517,13 +511,6 @@ static bool calculate_input_system_input_port_cfg( rc &= calculate_be_cfg(input_port, isys_cfg, true, &input_port_cfg->csi_rx_cfg.md_backend_cfg); break; - case INPUT_SYSTEM_SOURCE_TYPE_TPG: - rc = calculate_tpg_cfg( - channel, - input_port, - isys_cfg, - &input_port_cfg->pixelgen_cfg.tpg_cfg); - break; case INPUT_SYSTEM_SOURCE_TYPE_PRBS: rc = calculate_prbs_cfg( channel, @@ -633,17 +620,6 @@ static void release_be_lut_entry( ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry); } -static bool calculate_tpg_cfg( - input_system_channel_t *channel, - input_system_input_port_t *input_port, - isp2401_input_system_cfg_t *isys_cfg, - pixelgen_tpg_cfg_t *cfg) -{ - memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t)); - - return true; -} - static bool calculate_prbs_cfg( input_system_channel_t *channel, input_system_input_port_t *input_port, @@ -703,9 +679,7 @@ static bool calculate_stream2mmio_cfg( cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel : isys_cfg->input_port_resolution.bits_per_pixel; - cfg->enable_blocking = - ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) || - (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS)); + cfg->enable_blocking = isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS; return true; } diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 8c30191b21a771..42a69b26db013f 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -462,9 +462,6 @@ ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream) return bpp; } -/* TODO: move define to proper file in tools */ -#define GP_ISEL_TPG_MODE 0x90058 - static int sh_css_config_input_network_2400(struct ia_css_stream *stream) { @@ -500,21 +497,16 @@ sh_css_config_input_network_2400(struct ia_css_stream *stream) return err; } - if (stream->config.mode == IA_CSS_INPUT_MODE_TPG || - stream->config.mode == IA_CSS_INPUT_MODE_PRBS) { - unsigned int hblank_cycles = 100, - vblank_lines = 6, - width, - height, - vblank_cycles; - width = (stream->config.input_config.input_res.width) / (1 + - (stream->config.pixels_per_clock == 2)); + if (stream->config.mode == IA_CSS_INPUT_MODE_PRBS) { + unsigned int width, height, vblank_cycles; + const unsigned int hblank_cycles = 100; + const unsigned int vblank_lines = 6; + + width = (stream->config.input_config.input_res.width) / + (1 + (stream->config.pixels_per_clock == 2)); height = stream->config.input_config.input_res.height; vblank_cycles = vblank_lines * (width + hblank_cycles); - sh_css_sp_configure_sync_gen(width, height, hblank_cycles, - vblank_cycles); - if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) - ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0); + sh_css_sp_configure_sync_gen(width, height, hblank_cycles, vblank_cycles); } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_config_input_network() leave:\n"); @@ -654,16 +646,6 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_id( rc = true; switch (stream_cfg->mode) { - case IA_CSS_INPUT_MODE_TPG: - - if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) - isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID; - else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) - isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID; - else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) - isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID; - - break; case IA_CSS_INPUT_MODE_PRBS: if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) @@ -700,11 +682,6 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_type( rc = true; switch (stream_cfg->mode) { - case IA_CSS_INPUT_MODE_TPG: - - isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_TPG; - - break; case IA_CSS_INPUT_MODE_PRBS: isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_PRBS; @@ -733,54 +710,6 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr( rc = true; switch (stream_cfg->mode) { - case IA_CSS_INPUT_MODE_TPG: - if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) - isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP; - else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) - isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO; - else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) - isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO; - else - rc = false; - - /* - * TODO - * - Make "color_cfg" as part of "ia_css_tpg_config". - */ - isys_stream_descr->tpg_port_attr.color_cfg.R1 = 51; - isys_stream_descr->tpg_port_attr.color_cfg.G1 = 102; - isys_stream_descr->tpg_port_attr.color_cfg.B1 = 255; - isys_stream_descr->tpg_port_attr.color_cfg.R2 = 0; - isys_stream_descr->tpg_port_attr.color_cfg.G2 = 100; - isys_stream_descr->tpg_port_attr.color_cfg.B2 = 160; - - isys_stream_descr->tpg_port_attr.mask_cfg.h_mask = - stream_cfg->source.tpg.x_mask; - isys_stream_descr->tpg_port_attr.mask_cfg.v_mask = - stream_cfg->source.tpg.y_mask; - isys_stream_descr->tpg_port_attr.mask_cfg.hv_mask = - stream_cfg->source.tpg.xy_mask; - - isys_stream_descr->tpg_port_attr.delta_cfg.h_delta = - stream_cfg->source.tpg.x_delta; - isys_stream_descr->tpg_port_attr.delta_cfg.v_delta = - stream_cfg->source.tpg.y_delta; - - /* - * TODO - * - Make "sync_gen_cfg" as part of "ia_css_tpg_config". - */ - isys_stream_descr->tpg_port_attr.sync_gen_cfg.hblank_cycles = 100; - isys_stream_descr->tpg_port_attr.sync_gen_cfg.vblank_cycles = 100; - isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_clock = - stream_cfg->pixels_per_clock; - isys_stream_descr->tpg_port_attr.sync_gen_cfg.nr_of_frames = (uint32_t)~(0x0); - isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_line = - stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.width; - isys_stream_descr->tpg_port_attr.sync_gen_cfg.lines_per_frame = - stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.height; - - break; case IA_CSS_INPUT_MODE_PRBS: isys_stream_descr->prbs_port_attr.seed0 = stream_cfg->source.prbs.seed; @@ -2903,7 +2832,6 @@ init_vf_frameinfo_defaults(struct ia_css_pipe *pipe, assert(vf_frame); sh_css_pipe_get_viewfinder_frame_info(pipe, &vf_frame->frame_info, idx); - vf_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx, thread_id, &queue_id); vf_frame->dynamic_queue_id = queue_id; @@ -3081,7 +3009,6 @@ init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe, in_frame->frame_info.raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); ia_css_frame_info_set_width(&in_frame->frame_info, pipe->stream->config.input_config.input_res.width, 0); - in_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_INPUT_FRAME, thread_id, &queue_id); in_frame->dynamic_queue_id = queue_id; @@ -3109,7 +3036,6 @@ init_out_frameinfo_defaults(struct ia_css_pipe *pipe, assert(out_frame); sh_css_pipe_get_output_frame_info(pipe, &out_frame->frame_info, idx); - out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx, thread_id, &queue_id); out_frame->dynamic_queue_id = queue_id; @@ -3890,12 +3816,6 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, buffer->exp_id = ddr_buffer.payload.frame.exp_id; frame->exp_id = ddr_buffer.payload.frame.exp_id; frame->isp_config_id = ddr_buffer.payload.frame.isp_parameters_id; - if (ddr_buffer.payload.frame.flashed == 1) - frame->flash_state = - IA_CSS_FRAME_FLASH_STATE_PARTIAL; - if (ddr_buffer.payload.frame.flashed == 2) - frame->flash_state = - IA_CSS_FRAME_FLASH_STATE_FULL; frame->valid = pipe->num_invalid_frames == 0; if (!frame->valid) pipe->num_invalid_frames--; @@ -6857,8 +6777,6 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe, ia_css_pipeline_clean(me); /* Construct out_frame info */ - out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; - if (copy_on_sp(pipe) && pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) { ia_css_frame_info_init(&out_frame->frame_info, JPEG_BYTES, 1, @@ -6906,7 +6824,6 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) err = sh_css_pipe_get_output_frame_info(pipe, &out_frame->frame_info, 0); if (err) return err; - out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id, &queue_id); out_frame->dynamic_queue_id = queue_id; @@ -7561,27 +7478,6 @@ int ia_css_stream_capture(struct ia_css_stream *stream, int num_captures, return return_err; } -void ia_css_stream_request_flash(struct ia_css_stream *stream) -{ - (void)stream; - - assert(stream); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, - "ia_css_stream_request_flash() enter: void\n"); - - if (!IS_ISP2401 || sh_css_sp_is_running()) { - if (!sh_css_write_host2sp_command(host2sp_cmd_start_flash) && IS_ISP2401) { - IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed"); - ia_css_debug_dump_sp_sw_debug_info(); - } - } else { - IA_CSS_LOG("SP is not running!"); - } - - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, - "ia_css_stream_request_flash() leave: return_void\n"); -} - static void sh_css_init_host_sp_control_vars(void) { @@ -8153,23 +8049,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, if (!IS_ISP2401) ia_css_stream_configure_rx(curr_stream); break; - case IA_CSS_INPUT_MODE_TPG: - if (!IS_ISP2401) { - IA_CSS_LOG("tpg_configuration: x_mask=%d, y_mask=%d, x_delta=%d, y_delta=%d, xy_mask=%d", - curr_stream->config.source.tpg.x_mask, - curr_stream->config.source.tpg.y_mask, - curr_stream->config.source.tpg.x_delta, - curr_stream->config.source.tpg.y_delta, - curr_stream->config.source.tpg.xy_mask); - - sh_css_sp_configure_tpg( - curr_stream->config.source.tpg.x_mask, - curr_stream->config.source.tpg.y_mask, - curr_stream->config.source.tpg.x_delta, - curr_stream->config.source.tpg.y_delta, - curr_stream->config.source.tpg.xy_mask); - } - break; case IA_CSS_INPUT_MODE_PRBS: if (!IS_ISP2401) { IA_CSS_LOG("mode prbs"); diff --git a/drivers/staging/media/atomisp/pci/sh_css_internal.h b/drivers/staging/media/atomisp/pci/sh_css_internal.h index 2349eb4d3767e7..bef2b8c5132baf 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_internal.h +++ b/drivers/staging/media/atomisp/pci/sh_css_internal.h @@ -360,7 +360,6 @@ struct sh_css_sp_config { } input_formatter; sync_generator_cfg_t sync_gen; - tpg_cfg_t tpg; prbs_cfg_t prbs; input_system_cfg_t input_circuit; u8 input_circuit_cfg_changed; diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c index 6e11fd7719384c..80f0395cc560ed 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c +++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c @@ -489,7 +489,7 @@ free_mipi_frames(struct ia_css_pipe *pipe) } } else { /* pipe ==NULL */ /* AM TEMP: free-ing all mipi buffers just like a legacy code. */ - for (port = CSI_PORT0_ID; port < N_CSI_PORTS; port++) { + for (port = 0; port < N_CSI_PORTS; port++) { unsigned int i; for (i = 0; i < my_css.num_mipi_frames[port]; i++) { diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.c b/drivers/staging/media/atomisp/pci/sh_css_sp.c index cd7f5a3fecaa68..29e5bee78c204a 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_sp.c +++ b/drivers/staging/media/atomisp/pci/sh_css_sp.c @@ -108,11 +108,6 @@ copy_isp_stage_to_sp_stage(void) sh_css_isp_stage.binary_info.iterator.row_stripes_overlap_lines; sh_css_sp_stage.top_cropping = (uint16_t) sh_css_isp_stage.binary_info.pipeline.top_cropping; - /* moved to sh_css_sp_init_stage - sh_css_sp_stage.enable.vf_output = - sh_css_isp_stage.binary_info.enable.vf_veceven || - sh_css_isp_stage.binary_info.num_output_pins > 1; - */ sh_css_sp_stage.enable.sdis = sh_css_isp_stage.binary_info.enable.dis; sh_css_sp_stage.enable.s3a = sh_css_isp_stage.binary_info.enable.s3a; } @@ -187,7 +182,7 @@ sh_css_sp_get_debug_state(struct sh_css_sp_debug_state *state) (void)HIVE_ADDR_sp_output; /* To get rid of warning in CRUN */ for (i = 0; i < sizeof(*state) / sizeof(int); i++) - ((unsigned *)state)[i] = load_sp_array_uint(sp_output, i + offset); + ((unsigned int *)state)[i] = load_sp_array_uint(sp_output, i + offset); } #endif @@ -411,18 +406,18 @@ sh_css_copy_buffer_attr_to_spbuffer(struct ia_css_buffer_sp *dest_buf, */ assert(queue_id < SH_CSS_MAX_NUM_QUEUES); - /* Klocwork assumes assert can be disabled; - Since we can get there with any type, and it does not - know that frame_in->dynamic_data_index can only be set - for one of the types in the assert) it has to assume we - can get here for any type. however this could lead to an - out of bounds reference when indexing buf_type about 10 - lines below. In order to satisfy KW an additional if - has been added. This one will always yield true. + /* + * Klocwork assumes assert can be disabled; + * Since we can get there with any type, and it does not + * know that frame_in->dynamic_data_index can only be set + * for one of the types in the assert) it has to assume we + * can get here for any type. however this could lead to an + * out of bounds reference when indexing buf_type about 10 + * lines below. In order to satisfy KW an additional if + * has been added. This one will always yield true. */ - if ((queue_id < SH_CSS_MAX_NUM_QUEUES)) { + if (queue_id < SH_CSS_MAX_NUM_QUEUES) dest_buf->buf_src.queue_id = queue_id; - } } else { assert(xmem_addr != mmgr_EXCEPTION); dest_buf->buf_src.xmem_addr = xmem_addr; @@ -515,7 +510,8 @@ sh_css_copy_frame_to_spframe(struct ia_css_frame_sp *sp_frame_out, frame_in->planes.binary.data.offset; break; default: - /* This should not happen, but in case it does, + /* + * This should not happen, but in case it does, * nullify the planes */ memset(&sp_frame_out->planes, 0, sizeof(sp_frame_out->planes)); @@ -643,8 +639,6 @@ void sh_css_sp_set_if_configs( *config_b; sh_css_sp_group.config.input_formatter.b_changed = true; } - - return; } void @@ -676,20 +670,6 @@ sh_css_sp_configure_sync_gen(int width, int height, } void -sh_css_sp_configure_tpg(int x_mask, - int y_mask, - int x_delta, - int y_delta, - int xy_mask) -{ - sh_css_sp_group.config.tpg.x_mask = x_mask; - sh_css_sp_group.config.tpg.y_mask = y_mask; - sh_css_sp_group.config.tpg.x_delta = x_delta; - sh_css_sp_group.config.tpg.y_delta = y_delta; - sh_css_sp_group.config.tpg.xy_mask = xy_mask; -} - -void sh_css_sp_configure_prbs(int seed) { sh_css_sp_group.config.prbs.seed = seed; @@ -733,7 +713,8 @@ sh_css_sp_write_frame_pointers(const struct sh_css_binary_args *args) /* we don't pass this error back to the upper layer, so we add a assert here because we actually hit the error here but it still works by accident... */ - if (err) assert(false); + if (err) + assert(false); return err; } @@ -748,7 +729,8 @@ sh_css_sp_init_group(bool two_ppc, sh_css_sp_group.config.no_isp_sync = (uint8_t)no_isp_sync; /* decide whether the frame is processed online or offline */ - if (if_config_index == SH_CSS_IF_CONFIG_NOT_NEEDED) return; + if (if_config_index == SH_CSS_IF_CONFIG_NOT_NEEDED) + return; if (!IS_ISP2401) { assert(if_config_index < SH_CSS_MAX_IF_CONFIGS); @@ -860,9 +842,9 @@ initialize_isp_states(const struct ia_css_binary *binary) if (!binary->info->mem_offsets.offsets.state) return; - for (i = 0; i < IA_CSS_NUM_STATE_IDS; i++) { + + for (i = 0; i < IA_CSS_NUM_STATE_IDS; i++) ia_css_kernel_init_state[i](binary); - } } static void @@ -878,9 +860,9 @@ initialize_stage_frames(struct ia_css_frames_sp *frames) unsigned int i; initialize_frame_buffer_attribute(&frames->in.buf_attr); - for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) initialize_frame_buffer_attribute(&frames->out[i].buf_attr); - } + initialize_frame_buffer_attribute(&frames->out_vf.buf_attr); initialize_frame_buffer_attribute(&frames->s3a_buf); initialize_frame_buffer_attribute(&frames->dvs_buf); @@ -952,9 +934,10 @@ sh_css_sp_init_stage(struct ia_css_binary *binary, sh_css_sp_stage.isp_copy_output = (uint8_t)args->copy_output; sh_css_sp_stage.enable.vf_output = (args->out_vf_frame != NULL); - /* Copy the frame infos first, to be overwritten by the frames, - if these are present. - */ + /* + * Copy the frame infos first, to be overwritten by the frames, + * if these are present. + */ sh_css_sp_stage.frames.effective_in_res.width = binary->effective_in_frame_res.width; sh_css_sp_stage.frames.effective_in_res.height = binary->effective_in_frame_res.height; @@ -1031,10 +1014,12 @@ sh_css_sp_init_stage(struct ia_css_binary *binary, initialize_isp_states(binary); - /* we do this only for preview pipe because in fill_binary_info function + /* + * We do this only for preview pipe because in fill_binary_info function * we assign vf_out res to out res, but for ISP internal processing, we need * the original out res. for video pipe, it has two output pins --- out and - * vf_out, so it can keep these two resolutions already. */ + * vf_out, so it can keep these two resolutions already. + */ if (binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW && (binary->vf_downscale_log2 > 0)) { /* TODO: Remove this after preview output decimation is fixed @@ -1070,20 +1055,23 @@ sp_init_stage(struct ia_css_pipeline_stage *stage, */ const char *binary_name = ""; const struct ia_css_binary_xinfo *info = NULL; - /* note: the var below is made static as it is quite large; - if it is not static it ends up on the stack which could - cause issues for drivers - */ + /* + * Note: the var below is made static as it is quite large; + * if it is not static it ends up on the stack which could + * cause issues for drivers + */ static struct ia_css_binary tmp_binary; const struct ia_css_blob_info *blob_info = NULL; struct ia_css_isp_param_css_segments isp_mem_if; - /* LA: should be ia_css_data, should not contain host pointer. - However, CSS/DDR pointer is not available yet. - Hack is to store it in params->ddr_ptrs and then copy it late in the SP just before vmem init. - TODO: Call this after CSS/DDR allocation and store that pointer. - Best is to allocate it at stage creation time together with host pointer. - Remove vmem from params. - */ + /* + * LA: should be ia_css_data, should not contain host pointer. + * However, CSS/DDR pointer is not available yet. + * Hack is to store it in params->ddr_ptrs and then copy it late in + * the SP just before vmem init. + * TODO: Call this after CSS/DDR allocation and store that pointer. + * Best is to allocate it at stage creation time together with host + * pointer. Remove vmem from params. + */ struct ia_css_isp_param_css_segments *mem_if = &isp_mem_if; int err = 0; @@ -1123,10 +1111,12 @@ sp_init_stage(struct ia_css_pipeline_stage *stage, } else { /* SP stage */ assert(stage->sp_func != IA_CSS_PIPELINE_NO_FUNC); - /* binary and blob_info are now NULL. - These will be passed to sh_css_sp_init_stage - and dereferenced there, so passing a NULL - pointer is no good. return an error */ + /* + * binary and blob_info are now NULL. + * These will be passed to sh_css_sp_init_stage + * and dereferenced there, so passing a NULL + * pointer is no good. return an error + */ return -EINVAL; } @@ -1260,8 +1250,10 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me, SH_CSS_PIPE_CONFIG_SAMPLE_PARAMS << thread_id; } - /* For continuous use-cases, SP copy is responsible for sampling the - * parameters */ + /* + * For continuous use-cases, SP copy is responsible for sampling the + * parameters + */ if (continuous) sh_css_sp_group.pipe[thread_id].pipe_config = 0; @@ -1269,9 +1261,9 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me, pipe = find_pipe_by_num(pipe_num); assert(pipe); - if (!pipe) { + if (!pipe) return; - } + sh_css_sp_group.pipe[thread_id].scaler_pp_lut = sh_css_pipe_get_pp_gdc_lut(pipe); if (md_info && md_info->size > 0) { @@ -1543,7 +1535,8 @@ ia_css_pipe_set_irq_mask(struct ia_css_pipe *pipe, assert(pipe); assert(IA_CSS_PIPE_ID_NUM == NR_OF_PIPELINES); - /* Linux kernel does not have UINT16_MAX + /* + * Linux kernel does not have UINT16_MAX * Therefore decided to comment out these 2 asserts for Linux * Alternatives that were not chosen: * - add a conditional #define for UINT16_MAX @@ -1642,7 +1635,8 @@ sh_css_sp_start_isp(void) (unsigned int)sp_address_of(sp_sw_state), (uint32_t)(IA_CSS_SP_SW_TERMINATED)); - /* Note 1: The sp_start_isp function contains a wait till + /* + * Note 1: The sp_start_isp function contains a wait till * the input network is configured by the SP. * Note 2: Not all SP binaries supports host2sp_commands. * In case a binary does support it, the host2sp_command @@ -1652,7 +1646,8 @@ sh_css_sp_start_isp(void) * received, the SP starts configuring the input network. */ - /* we need to set sp_running before we call ia_css_mmu_invalidate_cache + /* + * We need to set sp_running before we call ia_css_mmu_invalidate_cache * as ia_css_mmu_invalidate_cache checks on sp_running to * avoid that it accesses dmem while the SP is not powered */ diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.h b/drivers/staging/media/atomisp/pci/sh_css_sp.h index 36b693bd916a50..c12f57f5befc84 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_sp.h +++ b/drivers/staging/media/atomisp/pci/sh_css_sp.h @@ -165,13 +165,6 @@ sh_css_sp_configure_sync_gen(int width, int vblank_cycles); void -sh_css_sp_configure_tpg(int x_mask, - int y_mask, - int x_delta, - int y_delta, - int xy_mask); - -void sh_css_sp_configure_prbs(int seed); void diff --git a/drivers/staging/media/atomisp/pci/system_global.h b/drivers/staging/media/atomisp/pci/system_global.h index 060b924023ec09..e8a29f73d67a7f 100644 --- a/drivers/staging/media/atomisp/pci/system_global.h +++ b/drivers/staging/media/atomisp/pci/system_global.h @@ -201,18 +201,6 @@ enum mipi_port_id { #define N_RX_CHANNEL_ID 4 -/* Generic port enumeration with an internal port type ID */ -typedef enum { - CSI_PORT0_ID = 0, - CSI_PORT1_ID, - CSI_PORT2_ID, - TPG_PORT0_ID, - PRBS_PORT0_ID, - FIFO_PORT0_ID, - MEMORY_PORT0_ID, - N_INPUT_PORT_ID -} input_port_ID_t; - typedef enum { CAPTURE_UNIT0_ID = 0, CAPTURE_UNIT1_ID, diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.c b/drivers/staging/media/ipu3/ipu3-css-fw.c index 2b659b0ccca14d..37482b626c3ce8 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.c +++ b/drivers/staging/media/ipu3/ipu3-css-fw.c @@ -117,7 +117,9 @@ int imgu_css_fw_init(struct imgu_css *css) unsigned int i, j, binary_nr; int r; - r = request_firmware(&css->fw, IMGU_FW_NAME_20161208, css->dev); + r = request_firmware(&css->fw, IMGU_FW_NAME_IPU_20161208, css->dev); + if (r == -ENOENT) + r = request_firmware(&css->fw, IMGU_FW_NAME_20161208, css->dev); if (r == -ENOENT) r = request_firmware(&css->fw, IMGU_FW_NAME, css->dev); if (r) diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.h b/drivers/staging/media/ipu3/ipu3-css-fw.h index f9403da7578513..c956aa21df25d1 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.h +++ b/drivers/staging/media/ipu3/ipu3-css-fw.h @@ -9,6 +9,8 @@ #define IMGU_FW_NAME "intel/ipu3-fw.bin" #define IMGU_FW_NAME_20161208 \ "intel/irci_irci_ecr-master_20161208_0213_20170112_1500.bin" +#define IMGU_FW_NAME_IPU_20161208 \ + "intel/ipu/irci_irci_ecr-master_20161208_0213_20170112_1500.bin" typedef u32 imgu_fw_ptr; diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 9bd326d3118129..f26c323e9c9630 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -310,7 +310,9 @@ void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier); * * @sd: pointer to &struct v4l2_subdev */ -int v4l2_async_register_subdev(struct v4l2_subdev *sd); +#define v4l2_async_register_subdev(sd) \ + __v4l2_async_register_subdev(sd, THIS_MODULE) +int __v4l2_async_register_subdev(struct v4l2_subdev *sd, struct module *module); /** * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index f6f111fae33c0d..dd897a362f369b 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -156,8 +156,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); * An error is returned if the module is no longer loaded on any attempts * to register it. */ -int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, - struct v4l2_subdev *sd); +#define v4l2_device_register_subdev(v4l2_dev, sd) \ + __v4l2_device_register_subdev(v4l2_dev, sd, THIS_MODULE) +int __must_check __v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd, + struct module *module); /** * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device. diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 7e0983b987c2d9..8d38c6befda8d0 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -854,7 +854,7 @@ struct dtv_stats { union { __u64 uvalue; /* for counters and relative scales */ __s64 svalue; /* for 0.001 dB measures */ - }; + } __attribute__ ((packed)); } __attribute__ ((packed)); diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 2663213b76a492..bf12860d570af6 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1842,7 +1842,7 @@ struct v4l2_ext_control { struct v4l2_ctrl_hdr10_cll_info __user *p_hdr10_cll_info; struct v4l2_ctrl_hdr10_mastering_display __user *p_hdr10_mastering_display; void __user *ptr; - }; + } __attribute__ ((packed)); } __attribute__ ((packed)); struct v4l2_ext_controls { |