Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * drivers/media/i2c/lm3646.c
0004  * General device driver for TI lm3646, Dual FLASH LED Driver
0005  *
0006  * Copyright (C) 2014 Texas Instruments
0007  *
0008  * Contact: Daniel Jeong <gshark.jeong@gmail.com>
0009  *          Ldd-Mlp <ldd-mlp@list.ti.com>
0010  */
0011 
0012 #include <linux/delay.h>
0013 #include <linux/i2c.h>
0014 #include <linux/module.h>
0015 #include <linux/slab.h>
0016 #include <linux/regmap.h>
0017 #include <linux/videodev2.h>
0018 #include <media/i2c/lm3646.h>
0019 #include <media/v4l2-ctrls.h>
0020 #include <media/v4l2-device.h>
0021 
0022 /* registers definitions */
0023 #define REG_ENABLE      0x01
0024 #define REG_TORCH_BR    0x05
0025 #define REG_FLASH_BR    0x05
0026 #define REG_FLASH_TOUT  0x04
0027 #define REG_FLAG        0x08
0028 #define REG_STROBE_SRC  0x06
0029 #define REG_LED1_FLASH_BR 0x06
0030 #define REG_LED1_TORCH_BR 0x07
0031 
0032 #define MASK_ENABLE     0x03
0033 #define MASK_TORCH_BR   0x70
0034 #define MASK_FLASH_BR   0x0F
0035 #define MASK_FLASH_TOUT 0x07
0036 #define MASK_FLAG       0xFF
0037 #define MASK_STROBE_SRC 0x80
0038 
0039 /* Fault Mask */
0040 #define FAULT_TIMEOUT   (1<<0)
0041 #define FAULT_SHORT_CIRCUIT (1<<1)
0042 #define FAULT_UVLO      (1<<2)
0043 #define FAULT_IVFM      (1<<3)
0044 #define FAULT_OCP       (1<<4)
0045 #define FAULT_OVERTEMP  (1<<5)
0046 #define FAULT_NTC_TRIP  (1<<6)
0047 #define FAULT_OVP       (1<<7)
0048 
0049 enum led_mode {
0050     MODE_SHDN = 0x0,
0051     MODE_TORCH = 0x2,
0052     MODE_FLASH = 0x3,
0053 };
0054 
0055 /*
0056  * struct lm3646_flash
0057  *
0058  * @pdata: platform data
0059  * @regmap: reg. map for i2c
0060  * @lock: muxtex for serial access.
0061  * @led_mode: V4L2 LED mode
0062  * @ctrls_led: V4L2 controls
0063  * @subdev_led: V4L2 subdev
0064  * @mode_reg : mode register value
0065  */
0066 struct lm3646_flash {
0067     struct device *dev;
0068     struct lm3646_platform_data *pdata;
0069     struct regmap *regmap;
0070 
0071     struct v4l2_ctrl_handler ctrls_led;
0072     struct v4l2_subdev subdev_led;
0073 
0074     u8 mode_reg;
0075 };
0076 
0077 #define to_lm3646_flash(_ctrl)  \
0078     container_of(_ctrl->handler, struct lm3646_flash, ctrls_led)
0079 
0080 /* enable mode control */
0081 static int lm3646_mode_ctrl(struct lm3646_flash *flash,
0082                 enum v4l2_flash_led_mode led_mode)
0083 {
0084     switch (led_mode) {
0085     case V4L2_FLASH_LED_MODE_NONE:
0086         return regmap_write(flash->regmap,
0087                     REG_ENABLE, flash->mode_reg | MODE_SHDN);
0088     case V4L2_FLASH_LED_MODE_TORCH:
0089         return regmap_write(flash->regmap,
0090                     REG_ENABLE, flash->mode_reg | MODE_TORCH);
0091     case V4L2_FLASH_LED_MODE_FLASH:
0092         return regmap_write(flash->regmap,
0093                     REG_ENABLE, flash->mode_reg | MODE_FLASH);
0094     }
0095     return -EINVAL;
0096 }
0097 
0098 /* V4L2 controls  */
0099 static int lm3646_get_ctrl(struct v4l2_ctrl *ctrl)
0100 {
0101     struct lm3646_flash *flash = to_lm3646_flash(ctrl);
0102     unsigned int reg_val;
0103     int rval;
0104 
0105     if (ctrl->id != V4L2_CID_FLASH_FAULT)
0106         return -EINVAL;
0107 
0108     rval = regmap_read(flash->regmap, REG_FLAG, &reg_val);
0109     if (rval < 0)
0110         return rval;
0111 
0112     ctrl->val = 0;
0113     if (reg_val & FAULT_TIMEOUT)
0114         ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT;
0115     if (reg_val & FAULT_SHORT_CIRCUIT)
0116         ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
0117     if (reg_val & FAULT_UVLO)
0118         ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE;
0119     if (reg_val & FAULT_IVFM)
0120         ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE;
0121     if (reg_val & FAULT_OCP)
0122         ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT;
0123     if (reg_val & FAULT_OVERTEMP)
0124         ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
0125     if (reg_val & FAULT_NTC_TRIP)
0126         ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE;
0127     if (reg_val & FAULT_OVP)
0128         ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
0129 
0130     return 0;
0131 }
0132 
0133 static int lm3646_set_ctrl(struct v4l2_ctrl *ctrl)
0134 {
0135     struct lm3646_flash *flash = to_lm3646_flash(ctrl);
0136     unsigned int reg_val;
0137     int rval;
0138 
0139     switch (ctrl->id) {
0140     case V4L2_CID_FLASH_LED_MODE:
0141 
0142         if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH)
0143             return lm3646_mode_ctrl(flash, ctrl->val);
0144         /* switch to SHDN mode before flash strobe on */
0145         return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
0146 
0147     case V4L2_CID_FLASH_STROBE_SOURCE:
0148         return regmap_update_bits(flash->regmap,
0149                       REG_STROBE_SRC, MASK_STROBE_SRC,
0150                       (ctrl->val) << 7);
0151 
0152     case V4L2_CID_FLASH_STROBE:
0153 
0154         /* read and check current mode of chip to start flash */
0155         rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
0156         if (rval < 0 || ((reg_val & MASK_ENABLE) != MODE_SHDN))
0157             return rval;
0158         /* flash on */
0159         return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_FLASH);
0160 
0161     case V4L2_CID_FLASH_STROBE_STOP:
0162 
0163         /*
0164          * flash mode will be turned automatically
0165          * from FLASH mode to SHDN mode after flash duration timeout
0166          * read and check current mode of chip to stop flash
0167          */
0168         rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
0169         if (rval < 0)
0170             return rval;
0171         if ((reg_val & MASK_ENABLE) == MODE_FLASH)
0172             return lm3646_mode_ctrl(flash,
0173                         V4L2_FLASH_LED_MODE_NONE);
0174         return rval;
0175 
0176     case V4L2_CID_FLASH_TIMEOUT:
0177         return regmap_update_bits(flash->regmap,
0178                       REG_FLASH_TOUT, MASK_FLASH_TOUT,
0179                       LM3646_FLASH_TOUT_ms_TO_REG
0180                       (ctrl->val));
0181 
0182     case V4L2_CID_FLASH_INTENSITY:
0183         return regmap_update_bits(flash->regmap,
0184                       REG_FLASH_BR, MASK_FLASH_BR,
0185                       LM3646_TOTAL_FLASH_BRT_uA_TO_REG
0186                       (ctrl->val));
0187 
0188     case V4L2_CID_FLASH_TORCH_INTENSITY:
0189         return regmap_update_bits(flash->regmap,
0190                       REG_TORCH_BR, MASK_TORCH_BR,
0191                       LM3646_TOTAL_TORCH_BRT_uA_TO_REG
0192                       (ctrl->val) << 4);
0193     }
0194 
0195     return -EINVAL;
0196 }
0197 
0198 static const struct v4l2_ctrl_ops lm3646_led_ctrl_ops = {
0199     .g_volatile_ctrl = lm3646_get_ctrl,
0200     .s_ctrl = lm3646_set_ctrl,
0201 };
0202 
0203 static int lm3646_init_controls(struct lm3646_flash *flash)
0204 {
0205     struct v4l2_ctrl *fault;
0206     struct v4l2_ctrl_handler *hdl = &flash->ctrls_led;
0207     const struct v4l2_ctrl_ops *ops = &lm3646_led_ctrl_ops;
0208 
0209     v4l2_ctrl_handler_init(hdl, 8);
0210     /* flash mode */
0211     v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
0212                    V4L2_FLASH_LED_MODE_TORCH, ~0x7,
0213                    V4L2_FLASH_LED_MODE_NONE);
0214 
0215     /* flash source */
0216     v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE,
0217                    0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
0218 
0219     /* flash strobe */
0220     v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
0221     /* flash strobe stop */
0222     v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
0223 
0224     /* flash strobe timeout */
0225     v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT,
0226               LM3646_FLASH_TOUT_MIN,
0227               LM3646_FLASH_TOUT_MAX,
0228               LM3646_FLASH_TOUT_STEP, flash->pdata->flash_timeout);
0229 
0230     /* max flash current */
0231     v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
0232               LM3646_TOTAL_FLASH_BRT_MIN,
0233               LM3646_TOTAL_FLASH_BRT_MAX,
0234               LM3646_TOTAL_FLASH_BRT_STEP,
0235               LM3646_TOTAL_FLASH_BRT_MAX);
0236 
0237     /* max torch current */
0238     v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY,
0239               LM3646_TOTAL_TORCH_BRT_MIN,
0240               LM3646_TOTAL_TORCH_BRT_MAX,
0241               LM3646_TOTAL_TORCH_BRT_STEP,
0242               LM3646_TOTAL_TORCH_BRT_MAX);
0243 
0244     /* fault */
0245     fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0,
0246                   V4L2_FLASH_FAULT_OVER_VOLTAGE
0247                   | V4L2_FLASH_FAULT_OVER_TEMPERATURE
0248                   | V4L2_FLASH_FAULT_SHORT_CIRCUIT
0249                   | V4L2_FLASH_FAULT_TIMEOUT, 0, 0);
0250     if (fault != NULL)
0251         fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
0252 
0253     if (hdl->error)
0254         return hdl->error;
0255 
0256     flash->subdev_led.ctrl_handler = hdl;
0257     return 0;
0258 }
0259 
0260 /* initialize device */
0261 static const struct v4l2_subdev_ops lm3646_ops = {
0262     .core = NULL,
0263 };
0264 
0265 static const struct regmap_config lm3646_regmap = {
0266     .reg_bits = 8,
0267     .val_bits = 8,
0268     .max_register = 0xFF,
0269 };
0270 
0271 static int lm3646_subdev_init(struct lm3646_flash *flash)
0272 {
0273     struct i2c_client *client = to_i2c_client(flash->dev);
0274     int rval;
0275 
0276     v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops);
0277     flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
0278     strscpy(flash->subdev_led.name, LM3646_NAME,
0279         sizeof(flash->subdev_led.name));
0280     rval = lm3646_init_controls(flash);
0281     if (rval)
0282         goto err_out;
0283     rval = media_entity_pads_init(&flash->subdev_led.entity, 0, NULL);
0284     if (rval < 0)
0285         goto err_out;
0286     flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH;
0287     return rval;
0288 
0289 err_out:
0290     v4l2_ctrl_handler_free(&flash->ctrls_led);
0291     return rval;
0292 }
0293 
0294 static int lm3646_init_device(struct lm3646_flash *flash)
0295 {
0296     unsigned int reg_val;
0297     int rval;
0298 
0299     /* read the value of mode register to reduce redundant i2c accesses */
0300     rval = regmap_read(flash->regmap, REG_ENABLE, &reg_val);
0301     if (rval < 0)
0302         return rval;
0303     flash->mode_reg = reg_val & 0xfc;
0304 
0305     /* output disable */
0306     rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
0307     if (rval < 0)
0308         return rval;
0309 
0310     /*
0311      * LED1 flash current setting
0312      * LED2 flash current = Total(Max) flash current - LED1 flash current
0313      */
0314     rval = regmap_update_bits(flash->regmap,
0315                   REG_LED1_FLASH_BR, 0x7F,
0316                   LM3646_LED1_FLASH_BRT_uA_TO_REG
0317                   (flash->pdata->led1_flash_brt));
0318 
0319     if (rval < 0)
0320         return rval;
0321 
0322     /*
0323      * LED1 torch current setting
0324      * LED2 torch current = Total(Max) torch current - LED1 torch current
0325      */
0326     rval = regmap_update_bits(flash->regmap,
0327                   REG_LED1_TORCH_BR, 0x7F,
0328                   LM3646_LED1_TORCH_BRT_uA_TO_REG
0329                   (flash->pdata->led1_torch_brt));
0330     if (rval < 0)
0331         return rval;
0332 
0333     /* Reset flag register */
0334     return regmap_read(flash->regmap, REG_FLAG, &reg_val);
0335 }
0336 
0337 static int lm3646_probe(struct i2c_client *client,
0338             const struct i2c_device_id *devid)
0339 {
0340     struct lm3646_flash *flash;
0341     struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev);
0342     int rval;
0343 
0344     flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
0345     if (flash == NULL)
0346         return -ENOMEM;
0347 
0348     flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap);
0349     if (IS_ERR(flash->regmap))
0350         return PTR_ERR(flash->regmap);
0351 
0352     /* check device tree if there is no platform data */
0353     if (pdata == NULL) {
0354         pdata = devm_kzalloc(&client->dev,
0355                      sizeof(struct lm3646_platform_data),
0356                      GFP_KERNEL);
0357         if (pdata == NULL)
0358             return -ENOMEM;
0359         /* use default data in case of no platform data */
0360         pdata->flash_timeout = LM3646_FLASH_TOUT_MAX;
0361         pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX;
0362         pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX;
0363     }
0364     flash->pdata = pdata;
0365     flash->dev = &client->dev;
0366 
0367     rval = lm3646_subdev_init(flash);
0368     if (rval < 0)
0369         return rval;
0370 
0371     rval = lm3646_init_device(flash);
0372     if (rval < 0)
0373         return rval;
0374 
0375     i2c_set_clientdata(client, flash);
0376 
0377     return 0;
0378 }
0379 
0380 static int lm3646_remove(struct i2c_client *client)
0381 {
0382     struct lm3646_flash *flash = i2c_get_clientdata(client);
0383 
0384     v4l2_device_unregister_subdev(&flash->subdev_led);
0385     v4l2_ctrl_handler_free(&flash->ctrls_led);
0386     media_entity_cleanup(&flash->subdev_led.entity);
0387 
0388     return 0;
0389 }
0390 
0391 static const struct i2c_device_id lm3646_id_table[] = {
0392     {LM3646_NAME, 0},
0393     {}
0394 };
0395 
0396 MODULE_DEVICE_TABLE(i2c, lm3646_id_table);
0397 
0398 static struct i2c_driver lm3646_i2c_driver = {
0399     .driver = {
0400            .name = LM3646_NAME,
0401            },
0402     .probe = lm3646_probe,
0403     .remove = lm3646_remove,
0404     .id_table = lm3646_id_table,
0405 };
0406 
0407 module_i2c_driver(lm3646_i2c_driver);
0408 
0409 MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>");
0410 MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");
0411 MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver");
0412 MODULE_LICENSE("GPL");