diff options
Diffstat (limited to 'drivers/media/i2c')
24 files changed, 556 insertions, 65 deletions
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index d18be19c96c..842654d3331 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -621,6 +621,15 @@ config VIDEO_AS3645A This is a driver for the AS3645A and LM3555 flash controllers. It has build in control for flash, torch and indicator LEDs. +config VIDEO_LM3560 + tristate "LM3560 dual flash driver support" + depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER + depends on MEDIA_CAMERA_SUPPORT + select REGMAP_I2C + ---help--- + This is a driver for the lm3560 dual flash controllers. It controls + flash, torch LEDs. + comment "Video improvement chips" config VIDEO_UPD64031A @@ -646,7 +655,7 @@ config VIDEO_UPD64083 To compile this driver as a module, choose M here: the module will be called upd64083. -comment "Miscelaneous helper chips" +comment "Miscellaneous helper chips" config VIDEO_THS7303 tristate "THS7303/53 Video Amplifier" diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 9f462df77b4..e03f1776f4f 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o +obj-$(CONFIG_VIDEO_LM3560) += lm3560.o obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o obj-$(CONFIG_VIDEO_AK881X) += ak881x.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index bb0c99d7a4f..b06a7e54ee0 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c @@ -628,16 +628,13 @@ static int ad9389b_s_stream(struct v4l2_subdev *sd, int enable) static const struct v4l2_dv_timings_cap ad9389b_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 170000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 170000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static int ad9389b_s_dv_timings(struct v4l2_subdev *sd, diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index 6f738d8e3a8..d45e0e3a781 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -178,7 +178,7 @@ static int adv7183_log_status(struct v4l2_subdev *sd) adv7183_read(sd, ADV7183_VS_FIELD_CTRL_1), adv7183_read(sd, ADV7183_VS_FIELD_CTRL_2), adv7183_read(sd, ADV7183_VS_FIELD_CTRL_3)); - v4l2_info(sd, "adv7183: Hsync positon control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n", + v4l2_info(sd, "adv7183: Hsync position control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n", adv7183_read(sd, ADV7183_HS_POS_CTRL_1), adv7183_read(sd, ADV7183_HS_POS_CTRL_2), adv7183_read(sd, ADV7183_HS_POS_CTRL_3)); diff --git a/drivers/media/i2c/adv7183_regs.h b/drivers/media/i2c/adv7183_regs.h index 4a5b7d211d2..b253d400e81 100644 --- a/drivers/media/i2c/adv7183_regs.h +++ b/drivers/media/i2c/adv7183_regs.h @@ -52,9 +52,9 @@ #define ADV7183_VS_FIELD_CTRL_1 0x31 /* Vsync field control 1 */ #define ADV7183_VS_FIELD_CTRL_2 0x32 /* Vsync field control 2 */ #define ADV7183_VS_FIELD_CTRL_3 0x33 /* Vsync field control 3 */ -#define ADV7183_HS_POS_CTRL_1 0x34 /* Hsync positon control 1 */ -#define ADV7183_HS_POS_CTRL_2 0x35 /* Hsync positon control 2 */ -#define ADV7183_HS_POS_CTRL_3 0x36 /* Hsync positon control 3 */ +#define ADV7183_HS_POS_CTRL_1 0x34 /* Hsync position control 1 */ +#define ADV7183_HS_POS_CTRL_2 0x35 /* Hsync position control 2 */ +#define ADV7183_HS_POS_CTRL_3 0x36 /* Hsync position control 3 */ #define ADV7183_POLARITY 0x37 /* Polarity */ #define ADV7183_NTSC_COMB_CTRL 0x38 /* NTSC comb control */ #define ADV7183_PAL_COMB_CTRL 0x39 /* PAL comb control */ diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index aeb56c53e39..d4e15a617c3 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/videodev2.h> #include <linux/uaccess.h> +#include <linux/of.h> #include <media/adv7343.h> #include <media/v4l2-async.h> diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 7a576097471..7c8d971f1f6 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -119,16 +119,14 @@ static int adv7511_s_clock_freq(struct v4l2_subdev *sd, u32 freq); static const struct v4l2_dv_timings_cap adv7511_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = ADV7511_MAX_WIDTH, - .max_height = ADV7511_MAX_HEIGHT, - .min_pixelclock = ADV7511_MIN_PIXELCLOCK, - .max_pixelclock = ADV7511_MAX_PIXELCLOCK, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, ADV7511_MAX_WIDTH, 0, ADV7511_MAX_HEIGHT, + ADV7511_MIN_PIXELCLOCK, ADV7511_MAX_PIXELCLOCK, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static inline struct adv7511_state *get_adv7511_state(struct v4l2_subdev *sd) @@ -1126,6 +1124,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->i2c_edid = i2c_new_dummy(client->adapter, state->i2c_edid_addr >> 1); if (state->i2c_edid == NULL) { v4l2_err(sd, "failed to register edid i2c client\n"); + err = -ENOMEM; goto err_entity; } @@ -1133,6 +1132,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id * state->work_queue = create_singlethread_workqueue(sd->name); if (state->work_queue == NULL) { v4l2_err(sd, "could not create workqueue\n"); + err = -ENOMEM; goto err_unreg_cec; } diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index fbfdd2fc2a3..a324106b9f1 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -877,7 +877,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, break; case ADV7604_MODE_HDMI: /* set default prim_mode/vid_std for HDMI - accoring to [REF_03, c. 4.2] */ + according to [REF_03, c. 4.2] */ io_write(sd, 0x00, 0x02); /* video std */ io_write(sd, 0x01, 0x06); /* prim mode */ break; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index d1748901337..b154f36740b 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -546,30 +546,24 @@ static inline bool is_digital_input(struct v4l2_subdev *sd) static const struct v4l2_dv_timings_cap adv7842_timings_cap_analog = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 170000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 170000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static const struct v4l2_dv_timings_cap adv7842_timings_cap_digital = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1200, - .min_pixelclock = 25000000, - .max_pixelclock = 225000000, - .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1200, 25000000, 225000000, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | - V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM, - }, + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) }; static inline const struct v4l2_dv_timings_cap * @@ -1019,7 +1013,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, break; case ADV7842_MODE_HDMI: /* set default prim_mode/vid_std for HDMI - accoring to [REF_03, c. 4.2] */ + according to [REF_03, c. 4.2] */ io_write(sd, 0x00, 0x02); /* video std */ io_write(sd, 0x01, 0x06); /* prim mode */ break; diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index 82bf5679da3..99ee456700f 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -394,7 +394,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!rc) { /* - * If platform_data doesn't specify rc_dev, initilize it + * If platform_data doesn't specify rc_dev, initialize it * internally */ rc = rc_allocate_device(); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c new file mode 100644 index 00000000000..3317a9ae396 --- /dev/null +++ b/drivers/media/i2c/lm3560.c @@ -0,0 +1,488 @@ +/* + * drivers/media/i2c/lm3560.c + * General device driver for TI lm3560, FLASH LED Driver + * + * Copyright (C) 2013 Texas Instruments + * + * Contact: Daniel Jeong <gshark.jeong@gmail.com> + * Ldd-Mlp <ldd-mlp@list.ti.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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/mutex.h> +#include <linux/regmap.h> +#include <linux/videodev2.h> +#include <media/lm3560.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> + +/* registers definitions */ +#define REG_ENABLE 0x10 +#define REG_TORCH_BR 0xa0 +#define REG_FLASH_BR 0xb0 +#define REG_FLASH_TOUT 0xc0 +#define REG_FLAG 0xd0 +#define REG_CONFIG1 0xe0 + +/* Fault Mask */ +#define FAULT_TIMEOUT (1<<0) +#define FAULT_OVERTEMP (1<<1) +#define FAULT_SHORT_CIRCUIT (1<<2) + +enum led_enable { + MODE_SHDN = 0x0, + MODE_TORCH = 0x2, + MODE_FLASH = 0x3, +}; + +/* struct lm3560_flash + * + * @pdata: platform data + * @regmap: reg. map for i2c + * @lock: muxtex for serial access. + * @led_mode: V4L2 LED mode + * @ctrls_led: V4L2 contols + * @subdev_led: V4L2 subdev + */ +struct lm3560_flash { + struct device *dev; + struct lm3560_platform_data *pdata; + struct regmap *regmap; + struct mutex lock; + + enum v4l2_flash_led_mode led_mode; + struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX]; + struct v4l2_subdev subdev_led[LM3560_LED_MAX]; +}; + +#define to_lm3560_flash(_ctrl, _no) \ + container_of(_ctrl->handler, struct lm3560_flash, ctrls_led[_no]) + +/* enable mode control */ +static int lm3560_mode_ctrl(struct lm3560_flash *flash) +{ + int rval = -EINVAL; + + switch (flash->led_mode) { + case V4L2_FLASH_LED_MODE_NONE: + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x03, MODE_SHDN); + break; + case V4L2_FLASH_LED_MODE_TORCH: + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x03, MODE_TORCH); + break; + case V4L2_FLASH_LED_MODE_FLASH: + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x03, MODE_FLASH); + break; + } + return rval; +} + +/* led1/2 enable/disable */ +static int lm3560_enable_ctrl(struct lm3560_flash *flash, + enum lm3560_led_id led_no, bool on) +{ + int rval; + + if (led_no == LM3560_LED0) { + if (on == true) + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x08, 0x08); + else + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x08, 0x00); + } else { + if (on == true) + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x10, 0x10); + else + rval = regmap_update_bits(flash->regmap, + REG_ENABLE, 0x10, 0x00); + } + return rval; +} + +/* torch1/2 brightness control */ +static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash, + enum lm3560_led_id led_no, unsigned int brt) +{ + int rval; + u8 br_bits; + + if (brt < LM3560_TORCH_BRT_MIN) + return lm3560_enable_ctrl(flash, led_no, false); + else + rval = lm3560_enable_ctrl(flash, led_no, true); + + br_bits = LM3560_TORCH_BRT_uA_TO_REG(brt); + if (led_no == LM3560_LED0) + rval = regmap_update_bits(flash->regmap, + REG_TORCH_BR, 0x07, br_bits); + else + rval = regmap_update_bits(flash->regmap, + REG_TORCH_BR, 0x38, br_bits << 3); + + return rval; +} + +/* flash1/2 brightness control */ +static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash, + enum lm3560_led_id led_no, unsigned int brt) +{ + int rval; + u8 br_bits; + + if (brt < LM3560_FLASH_BRT_MIN) + return lm3560_enable_ctrl(flash, led_no, false); + else + rval = lm3560_enable_ctrl(flash, led_no, true); + + br_bits = LM3560_FLASH_BRT_uA_TO_REG(brt); + if (led_no == LM3560_LED0) + rval = regmap_update_bits(flash->regmap, + REG_FLASH_BR, 0x0f, br_bits); + else + rval = regmap_update_bits(flash->regmap, + REG_FLASH_BR, 0xf0, br_bits << 4); + + return rval; +} + +/* V4L2 controls */ +static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) +{ + struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); + + mutex_lock(&flash->lock); + + if (ctrl->id == V4L2_CID_FLASH_FAULT) { + int rval; + s32 fault = 0; + unsigned int reg_val; + rval = regmap_read(flash->regmap, REG_FLAG, ®_val); + if (rval < 0) + return rval; + if (rval & FAULT_SHORT_CIRCUIT) + fault |= V4L2_FLASH_FAULT_SHORT_CIRCUIT; + if (rval & FAULT_OVERTEMP) + fault |= V4L2_FLASH_FAULT_OVER_TEMPERATURE; + if (rval & FAULT_TIMEOUT) + fault |= V4L2_FLASH_FAULT_TIMEOUT; + ctrl->cur.val = fault; + return 0; + } + + mutex_unlock(&flash->lock); + return -EINVAL; +} + +static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no) +{ + struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no); + u8 tout_bits; + int rval = -EINVAL; + + mutex_lock(&flash->lock); + + switch (ctrl->id) { + case V4L2_CID_FLASH_LED_MODE: + flash->led_mode = ctrl->val; + if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) + rval = lm3560_mode_ctrl(flash); + break; + + case V4L2_CID_FLASH_STROBE_SOURCE: + rval = regmap_update_bits(flash->regmap, + REG_CONFIG1, 0x04, (ctrl->val) << 2); + if (rval < 0) + goto err_out; + break; + + case V4L2_CID_FLASH_STROBE: + if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) + return -EBUSY; + flash->led_mode = V4L2_FLASH_LED_MODE_FLASH; + rval = lm3560_mode_ctrl(flash); + break; + + case V4L2_CID_FLASH_STROBE_STOP: + if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) + return -EBUSY; + flash->led_mode = V4L2_FLASH_LED_MODE_NONE; + rval = lm3560_mode_ctrl(flash); + break; + + case V4L2_CID_FLASH_TIMEOUT: + tout_bits = LM3560_FLASH_TOUT_ms_TO_REG(ctrl->val); + rval = regmap_update_bits(flash->regmap, + REG_FLASH_TOUT, 0x1f, tout_bits); + break; + + case V4L2_CID_FLASH_INTENSITY: + rval = lm3560_flash_brt_ctrl(flash, led_no, ctrl->val); + break; + + case V4L2_CID_FLASH_TORCH_INTENSITY: + rval = lm3560_torch_brt_ctrl(flash, led_no, ctrl->val); + break; + } + + mutex_unlock(&flash->lock); +err_out: + return rval; +} + +static int lm3560_led1_get_ctrl(struct v4l2_ctrl *ctrl) +{ + return lm3560_get_ctrl(ctrl, LM3560_LED1); +} + +static int lm3560_led1_set_ctrl(struct v4l2_ctrl *ctrl) +{ + return lm3560_set_ctrl(ctrl, LM3560_LED1); +} + +static int lm3560_led0_get_ctrl(struct v4l2_ctrl *ctrl) +{ + return lm3560_get_ctrl(ctrl, LM3560_LED0); +} + +static int lm3560_led0_set_ctrl(struct v4l2_ctrl *ctrl) +{ + return lm3560_set_ctrl(ctrl, LM3560_LED0); +} + +static const struct v4l2_ctrl_ops lm3560_led_ctrl_ops[LM3560_LED_MAX] = { + [LM3560_LED0] = { + .g_volatile_ctrl = lm3560_led0_get_ctrl, + .s_ctrl = lm3560_led0_set_ctrl, + }, + [LM3560_LED1] = { + .g_volatile_ctrl = lm3560_led1_get_ctrl, + .s_ctrl = lm3560_led1_set_ctrl, + } +}; + +static int lm3560_init_controls(struct lm3560_flash *flash, + enum lm3560_led_id led_no) +{ + struct v4l2_ctrl *fault; + u32 max_flash_brt = flash->pdata->max_flash_brt[led_no]; + u32 max_torch_brt = flash->pdata->max_torch_brt[led_no]; + struct v4l2_ctrl_handler *hdl = &flash->ctrls_led[led_no]; + const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no]; + + v4l2_ctrl_handler_init(hdl, 8); + /* flash mode */ + v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE, + V4L2_FLASH_LED_MODE_TORCH, ~0x7, + V4L2_FLASH_LED_MODE_NONE); + flash->led_mode = V4L2_FLASH_LED_MODE_NONE; + + /* flash source */ + v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE, + 0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE); + + /* flash strobe */ + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0); + /* flash strobe stop */ + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0); + + /* flash strobe timeout */ + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT, + LM3560_FLASH_TOUT_MIN, + flash->pdata->max_flash_timeout, + LM3560_FLASH_TOUT_STEP, + flash->pdata->max_flash_timeout); + + /* flash brt */ + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, + LM3560_FLASH_BRT_MIN, max_flash_brt, + LM3560_FLASH_BRT_STEP, max_flash_brt); + + /* torch brt */ + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY, + LM3560_TORCH_BRT_MIN, max_torch_brt, + LM3560_TORCH_BRT_STEP, max_torch_brt); + + /* fault */ + fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0, + V4L2_FLASH_FAULT_OVER_VOLTAGE + | V4L2_FLASH_FAULT_OVER_TEMPERATURE + | V4L2_FLASH_FAULT_SHORT_CIRCUIT + | V4L2_FLASH_FAULT_TIMEOUT, 0, 0); + if (fault != NULL) + fault->flags |= V4L2_CTRL_FLAG_VOLATILE; + + if (hdl->error) + return hdl->error; + + flash->subdev_led[led_no].ctrl_handler = hdl; + return 0; +} + +/* initialize device */ +static const struct v4l2_subdev_ops lm3560_ops = { + .core = NULL, +}; + +static const struct regmap_config lm3560_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xFF, +}; + +static int lm3560_subdev_init(struct lm3560_flash *flash, + enum lm3560_led_id led_no, char *led_name) +{ + struct i2c_client *client = to_i2c_client(flash->dev); + int rval; + + v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops); + flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + strcpy(flash->subdev_led[led_no].name, led_name); + rval = lm3560_init_controls(flash, led_no); + if (rval) + goto err_out; + rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0); + if (rval < 0) + goto err_out; + flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + + return rval; + +err_out: + v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); + return rval; +} + +static int lm3560_init_device(struct lm3560_flash *flash) +{ + int rval; + unsigned int reg_val; + + /* set peak current */ + rval = regmap_update_bits(flash->regmap, + REG_FLASH_TOUT, 0x60, flash->pdata->peak); + if (rval < 0) + return rval; + /* output disable */ + flash->led_mode = V4L2_FLASH_LED_MODE_NONE; + rval = lm3560_mode_ctrl(flash); + if (rval < 0) + return rval; + /* Reset faults */ + rval = regmap_read(flash->regmap, REG_FLAG, ®_val); + return rval; +} + +static int lm3560_probe(struct i2c_client *client, + const struct i2c_device_id *devid) +{ + struct lm3560_flash *flash; + struct lm3560_platform_data *pdata = dev_get_platdata(&client->dev); + int rval; + + flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); + if (flash == NULL) + return -ENOMEM; + + flash->regmap = devm_regmap_init_i2c(client, &lm3560_regmap); + if (IS_ERR(flash->regmap)) { + rval = PTR_ERR(flash->regmap); + return rval; + } + + /* if there is no platform data, use chip default value */ + if (pdata == NULL) { + pdata = + kzalloc(sizeof(struct lm3560_platform_data), GFP_KERNEL); + if (pdata == NULL) + return -ENODEV; + pdata->peak = LM3560_PEAK_3600mA; + pdata->max_flash_timeout = LM3560_FLASH_TOUT_MAX; + /* led 1 */ + pdata->max_flash_brt[LM3560_LED0] = LM3560_FLASH_BRT_MAX; + pdata->max_torch_brt[LM3560_LED0] = LM3560_TORCH_BRT_MAX; + /* led 2 */ + pdata->max_flash_brt[LM3560_LED1] = LM3560_FLASH_BRT_MAX; + pdata->max_torch_brt[LM3560_LED1] = LM3560_TORCH_BRT_MAX; + } + flash->pdata = pdata; + flash->dev = &client->dev; + mutex_init(&flash->lock); + + rval = lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); + if (rval < 0) + return rval; + + rval = lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); + if (rval < 0) + return rval; + + rval = lm3560_init_device(flash); + if (rval < 0) + return rval; + + return 0; +} + +static int lm3560_remove(struct i2c_client *client) +{ + struct v4l2_subdev *subdev = i2c_get_clientdata(client); + struct lm3560_flash *flash = container_of(subdev, struct lm3560_flash, + subdev_led[LM3560_LED_MAX]); + unsigned int i; + + for (i = LM3560_LED0; i < LM3560_LED_MAX; i++) { + v4l2_device_unregister_subdev(&flash->subdev_led[i]); + v4l2_ctrl_handler_free(&flash->ctrls_led[i]); + media_entity_cleanup(&flash->subdev_led[i].entity); + } + + return 0; +} + +static const struct i2c_device_id lm3560_id_table[] = { + {LM3560_NAME, 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, lm3560_id_table); + +static struct i2c_driver lm3560_i2c_driver = { + .driver = { + .name = LM3560_NAME, + .pm = NULL, + }, + .probe = lm3560_probe, + .remove = lm3560_remove, + .id_table = lm3560_id_table, +}; + +module_i2c_driver(lm3560_i2c_driver); + +MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); +MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>"); +MODULE_DESCRIPTION("Texas Instruments LM3560 LED flash driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/m5mols/m5mols_controls.c b/drivers/media/i2c/m5mols/m5mols_controls.c index f34429e452a..a60931e6631 100644 --- a/drivers/media/i2c/m5mols/m5mols_controls.c +++ b/drivers/media/i2c/m5mols/m5mols_controls.c @@ -544,7 +544,7 @@ int m5mols_init_controls(struct v4l2_subdev *sd) u16 zoom_step; int ret; - /* Determine the firmware dependant control range and step values */ + /* Determine the firmware dependent control range and step values */ ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &exposure_max); if (ret < 0) return ret; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 4734836fe5a..1c2303d18bf 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/log2.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/of_gpio.h> #include <linux/pm.h> #include <linux/regulator/consumer.h> diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index b76ec0e7e68..e7f555cc827 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1460,7 +1460,7 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd) mutex_unlock(&state->lock); v4l2_dbg(1, s5c73m3_dbg, sd, "%s: Booting %s (%d)\n", - __func__, ret ? "failed" : "succeded", ret); + __func__, ret ? "failed" : "succeeded", ret); return ret; } @@ -1581,7 +1581,7 @@ static int s5c73m3_probe(struct i2c_client *client, oif_sd = &state->oif_sd; v4l2_subdev_init(sd, &s5c73m3_subdev_ops); - sd->owner = client->driver->driver.owner; + sd->owner = client->dev.driver->owner; v4l2_set_subdevdata(sd, state); strlcpy(sd->name, "S5C73M3", sizeof(sd->name)); @@ -1651,7 +1651,7 @@ static int s5c73m3_probe(struct i2c_client *client, if (ret < 0) goto out_err; - v4l2_info(sd, "%s: completed succesfully\n", __func__); + v4l2_info(sd, "%s: completed successfully\n", __func__); return 0; out_err: diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h index 9d2c0865224..9dfa516f694 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3.h +++ b/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -393,7 +393,7 @@ struct s5c73m3 { /* External master clock frequency */ u32 mclk_frequency; - /* Video bus type - MIPI-CSI2/paralell */ + /* Video bus type - MIPI-CSI2/parallel */ enum v4l2_mbus_type bus_type; const struct s5c73m3_frame_size *sensor_pix_size[2]; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 637d0263452..afdbcb045ce 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1699,7 +1699,7 @@ static void saa711x_write_platform_data(struct saa711x_state *state, * the analog demod. * If the tuner is not found, it returns -ENODEV. * If auto-detection is disabled and the tuner doesn't match what it was - * requred, it returns -EINVAL and fills 'name'. + * required, it returns -EINVAL and fills 'name'. * If the chip is found, it returns the chip ID and fills 'name'. */ static int saa711x_detect_chip(struct i2c_client *client, diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index 1d384a371b4..5b915936c3f 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -451,7 +451,9 @@ static int imx074_probe(struct i2c_client *client, if (ret < 0) goto eprobe; - return v4l2_async_register_subdev(&priv->subdev); + ret = v4l2_async_register_subdev(&priv->subdev); + if (!ret) + return 0; epwrinit: eprobe: diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index 0a5c5d4fedd..d2daa6a8f27 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -642,7 +642,7 @@ static const struct ov5642_datafmt static int reg_read(struct i2c_client *client, u16 reg, u8 *val) { int ret; - /* We have 16-bit i2c addresses - care for endianess */ + /* We have 16-bit i2c addresses - care for endianness */ unsigned char data[2] = { reg >> 8, reg & 0xff }; ret = i2c_master_send(client, data, 2); diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index e968c3fdbd9..bc74224503e 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -371,7 +371,7 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_565; break; - }; + } } /* Setup registers according to resolution and color encoding */ diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index 42276d93624..ed9ae887534 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c @@ -83,7 +83,8 @@ static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val) } /* following function is used to set ths7303 */ -int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode) +static int ths7303_setval(struct v4l2_subdev *sd, + enum ths7303_filter_mode mode) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ths7303_state *state = to_state(sd); diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index a58a8f663ff..04139eec8c4 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/v4l2-dv-timings.h> #include <media/v4l2-dv-timings.h> @@ -46,14 +47,10 @@ struct ths8200_state { static const struct v4l2_dv_timings_cap ths8200_timings_cap = { .type = V4L2_DV_BT_656_1120, - .bt = { - .max_width = 1920, - .max_height = 1080, - .min_pixelclock = 25000000, - .max_pixelclock = 148500000, - .standards = V4L2_DV_BT_STD_CEA861, - .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE, - }, + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1080, 25000000, 148500000, + V4L2_DV_BT_STD_CEA861, V4L2_DV_BT_CAP_PROGRESSIVE) }; static inline struct ths8200_state *to_state(struct v4l2_subdev *sd) diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 91f3dd4cda1..83d85df4853 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -35,6 +35,7 @@ #include <linux/videodev2.h> #include <linux/module.h> #include <linux/v4l2-mediabus.h> +#include <linux/of.h> #include <media/v4l2-async.h> #include <media/v4l2-device.h> diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 24a08fa7e32..912e1cccdd1 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -29,6 +29,7 @@ #include <linux/slab.h> #include <linux/videodev2.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/v4l2-dv-timings.h> #include <media/tvp7002.h> #include <media/v4l2-async.h> diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c index 3f584a7d078..bee7946faa7 100644 --- a/drivers/media/i2c/wm8775.c +++ b/drivers/media/i2c/wm8775.c @@ -130,12 +130,10 @@ static int wm8775_s_routing(struct v4l2_subdev *sd, return -EINVAL; } state->input = input; - if (!v4l2_ctrl_g_ctrl(state->mute)) + if (v4l2_ctrl_g_ctrl(state->mute)) return 0; if (!v4l2_ctrl_g_ctrl(state->vol)) return 0; - if (!v4l2_ctrl_g_ctrl(state->bal)) - return 0; wm8775_set_audio(sd, 1); return 0; } |