diff options
Diffstat (limited to 'drivers/media/i2c')
35 files changed, 283 insertions, 188 deletions
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 56256c1e8b0d..31bac06d46b5 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -42,8 +42,8 @@ enum adv748x_page { ADV748X_PAGE_EOR, /* End Mark */ }; -/** - * enum adv748x_ports - Device tree port number definitions +/* + * Device tree port number definitions * * The ADV748X ports define the mapping between subdevices * and the device tree specification @@ -173,9 +173,9 @@ struct adv748x_afe { * * @endpoints: parsed device node endpoints for each port * - * @i2c_addresses I2C Page addresses - * @i2c_clients I2C clients for the page accesses - * @regmap regmap configuration pages. + * @i2c_addresses: I2C Page addresses + * @i2c_clients: I2C clients for the page accesses + * @regmap: regmap configuration pages. * * @hdmi: state of HDMI receiver context * @afe: state of AFE receiver context diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c index a3161d709015..5fc6c06edda1 100644 --- a/drivers/media/i2c/adv7511-v4l2.c +++ b/drivers/media/i2c/adv7511-v4l2.c @@ -214,36 +214,25 @@ static inline void adv7511_wr_and_or(struct v4l2_subdev *sd, u8 reg, u8 clr_mask adv7511_wr(sd, reg, (adv7511_rd(sd, reg) & clr_mask) | val_mask); } -static int adv_smbus_read_i2c_block_data(struct i2c_client *client, - u8 command, unsigned length, u8 *values) -{ - union i2c_smbus_data data; - int ret; - - if (length > I2C_SMBUS_BLOCK_MAX) - length = I2C_SMBUS_BLOCK_MAX; - data.block[0] = length; - - ret = i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_READ, command, - I2C_SMBUS_I2C_BLOCK_DATA, &data); - memcpy(values, data.block + 1, length); - return ret; -} - -static void adv7511_edid_rd(struct v4l2_subdev *sd, uint16_t len, uint8_t *buf) +static int adv7511_edid_rd(struct v4l2_subdev *sd, uint16_t len, uint8_t *buf) { struct adv7511_state *state = get_adv7511_state(sd); int i; - int err = 0; v4l2_dbg(1, debug, sd, "%s:\n", __func__); - for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) - err = adv_smbus_read_i2c_block_data(state->i2c_edid, i, + for (i = 0; i < len; i += I2C_SMBUS_BLOCK_MAX) { + s32 ret; + + ret = i2c_smbus_read_i2c_block_data(state->i2c_edid, i, I2C_SMBUS_BLOCK_MAX, buf + i); - if (err) - v4l2_err(sd, "%s: i2c read error\n", __func__); + if (ret < 0) { + v4l2_err(sd, "%s: i2c read error\n", __func__); + return ret; + } + } + + return 0; } static inline int adv7511_cec_read(struct v4l2_subdev *sd, u8 reg) @@ -1207,21 +1196,21 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) return -EINVAL; if (edid->start_block == 0 && edid->blocks == 0) { - edid->blocks = state->edid.segments * 2; + edid->blocks = state->edid.blocks; return 0; } - if (state->edid.segments == 0) + if (state->edid.blocks == 0) return -ENODATA; - if (edid->start_block >= state->edid.segments * 2) + if (edid->start_block >= state->edid.blocks) return -EINVAL; - if (edid->start_block + edid->blocks > state->edid.segments * 2) - edid->blocks = state->edid.segments * 2 - edid->start_block; + if (edid->start_block + edid->blocks > state->edid.blocks) + edid->blocks = state->edid.blocks - edid->start_block; memcpy(edid->edid, &state->edid.data[edid->start_block * 128], - 128 * edid->blocks); + 128 * edid->blocks); return 0; } @@ -1668,22 +1657,27 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd) if (edidRdy & MASK_ADV7511_EDID_RDY) { int segment = adv7511_rd(sd, 0xc4); struct adv7511_edid_detect ed; + int err; if (segment >= EDID_MAX_SEGM) { v4l2_err(sd, "edid segment number too big\n"); return false; } v4l2_dbg(1, debug, sd, "%s: got segment %d\n", __func__, segment); - adv7511_edid_rd(sd, 256, &state->edid.data[segment * 256]); - adv7511_dbg_dump_edid(2, debug, sd, segment, &state->edid.data[segment * 256]); - if (segment == 0) { - state->edid.blocks = state->edid.data[0x7e] + 1; - v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", __func__, state->edid.blocks); + err = adv7511_edid_rd(sd, 256, &state->edid.data[segment * 256]); + if (!err) { + adv7511_dbg_dump_edid(2, debug, sd, segment, &state->edid.data[segment * 256]); + if (segment == 0) { + state->edid.blocks = state->edid.data[0x7e] + 1; + v4l2_dbg(1, debug, sd, "%s: %d blocks in total\n", + __func__, state->edid.blocks); + } } - if (!edid_verify_crc(sd, segment) || - !edid_verify_header(sd, segment)) { - /* edid crc error, force reread of edid segment */ - v4l2_err(sd, "%s: edid crc or header error\n", __func__); + + if (err || !edid_verify_crc(sd, segment) || !edid_verify_header(sd, segment)) { + /* Couldn't read EDID or EDID is invalid. Force retry! */ + if (!err) + v4l2_err(sd, "%s: edid crc or header error\n", __func__); state->have_monitor = false; adv7511_s_power(sd, false); adv7511_s_power(sd, true); @@ -1964,7 +1958,7 @@ static int adv7511_remove(struct i2c_client *client) adv7511_set_isr(sd, false); adv7511_init_setup(sd); - cancel_delayed_work(&state->edid_handler); + cancel_delayed_work_sync(&state->edid_handler); i2c_unregister_device(state->i2c_edid); i2c_unregister_device(state->i2c_cec); i2c_unregister_device(state->i2c_pktmem); diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 09004d928d11..3049aa2fd0f0 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -73,6 +73,8 @@ MODULE_LICENSE("GPL"); #define ADV76XX_MAX_ADDRS (3) +#define ADV76XX_MAX_EDID_BLOCKS 4 + enum adv76xx_type { ADV7604, ADV7611, @@ -108,6 +110,11 @@ struct adv76xx_chip_info { unsigned int edid_enable_reg; unsigned int edid_status_reg; + unsigned int edid_segment_reg; + unsigned int edid_segment_mask; + unsigned int edid_spa_loc_reg; + unsigned int edid_spa_loc_msb_mask; + unsigned int edid_spa_port_b_reg; unsigned int lcf_reg; unsigned int cable_det_mask; @@ -176,7 +183,7 @@ struct adv76xx_state { const struct adv76xx_format_info *format; struct { - u8 edid[256]; + u8 edid[ADV76XX_MAX_EDID_BLOCKS * 128]; u32 present; unsigned blocks; } edid; @@ -512,10 +519,17 @@ static inline int edid_write_block(struct v4l2_subdev *sd, static void adv76xx_set_hpd(struct adv76xx_state *state, unsigned int hpd) { + const struct adv76xx_chip_info *info = state->info; unsigned int i; - for (i = 0; i < state->info->num_dv_ports; ++i) - gpiod_set_value_cansleep(state->hpd_gpio[i], hpd & BIT(i)); + if (info->type == ADV7604) { + for (i = 0; i < state->info->num_dv_ports; ++i) + gpiod_set_value_cansleep(state->hpd_gpio[i], hpd & BIT(i)); + } else { + for (i = 0; i < state->info->num_dv_ports; ++i) + io_write_clr_set(&state->sd, 0x20, 0x80 >> i, + (!!(hpd & BIT(i))) << (7 - i)); + } v4l2_subdev_notify(&state->sd, ADV76XX_HOTPLUG, &hpd); } @@ -2298,7 +2312,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) struct adv76xx_state *state = to_state(sd); const struct adv76xx_chip_info *info = state->info; unsigned int spa_loc; - u16 pa; + u16 pa, parent_pa; int err; int i; @@ -2327,15 +2341,25 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) __func__, edid->pad, state->edid.present); return 0; } - if (edid->blocks > 2) { - edid->blocks = 2; + if (edid->blocks > ADV76XX_MAX_EDID_BLOCKS) { + edid->blocks = ADV76XX_MAX_EDID_BLOCKS; return -E2BIG; } + pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc); - err = v4l2_phys_addr_validate(pa, &pa, NULL); + err = v4l2_phys_addr_validate(pa, &parent_pa, NULL); if (err) return err; + if (!spa_loc) { + /* + * There is no SPA, so just set spa_loc to 128 and pa to whatever + * data is there. + */ + spa_loc = 128; + pa = (edid->edid[spa_loc] << 8) | edid->edid[spa_loc + 1]; + } + v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n", __func__, edid->pad, state->edid.present); @@ -2344,41 +2368,33 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) adv76xx_set_hpd(state, 0); rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, 0x00); - /* - * Return an error if no location of the source physical address - * was found. - */ - if (spa_loc == 0) - return -EINVAL; - switch (edid->pad) { case ADV76XX_PAD_HDMI_PORT_A: - state->spa_port_a[0] = edid->edid[spa_loc]; - state->spa_port_a[1] = edid->edid[spa_loc + 1]; + state->spa_port_a[0] = pa >> 8; + state->spa_port_a[1] = pa & 0xff; break; case ADV7604_PAD_HDMI_PORT_B: - rep_write(sd, 0x70, edid->edid[spa_loc]); - rep_write(sd, 0x71, edid->edid[spa_loc + 1]); + rep_write(sd, info->edid_spa_port_b_reg, pa >> 8); + rep_write(sd, info->edid_spa_port_b_reg + 1, pa & 0xff); break; case ADV7604_PAD_HDMI_PORT_C: - rep_write(sd, 0x72, edid->edid[spa_loc]); - rep_write(sd, 0x73, edid->edid[spa_loc + 1]); + rep_write(sd, info->edid_spa_port_b_reg + 2, pa >> 8); + rep_write(sd, info->edid_spa_port_b_reg + 3, pa & 0xff); break; case ADV7604_PAD_HDMI_PORT_D: - rep_write(sd, 0x74, edid->edid[spa_loc]); - rep_write(sd, 0x75, edid->edid[spa_loc + 1]); + rep_write(sd, info->edid_spa_port_b_reg + 4, pa >> 8); + rep_write(sd, info->edid_spa_port_b_reg + 5, pa & 0xff); break; default: return -EINVAL; } - if (info->type == ADV7604) { - rep_write(sd, 0x76, spa_loc & 0xff); - rep_write_clr_set(sd, 0x77, 0x40, (spa_loc & 0x100) >> 2); - } else { - /* ADV7612 Software Manual Rev. A, p. 15 */ - rep_write(sd, 0x70, spa_loc & 0xff); - rep_write_clr_set(sd, 0x71, 0x01, (spa_loc & 0x100) >> 8); + if (info->edid_spa_loc_reg) { + u8 mask = info->edid_spa_loc_msb_mask; + + rep_write(sd, info->edid_spa_loc_reg, spa_loc & 0xff); + rep_write_clr_set(sd, info->edid_spa_loc_reg + 1, + mask, (spa_loc & 0x100) ? mask : 0); } edid->edid[spa_loc] = state->spa_port_a[0]; @@ -2390,11 +2406,25 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) edid->edid[0x16]); state->edid.present |= 1 << edid->pad; - err = edid_write_block(sd, 128 * edid->blocks, state->edid.edid); + rep_write_clr_set(sd, info->edid_segment_reg, + info->edid_segment_mask, 0); + err = edid_write_block(sd, 128 * min(edid->blocks, 2U), state->edid.edid); if (err < 0) { v4l2_err(sd, "error %d writing edid pad %d\n", err, edid->pad); return err; } + if (edid->blocks > 2) { + rep_write_clr_set(sd, info->edid_segment_reg, + info->edid_segment_mask, + info->edid_segment_mask); + err = edid_write_block(sd, 128 * (edid->blocks - 2), + state->edid.edid + 256); + if (err < 0) { + v4l2_err(sd, "error %d writing edid pad %d\n", + err, edid->pad); + return err; + } + } /* adv76xx calculates the checksums and enables I2C access to internal EDID RAM from DDC port. */ @@ -2409,7 +2439,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) v4l2_err(sd, "error enabling edid (0x%x)\n", state->edid.present); return -EIO; } - cec_s_phys_addr(state->cec_adap, pa, false); + cec_s_phys_addr(state->cec_adap, parent_pa, false); /* enable hotplug after 100 ms */ schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10); @@ -2803,6 +2833,18 @@ static int adv76xx_core_init(struct v4l2_subdev *sd) io_write(sd, 0x0b, 0x44); /* Power down ESDP block */ cp_write(sd, 0xcf, 0x01); /* Power down macrovision */ + /* HPD */ + if (info->type != ADV7604) { + /* Set manual HPD values to 0 */ + io_write_clr_set(sd, 0x20, 0xc0, 0); + /* + * Set HPA_DELAY to 200 ms and set automatic HPD control + * to: internal EDID is active AND a cable is detected + * AND the manual HPD control is set to 1. + */ + hdmi_write_clr_set(sd, 0x6c, 0xf6, 0x26); + } + /* video format */ io_write_clr_set(sd, 0x02, 0x0f, pdata->alt_gamma << 3); io_write_clr_set(sd, 0x05, 0x0e, pdata->blank_data << 3 | @@ -2987,6 +3029,11 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { .num_dv_ports = 4, .edid_enable_reg = 0x77, .edid_status_reg = 0x7d, + .edid_segment_reg = 0x77, + .edid_segment_mask = 0x10, + .edid_spa_loc_reg = 0x76, + .edid_spa_loc_msb_mask = 0x40, + .edid_spa_port_b_reg = 0x70, .lcf_reg = 0xb3, .tdms_lock_mask = 0xe0, .cable_det_mask = 0x1e, @@ -3037,6 +3084,8 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { .num_dv_ports = 1, .edid_enable_reg = 0x74, .edid_status_reg = 0x76, + .edid_segment_reg = 0x7a, + .edid_segment_mask = 0x01, .lcf_reg = 0xa3, .tdms_lock_mask = 0x43, .cable_det_mask = 0x01, @@ -3081,6 +3130,11 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = { .num_dv_ports = 1, /* normally 2 */ .edid_enable_reg = 0x74, .edid_status_reg = 0x76, + .edid_segment_reg = 0x7a, + .edid_segment_mask = 0x01, + .edid_spa_loc_reg = 0x70, + .edid_spa_loc_msb_mask = 0x01, + .edid_spa_port_b_reg = 0x52, .lcf_reg = 0xa3, .tdms_lock_mask = 0x43, .cable_det_mask = 0x01, @@ -3616,7 +3670,7 @@ static int adv76xx_remove(struct i2c_client *client) io_write(sd, 0x6e, 0); io_write(sd, 0x73, 0); - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv76xx_unregister_clients(to_state(sd)); diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 0855f648416d..ff10af757b99 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -88,7 +88,7 @@ struct adv7842_format_info { struct adv7842_state { struct adv7842_platform_data pdata; struct v4l2_subdev sd; - struct media_pad pad; + struct media_pad pads[ADV7842_PAD_SOURCE + 1]; struct v4l2_ctrl_handler hdl; enum adv7842_mode mode; struct v4l2_dv_timings timings; @@ -99,10 +99,12 @@ struct adv7842_state { v4l2_std_id norm; struct { u8 edid[256]; + u32 blocks; u32 present; } hdmi_edid; struct { u8 edid[256]; + u32 blocks; u32 present; } vga_edid; struct v4l2_fract aspect_ratio; @@ -343,20 +345,6 @@ static void adv_smbus_write_byte_no_check(struct i2c_client *client, I2C_SMBUS_BYTE_DATA, &data); } -static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client, - u8 command, unsigned length, const u8 *values) -{ - union i2c_smbus_data data; - - if (length > I2C_SMBUS_BLOCK_MAX) - length = I2C_SMBUS_BLOCK_MAX; - data.block[0] = length; - memcpy(data.block + 1, values, length); - return i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_WRITE, command, - I2C_SMBUS_I2C_BLOCK_DATA, &data); -} - /* ----------------------------------------------------------------------- */ static inline int io_read(struct v4l2_subdev *sd, u8 reg) @@ -725,7 +713,8 @@ static int edid_write_vga_segment(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct adv7842_state *state = to_state(sd); - const u8 *val = state->vga_edid.edid; + const u8 *edid = state->vga_edid.edid; + u32 blocks = state->vga_edid.blocks; int err = 0; int i; @@ -740,9 +729,10 @@ static int edid_write_vga_segment(struct v4l2_subdev *sd) /* edid segment pointer '1' for VGA port */ rep_write_and_or(sd, 0x77, 0xef, 0x10); - for (i = 0; !err && i < 256; i += I2C_SMBUS_BLOCK_MAX) - err = adv_smbus_write_i2c_block_data(state->i2c_edid, i, - I2C_SMBUS_BLOCK_MAX, val + i); + for (i = 0; !err && i < blocks * 128; i += I2C_SMBUS_BLOCK_MAX) + err = i2c_smbus_write_i2c_block_data(state->i2c_edid, i, + I2C_SMBUS_BLOCK_MAX, + edid + i); if (err) return err; @@ -772,8 +762,9 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) struct i2c_client *client = v4l2_get_subdevdata(sd); struct adv7842_state *state = to_state(sd); const u8 *edid = state->hdmi_edid.edid; + u32 blocks = state->hdmi_edid.blocks; int spa_loc; - u16 pa; + u16 pa, parent_pa; int err = 0; int i; @@ -791,33 +782,35 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) return 0; } - pa = v4l2_get_edid_phys_addr(edid, 256, &spa_loc); - err = v4l2_phys_addr_validate(pa, &pa, NULL); + pa = v4l2_get_edid_phys_addr(edid, blocks * 128, &spa_loc); + err = v4l2_phys_addr_validate(pa, &parent_pa, NULL); if (err) return err; - /* - * Return an error if no location of the source physical address - * was found. - */ - if (spa_loc == 0) - return -EINVAL; + if (!spa_loc) { + /* + * There is no SPA, so just set spa_loc to 128 and pa to whatever + * data is there. + */ + spa_loc = 128; + pa = (edid[spa_loc] << 8) | edid[spa_loc + 1]; + } /* edid segment pointer '0' for HDMI ports */ rep_write_and_or(sd, 0x77, 0xef, 0x00); - for (i = 0; !err && i < 256; i += I2C_SMBUS_BLOCK_MAX) - err = adv_smbus_write_i2c_block_data(state->i2c_edid, i, + for (i = 0; !err && i < blocks * 128; i += I2C_SMBUS_BLOCK_MAX) + err = i2c_smbus_write_i2c_block_data(state->i2c_edid, i, I2C_SMBUS_BLOCK_MAX, edid + i); if (err) return err; if (port == ADV7842_EDID_PORT_A) { - rep_write(sd, 0x72, edid[spa_loc]); - rep_write(sd, 0x73, edid[spa_loc + 1]); + rep_write(sd, 0x72, pa >> 8); + rep_write(sd, 0x73, pa & 0xff); } else { - rep_write(sd, 0x74, edid[spa_loc]); - rep_write(sd, 0x75, edid[spa_loc + 1]); + rep_write(sd, 0x74, pa >> 8); + rep_write(sd, 0x75, pa & 0xff); } rep_write(sd, 0x76, spa_loc & 0xff); rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40); @@ -837,7 +830,7 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) (port == ADV7842_EDID_PORT_A) ? 'A' : 'B'); return -EIO; } - cec_s_phys_addr(state->cec_adap, pa, false); + cec_s_phys_addr(state->cec_adap, parent_pa, false); /* enable hotplug after 200 ms */ schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 5); @@ -1079,7 +1072,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ /* IO-map reg. 0x16 and 0x17 should be written in sequence */ - if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { + if (i2c_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); break; } @@ -1135,7 +1128,7 @@ static void adv7842_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off offset_buf[3] = offset_c & 0x0ff; /* Registers must be written in this order with no i2c access in between */ - if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf)) + if (i2c_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf)) v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); } @@ -1164,7 +1157,7 @@ static void adv7842_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, gain_buf[3] = ((gain_c & 0x0ff)); /* Registers must be written in this order with no i2c access in between */ - if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf)) + if (i2c_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf)) v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); } @@ -2456,6 +2449,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled) static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) { struct adv7842_state *state = to_state(sd); + u32 blocks = 0; u8 *data = NULL; memset(edid->reserved, 0, sizeof(edid->reserved)); @@ -2463,30 +2457,34 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) switch (edid->pad) { case ADV7842_EDID_PORT_A: case ADV7842_EDID_PORT_B: - if (state->hdmi_edid.present & (0x04 << edid->pad)) + if (state->hdmi_edid.present & (0x04 << edid->pad)) { data = state->hdmi_edid.edid; + blocks = state->hdmi_edid.blocks; + } break; case ADV7842_EDID_PORT_VGA: - if (state->vga_edid.present) + if (state->vga_edid.present) { data = state->vga_edid.edid; + blocks = state->vga_edid.blocks; + } break; default: return -EINVAL; } if (edid->start_block == 0 && edid->blocks == 0) { - edid->blocks = data ? 2 : 0; + edid->blocks = blocks; return 0; } if (!data) return -ENODATA; - if (edid->start_block >= 2) + if (edid->start_block >= blocks) return -EINVAL; - if (edid->start_block + edid->blocks > 2) - edid->blocks = 2 - edid->start_block; + if (edid->start_block + edid->blocks > blocks) + edid->blocks = blocks - edid->start_block; memcpy(edid->edid, data + edid->start_block * 128, edid->blocks * 128); @@ -2510,26 +2508,30 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) } /* todo, per edid */ - state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], - e->edid[0x16]); + if (e->blocks) + state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], + e->edid[0x16]); switch (e->pad) { case ADV7842_EDID_PORT_VGA: memset(&state->vga_edid.edid, 0, 256); + state->vga_edid.blocks = e->blocks; state->vga_edid.present = e->blocks ? 0x1 : 0x0; - memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); + if (e->blocks) + memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); err = edid_write_vga_segment(sd); break; case ADV7842_EDID_PORT_A: case ADV7842_EDID_PORT_B: memset(&state->hdmi_edid.edid, 0, 256); + state->hdmi_edid.blocks = e->blocks; if (e->blocks) { state->hdmi_edid.present |= 0x04 << e->pad; + memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks); } else { state->hdmi_edid.present &= ~(0x04 << e->pad); adv7842_s_detect_tx_5v_ctrl(sd); } - memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks); err = edid_write_hdmi_segment(sd, e->pad); break; default: @@ -3442,6 +3444,7 @@ static int adv7842_probe(struct i2c_client *client, struct v4l2_ctrl_handler *hdl; struct v4l2_ctrl *ctrl; struct v4l2_subdev *sd; + unsigned int i; u16 rev; int err; @@ -3545,8 +3548,11 @@ static int adv7842_probe(struct i2c_client *client, adv7842_delayed_work_enable_hotplug); sd->entity.function = MEDIA_ENT_F_DV_DECODER; - state->pad.flags = MEDIA_PAD_FL_SOURCE; - err = media_entity_pads_init(&sd->entity, 1, &state->pad); + for (i = 0; i < ADV7842_PAD_SOURCE; ++i) + state->pads[i].flags = MEDIA_PAD_FL_SINK; + state->pads[ADV7842_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + err = media_entity_pads_init(&sd->entity, ADV7842_PAD_SOURCE + 1, + state->pads); if (err) goto err_work_queues; @@ -3586,7 +3592,7 @@ static int adv7842_remove(struct i2c_client *client) struct adv7842_state *state = to_state(sd); adv7842_irq_enable(sd, false); - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv7842_unregister_clients(sd); diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 15afbb4f5b31..9dc3f45da3dc 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3522,11 +3522,11 @@ static int ccs_probe(struct i2c_client *client) sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN); ccs_create_subdev(sensor, sensor->scaler, " scaler", 2, - MEDIA_ENT_F_CAM_SENSOR); + MEDIA_ENT_F_PROC_VIDEO_SCALER); ccs_create_subdev(sensor, sensor->binner, " binner", 2, MEDIA_ENT_F_PROC_VIDEO_SCALER); ccs_create_subdev(sensor, sensor->pixel_array, " pixel_array", 1, - MEDIA_ENT_F_PROC_VIDEO_SCALER); + MEDIA_ENT_F_CAM_SENSOR); rval = ccs_init_controls(sensor); if (rval < 0) @@ -3572,7 +3572,7 @@ static int ccs_probe(struct i2c_client *client) pm_runtime_get_noresume(&client->dev); pm_runtime_enable(&client->dev); - rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd); + rval = v4l2_async_register_subdev_sensor(&sensor->src->sd); if (rval < 0) goto out_disable_runtime_pm; diff --git a/drivers/media/i2c/ccs/ccs-data.h b/drivers/media/i2c/ccs/ccs-data.h index c75d480c8792..638df69804ec 100644 --- a/drivers/media/i2c/ccs/ccs-data.h +++ b/drivers/media/i2c/ccs/ccs-data.h @@ -132,7 +132,7 @@ struct ccs_pdaf_pix_loc_block_desc_group { }; /** - * struct ccs_pdaf_pix_loc_block_desc - PDAF pixel location block descriptor + * struct ccs_pdaf_pix_loc_pixel_desc - PDAF pixel location block descriptor * @pixel_type: Type of the pixel; CCS_DATA_PDAF_PIXEL_TYPE_* * @small_offset_x: offset X coordinate * @small_offset_y: offset Y coordinate diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h index 6b4ec4beaba0..5838fcda92fd 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.h +++ b/drivers/media/i2c/ccs/ccs-quirk.h @@ -21,7 +21,7 @@ struct ccs_sensor; * sensor registers. Called the first time the sensor is powered up. * @post_poweron: Called always after the sensor has been fully powered on. * @pre_streamon: Called just before streaming is enabled. - * @post_streamon: Called right after stopping streaming. + * @post_streamoff: Called right after stopping streaming. * @pll_flags: Return flags for the PLL calculator. * @init: Quirk initialisation, called the last in probe(). This is * also appropriate for adding sensor specific controls, for instance. @@ -33,6 +33,8 @@ struct ccs_sensor; * @value: Register value, set by the caller on write, or * by the quirk on read * + * @flags: Quirk flags + * * @return: 0 on success, -ENOIOCTLCMD if no register * access may be done by the caller (default read * value is zero), else negative error code on error diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c index 122af761c8e3..bb3eac5e005e 100644 --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -1443,7 +1443,7 @@ static int et8ek8_probe(struct i2c_client *client) goto err_mutex; } - ret = v4l2_async_register_subdev_sensor_common(&sensor->subdev); + ret = v4l2_async_register_subdev_sensor(&sensor->subdev); if (ret < 0) goto err_entity; diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index c74736845d7a..6f05c1138e3b 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -1145,7 +1145,7 @@ static int hi556_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&hi556->sd); + ret = v4l2_async_register_subdev_sensor(&hi556->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index cee1a4817af9..e8b281e432e8 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -1061,7 +1061,7 @@ static int imx214_probe(struct i2c_client *client) imx214_entity_init_cfg(&imx214->sd, NULL); - ret = v4l2_async_register_subdev_sensor_common(&imx214->sd); + ret = v4l2_async_register_subdev_sensor(&imx214->sd); if (ret < 0) { dev_err(dev, "could not register v4l2 device\n"); goto free_entity; diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 6e3382b85a90..1054ffedaefd 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -1035,29 +1035,47 @@ static int imx219_start_streaming(struct imx219 *imx219) const struct imx219_reg_list *reg_list; int ret; + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + return ret; + } + /* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); if (ret) { dev_err(&client->dev, "%s failed to set mode\n", __func__); - return ret; + goto err_rpm_put; } ret = imx219_set_framefmt(imx219); if (ret) { dev_err(&client->dev, "%s failed to set frame format: %d\n", __func__, ret); - return ret; + goto err_rpm_put; } /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); if (ret) - return ret; + goto err_rpm_put; /* set stream on register */ - return imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, - IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); + ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, + IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); + if (ret) + goto err_rpm_put; + + /* vflip and hflip cannot change during streaming */ + __v4l2_ctrl_grab(imx219->vflip, true); + __v4l2_ctrl_grab(imx219->hflip, true); + + return 0; + +err_rpm_put: + pm_runtime_put(&client->dev); + return ret; } static void imx219_stop_streaming(struct imx219 *imx219) @@ -1070,12 +1088,16 @@ static void imx219_stop_streaming(struct imx219 *imx219) IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); if (ret) dev_err(&client->dev, "%s failed to set stream\n", __func__); + + __v4l2_ctrl_grab(imx219->vflip, false); + __v4l2_ctrl_grab(imx219->hflip, false); + + pm_runtime_put(&client->dev); } static int imx219_set_stream(struct v4l2_subdev *sd, int enable) { struct imx219 *imx219 = to_imx219(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; mutex_lock(&imx219->mutex); @@ -1085,36 +1107,23 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); - goto err_unlock; - } - /* * Apply default & customized values * and then start streaming. */ ret = imx219_start_streaming(imx219); if (ret) - goto err_rpm_put; + goto err_unlock; } else { imx219_stop_streaming(imx219); - pm_runtime_put(&client->dev); } imx219->streaming = enable; - /* vflip and hflip cannot change during streaming */ - __v4l2_ctrl_grab(imx219->vflip, enable); - __v4l2_ctrl_grab(imx219->hflip, enable); - mutex_unlock(&imx219->mutex); return ret; -err_rpm_put: - pm_runtime_put(&client->dev); err_unlock: mutex_unlock(&imx219->mutex); @@ -1528,7 +1537,7 @@ static int imx219_probe(struct i2c_client *client) goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&imx219->sd); + ret = v4l2_async_register_subdev_sensor(&imx219->sd); if (ret < 0) { dev_err(dev, "failed to register sensor sub-device: %d\n", ret); goto error_media_entity; diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 61d74b794582..a017ec4e0f50 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -61,6 +61,15 @@ #define IMX258_DGTL_GAIN_DEFAULT 1024 #define IMX258_DGTL_GAIN_STEP 1 +/* HDR control */ +#define IMX258_REG_HDR 0x0220 +#define IMX258_HDR_ON BIT(0) +#define IMX258_REG_HDR_RATIO 0x0222 +#define IMX258_HDR_RATIO_MIN 0 +#define IMX258_HDR_RATIO_MAX 5 +#define IMX258_HDR_RATIO_STEP 1 +#define IMX258_HDR_RATIO_DEFAULT 0x0 + /* Test Pattern Control */ #define IMX258_REG_TEST_PATTERN 0x0600 @@ -777,6 +786,22 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl) !ctrl->val ? REG_CONFIG_MIRROR_FLIP : REG_CONFIG_FLIP_TEST_PATTERN); break; + case V4L2_CID_WIDE_DYNAMIC_RANGE: + if (!ctrl->val) { + ret = imx258_write_reg(imx258, IMX258_REG_HDR, + IMX258_REG_VALUE_08BIT, + IMX258_HDR_RATIO_MIN); + } else { + ret = imx258_write_reg(imx258, IMX258_REG_HDR, + IMX258_REG_VALUE_08BIT, + IMX258_HDR_ON); + if (ret) + break; + ret = imx258_write_reg(imx258, IMX258_REG_HDR_RATIO, + IMX258_REG_VALUE_08BIT, + BIT(IMX258_HDR_RATIO_MAX)); + } + break; default: dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled\n", @@ -1193,6 +1218,9 @@ static int imx258_init_controls(struct imx258 *imx258) IMX258_DGTL_GAIN_STEP, IMX258_DGTL_GAIN_DEFAULT); + v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE, + 0, 1, 1, IMX258_HDR_RATIO_DEFAULT); + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_TEST_PATTERN, ARRAY_SIZE(imx258_test_pattern_menu) - 1, @@ -1289,7 +1317,7 @@ static int imx258_probe(struct i2c_client *client) if (ret) goto error_handler_free; - ret = v4l2_async_register_subdev_sensor_common(&imx258->sd); + ret = v4l2_async_register_subdev_sensor(&imx258->sd); if (ret < 0) goto error_media_entity; diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c index 54642d5f2d5b..cdccaab3043a 100644 --- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -697,7 +697,7 @@ static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val) } /** - * Read a multibyte register. + * imx274_read_mbreg - Read a multibyte register. * * Uses a bulk read where possible. * @@ -732,7 +732,7 @@ static int imx274_read_mbreg(struct stimx274 *priv, u16 addr, u32 *val, } /** - * Write a multibyte register. + * imx274_write_mbreg - Write a multibyte register. * * Uses a bulk write where possible. * @@ -980,7 +980,8 @@ static int imx274_binning_goodness(struct stimx274 *imx274, } /** - * Helper function to change binning and set both compose and format. + * __imx274_change_compose - Helper function to change binning and set both + * compose and format. * * We have two entry points to change binning: set_fmt and * set_selection(COMPOSE). Both have to compute the new output size @@ -1380,7 +1381,8 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd, max = fi->interval.numerator * 1000000 / fi->interval.denominator; def = max; - if (__v4l2_ctrl_modify_range(ctrl, min, max, 1, def)) { + ret = __v4l2_ctrl_modify_range(ctrl, min, max, 1, def); + if (ret) { dev_err(&imx274->client->dev, "Exposure ctrl range update failed\n"); goto unlock; diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 8473c0bbb35d..38540323a156 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -2486,7 +2486,7 @@ static int imx319_probe(struct i2c_client *client) goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&imx319->sd); + ret = v4l2_async_register_subdev_sensor(&imx319->sd); if (ret < 0) goto error_media_entity; diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index ad530f0d338a..047aa7658d21 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -1057,7 +1057,7 @@ static int imx334_probe(struct i2c_client *client) goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&imx334->sd); + ret = v4l2_async_register_subdev_sensor(&imx334->sd); if (ret < 0) { dev_err(imx334->dev, "failed to register async subdev: %d", ret); diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 700f7467fb31..ccedcd4c520a 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -1786,7 +1786,7 @@ static int imx355_probe(struct i2c_client *client) goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&imx355->sd); + ret = v4l2_async_register_subdev_sensor(&imx355->sd); if (ret < 0) goto error_media_entity; diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h index 4023906d273d..60c102fa7df5 100644 --- a/drivers/media/i2c/m5mols/m5mols.h +++ b/drivers/media/i2c/m5mols/m5mols.h @@ -50,6 +50,7 @@ struct m5mols_resolution { * @exposure_time: exposure time register value * @shutter_speed: speed of the shutter register value * @aperture: aperture register value + * @brightness: brightness register value * @exposure_bias: it calls also EV bias * @iso_speed: ISO register value * @flash: status register value of the flash @@ -126,6 +127,8 @@ struct m5mols_scenemode { u8 wdr; }; +#define VERSION_STRING_SIZE 22 + /** * struct m5mols_version - firmware version information * @customer: customer information @@ -144,7 +147,6 @@ struct m5mols_scenemode { * about manufacturer and the vendor of the sensor's packaging. The least * significant 2 bytes of the string indicate packaging manufacturer. */ -#define VERSION_STRING_SIZE 22 struct m5mols_version { u8 customer; u8 project; diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index 661208c9bfc5..bc46a0957b40 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c @@ -1125,7 +1125,6 @@ static int max2175_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *vf) { struct max2175 *ctx = max2175_from_sd(sd); - int ret = 0; if (vf->tuner != 0) return -EINVAL; @@ -1134,7 +1133,7 @@ static int max2175_g_frequency(struct v4l2_subdev *sd, vf->type = V4L2_TUNER_RF; vf->frequency = ctx->freq; - return ret; + return 0; } static int max2175_enum_freq_bands(struct v4l2_subdev *sd, diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c index 60b4bc645334..c47b1d45d8fd 100644 --- a/drivers/media/i2c/ov02a10.c +++ b/drivers/media/i2c/ov02a10.c @@ -700,7 +700,7 @@ static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl) default: ret = -EINVAL; break; - }; + } pm_runtime_put(&client->dev); diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 2f3be7a80cef..4a2885ff0cbe 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1738,7 +1738,7 @@ static int ov13858_probe(struct i2c_client *client, goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&ov13858->sd); + ret = v4l2_async_register_subdev_sensor(&ov13858->sd); if (ret < 0) goto error_media_entity; diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index b41a90c2aed5..0f3f17f3c426 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -1154,7 +1154,7 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&ov2740->sd); + ret = v4l2_async_register_subdev_sensor(&ov2740->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 14f3afa7721a..5b9cc71df473 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -3162,7 +3162,7 @@ static int ov5640_probe(struct i2c_client *client) if (ret) goto entity_cleanup; - ret = v4l2_async_register_subdev_sensor_common(&sensor->sd); + ret = v4l2_async_register_subdev_sensor(&sensor->sd); if (ret) goto free_ctrls; diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c index dfe38ab8224d..3ecb4a3e8773 100644 --- a/drivers/media/i2c/ov5648.c +++ b/drivers/media/i2c/ov5648.c @@ -2559,7 +2559,7 @@ static int ov5648_probe(struct i2c_client *client) /* V4L2 subdev register */ - ret = v4l2_async_register_subdev_sensor_common(subdev); + ret = v4l2_async_register_subdev_sensor(subdev); if (ret) goto error_pm; diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 866c8c2e8f59..dee7df8dd100 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -2503,7 +2503,7 @@ static int ov5670_probe(struct i2c_client *client) } /* Async register for subdev */ - ret = v4l2_async_register_subdev_sensor_common(&ov5670->sd); + ret = v4l2_async_register_subdev_sensor(&ov5670->sd); if (ret < 0) { err_msg = "v4l2_async_register_subdev() error"; goto error_entity_cleanup; diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index ae00d717e599..dea32859459a 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -1193,7 +1193,7 @@ static int ov5675_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&ov5675->sd); + ret = v4l2_async_register_subdev_sensor(&ov5675->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index bbccb6f9582f..09bee57a241d 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -1336,7 +1336,7 @@ static int ov5695_probe(struct i2c_client *client, goto err_power_off; #endif - ret = v4l2_async_register_subdev_sensor_common(sd); + ret = v4l2_async_register_subdev_sensor(sd); if (ret) { dev_err(dev, "v4l2 async register subdev failed\n"); goto err_clean_entity; diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index b337f729d5e3..e3af3ea277af 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -1795,7 +1795,7 @@ static int ov8856_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&ov8856->sd); + ret = v4l2_async_register_subdev_sensor(&ov8856->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index 36a60fbc211d..9ecf180635ee 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -2524,7 +2524,6 @@ static int ov8865_g_frame_interval(struct v4l2_subdev *subdev, { struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev); const struct ov8865_mode *mode; - int ret = 0; mutex_lock(&sensor->mutex); @@ -2533,7 +2532,7 @@ static int ov8865_g_frame_interval(struct v4l2_subdev *subdev, mutex_unlock(&sensor->mutex); - return ret; + return 0; } static const struct v4l2_subdev_video_ops ov8865_subdev_video_ops = { @@ -2905,7 +2904,7 @@ static int ov8865_probe(struct i2c_client *client) /* V4L2 subdev register */ - ret = v4l2_async_register_subdev_sensor_common(subdev); + ret = v4l2_async_register_subdev_sensor(subdev); if (ret) goto error_pm; diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index e212465489e8..b7309a551cae 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -964,7 +964,7 @@ static int ov9734_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor_common(&ov9734->sd); + ret = v4l2_async_register_subdev_sensor(&ov9734->sd); if (ret < 0) { dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret); diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index dcc21515e5a4..179d107f494c 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -345,7 +345,7 @@ static int ov10640_initialize(struct rdacm21_device *dev) /* Read OV10640 ID to test communications. */ ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, OV490_SCCB_SLAVE_READ); ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, OV10640_CHIP_ID >> 8); - ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, (u8)OV10640_CHIP_ID); + ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, OV10640_CHIP_ID & 0xff); /* Trigger SCCB slave transaction and give it some time to complete. */ ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index ec6f22efe19a..6e702b57c37d 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -510,7 +510,7 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr, #define s5k5baf_write_seq(state, addr, seq...) \ s5k5baf_write_arr_seq(state, addr, sizeof((char[]){ seq }), \ - (const u16 []){ seq }); + (const u16 []){ seq }) /* add items count at the beginning of the list */ #define NSEQ(seq...) sizeof((char[]){ seq }), seq diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 72439fae7968..038e38500760 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -416,7 +416,7 @@ static int s5k6aa_set_ahb_address(struct i2c_client *client) } /** - * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration + * s5k6aa_configure_pixel_clocks - apply ISP main clock/PLL configuration * @s5k6aa: pointer to &struct s5k6aa describing the device * * Configure the internal ISP PLL for the required output frequency. diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 831b5b54fd78..1b309bb743c7 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2193,7 +2193,7 @@ static int tc358743_remove(struct i2c_client *client) del_timer_sync(&state->timer); flush_work(&state->work_i2c_poll); } - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); cec_unregister_adapter(state->cec_adap); v4l2_async_unregister_subdev(sd); v4l2_device_unregister_subdev(sd); diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index a09bf0a39d05..89bb7e6dc7a4 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2804,7 +2804,7 @@ static int tda1997x_remove(struct i2c_client *client) media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(&state->hdl); regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies); - cancel_delayed_work(&state->delayed_work_enable_hpd); + cancel_delayed_work_sync(&state->delayed_work_enable_hpd); mutex_destroy(&state->page_lock); mutex_destroy(&state->lock); diff --git a/drivers/media/i2c/tvp514x_regs.h b/drivers/media/i2c/tvp514x_regs.h index cc236c968f67..b452725d5cfb 100644 --- a/drivers/media/i2c/tvp514x_regs.h +++ b/drivers/media/i2c/tvp514x_regs.h @@ -261,9 +261,9 @@ #define TOK_SKIP (3) /* token to skip a register */ /** * struct tvp514x_reg - Structure for TVP5146/47 register initialization values - * @token - Token: TOK_WRITE, TOK_TERM etc.. - * @reg - Register offset - * @val - Register Value for TOK_WRITE or delay in ms for TOK_DELAY + * @token: Token: TOK_WRITE, TOK_TERM etc.. + * @reg: Register offset + * @val: Register Value for TOK_WRITE or delay in ms for TOK_DELAY */ struct tvp514x_reg { u8 token; |