1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/bitops.h> 4 #include <linux/i2c.h> 5 #include <linux/kernel.h> 6 #include <linux/led-class-flash.h> 7 #include <linux/module.h> 8 #include <linux/mutex.h> 9 #include <linux/property.h> 10 #include <linux/regmap.h> 11 #include <media/v4l2-flash-led-class.h> 12 13 #define RT4505_REG_RESET 0x0 14 #define RT4505_REG_CONFIG 0x8 15 #define RT4505_REG_ILED 0x9 16 #define RT4505_REG_ENABLE 0xA 17 #define RT4505_REG_FLAGS 0xB 18 19 #define RT4505_RESET_MASK BIT(7) 20 #define RT4505_FLASHTO_MASK GENMASK(2, 0) 21 #define RT4505_ITORCH_MASK GENMASK(7, 5) 22 #define RT4505_ITORCH_SHIFT 5 23 #define RT4505_IFLASH_MASK GENMASK(4, 0) 24 #define RT4505_ENABLE_MASK GENMASK(5, 0) 25 #define RT4505_TORCH_SET (BIT(0) | BIT(4)) 26 #define RT4505_FLASH_SET (BIT(0) | BIT(1) | BIT(2) | BIT(4)) 27 #define RT4505_EXT_FLASH_SET (BIT(0) | BIT(1) | BIT(4) | BIT(5)) 28 #define RT4505_FLASH_GET (BIT(0) | BIT(1) | BIT(4)) 29 #define RT4505_OVP_MASK BIT(3) 30 #define RT4505_SHORT_MASK BIT(2) 31 #define RT4505_OTP_MASK BIT(1) 32 #define RT4505_TIMEOUT_MASK BIT(0) 33 34 #define RT4505_ITORCH_MINUA 46000 35 #define RT4505_ITORCH_MAXUA 375000 36 #define RT4505_ITORCH_STPUA 47000 37 #define RT4505_IFLASH_MINUA 93750 38 #define RT4505_IFLASH_MAXUA 1500000 39 #define RT4505_IFLASH_STPUA 93750 40 #define RT4505_FLASHTO_MINUS 100000 41 #define RT4505_FLASHTO_MAXUS 800000 42 #define RT4505_FLASHTO_STPUS 100000 43 44 struct rt4505_priv { 45 struct device *dev; 46 struct regmap *regmap; 47 struct mutex lock; 48 struct led_classdev_flash flash; 49 struct v4l2_flash *v4l2_flash; 50 }; 51 52 static int rt4505_torch_brightness_set(struct led_classdev *lcdev, 53 enum led_brightness level) 54 { 55 struct rt4505_priv *priv = 56 container_of(lcdev, struct rt4505_priv, flash.led_cdev); 57 u32 val = 0; 58 int ret; 59 60 mutex_lock(&priv->lock); 61 62 if (level != LED_OFF) { 63 ret = regmap_update_bits(priv->regmap, 64 RT4505_REG_ILED, RT4505_ITORCH_MASK, 65 (level - 1) << RT4505_ITORCH_SHIFT); 66 if (ret) 67 goto unlock; 68 69 val = RT4505_TORCH_SET; 70 } 71 72 ret = regmap_update_bits(priv->regmap, RT4505_REG_ENABLE, 73 RT4505_ENABLE_MASK, val); 74 75 unlock: 76 mutex_unlock(&priv->lock); 77 return ret; 78 } 79 80 static enum led_brightness rt4505_torch_brightness_get( 81 struct led_classdev *lcdev) 82 { 83 struct rt4505_priv *priv = 84 container_of(lcdev, struct rt4505_priv, flash.led_cdev); 85 u32 val; 86 int ret; 87 88 mutex_lock(&priv->lock); 89 90 ret = regmap_read(priv->regmap, RT4505_REG_ENABLE, &val); 91 if (ret) { 92 dev_err(lcdev->dev, "Failed to get LED enable\n"); 93 ret = LED_OFF; 94 goto unlock; 95 } 96 97 if ((val & RT4505_ENABLE_MASK) != RT4505_TORCH_SET) { 98 ret = LED_OFF; 99 goto unlock; 100 } 101 102 ret = regmap_read(priv->regmap, RT4505_REG_ILED, &val); 103 if (ret) { 104 dev_err(lcdev->dev, "Failed to get LED brightness\n"); 105 ret = LED_OFF; 106 goto unlock; 107 } 108 109 ret = ((val & RT4505_ITORCH_MASK) >> RT4505_ITORCH_SHIFT) + 1; 110 111 unlock: 112 mutex_unlock(&priv->lock); 113 return ret; 114 } 115 116 static int rt4505_flash_brightness_set(struct led_classdev_flash *fled_cdev, 117 u32 brightness) 118 { 119 struct rt4505_priv *priv = 120 container_of(fled_cdev, struct rt4505_priv, flash); 121 struct led_flash_setting *s = &fled_cdev->brightness; 122 u32 val = (brightness - s->min) / s->step; 123 int ret; 124 125 mutex_lock(&priv->lock); 126 ret = regmap_update_bits(priv->regmap, RT4505_REG_ILED, 127 RT4505_IFLASH_MASK, val); 128 mutex_unlock(&priv->lock); 129 130 return ret; 131 } 132 133 static int rt4505_flash_strobe_set(struct led_classdev_flash *fled_cdev, 134 bool state) 135 { 136 struct rt4505_priv *priv = 137 container_of(fled_cdev, struct rt4505_priv, flash); 138 u32 val = state ? RT4505_FLASH_SET : 0; 139 int ret; 140 141 mutex_lock(&priv->lock); 142 ret = regmap_update_bits(priv->regmap, RT4505_REG_ENABLE, 143 RT4505_ENABLE_MASK, val); 144 mutex_unlock(&priv->lock); 145 146 return ret; 147 } 148 149 static int rt4505_flash_strobe_get(struct led_classdev_flash *fled_cdev, 150 bool *state) 151 { 152 struct rt4505_priv *priv = 153 container_of(fled_cdev, struct rt4505_priv, flash); 154 u32 val; 155 int ret; 156 157 mutex_lock(&priv->lock); 158 159 ret = regmap_read(priv->regmap, RT4505_REG_ENABLE, &val); 160 if (ret) 161 goto unlock; 162 163 *state = (val & RT4505_FLASH_GET) == RT4505_FLASH_GET; 164 165 unlock: 166 mutex_unlock(&priv->lock); 167 return ret; 168 } 169 170 static int rt4505_flash_timeout_set(struct led_classdev_flash *fled_cdev, 171 u32 timeout) 172 { 173 struct rt4505_priv *priv = 174 container_of(fled_cdev, struct rt4505_priv, flash); 175 struct led_flash_setting *s = &fled_cdev->timeout; 176 u32 val = (timeout - s->min) / s->step; 177 int ret; 178 179 mutex_lock(&priv->lock); 180 ret = regmap_update_bits(priv->regmap, RT4505_REG_CONFIG, 181 RT4505_FLASHTO_MASK, val); 182 mutex_unlock(&priv->lock); 183 184 return ret; 185 } 186 187 static int rt4505_fault_get(struct led_classdev_flash *fled_cdev, u32 *fault) 188 { 189 struct rt4505_priv *priv = 190 container_of(fled_cdev, struct rt4505_priv, flash); 191 u32 val, led_faults = 0; 192 int ret; 193 194 ret = regmap_read(priv->regmap, RT4505_REG_FLAGS, &val); 195 if (ret) 196 return ret; 197 198 if (val & RT4505_OVP_MASK) 199 led_faults |= LED_FAULT_OVER_VOLTAGE; 200 201 if (val & RT4505_SHORT_MASK) 202 led_faults |= LED_FAULT_SHORT_CIRCUIT; 203 204 if (val & RT4505_OTP_MASK) 205 led_faults |= LED_FAULT_OVER_TEMPERATURE; 206 207 if (val & RT4505_TIMEOUT_MASK) 208 led_faults |= LED_FAULT_TIMEOUT; 209 210 *fault = led_faults; 211 return 0; 212 } 213 214 static const struct led_flash_ops rt4505_flash_ops = { 215 .flash_brightness_set = rt4505_flash_brightness_set, 216 .strobe_set = rt4505_flash_strobe_set, 217 .strobe_get = rt4505_flash_strobe_get, 218 .timeout_set = rt4505_flash_timeout_set, 219 .fault_get = rt4505_fault_get, 220 }; 221 222 static bool rt4505_is_accessible_reg(struct device *dev, unsigned int reg) 223 { 224 if (reg == RT4505_REG_RESET || 225 (reg >= RT4505_REG_CONFIG && reg <= RT4505_REG_FLAGS)) 226 return true; 227 return false; 228 } 229 230 static const struct regmap_config rt4505_regmap_config = { 231 .reg_bits = 8, 232 .val_bits = 8, 233 .max_register = RT4505_REG_FLAGS, 234 235 .readable_reg = rt4505_is_accessible_reg, 236 .writeable_reg = rt4505_is_accessible_reg, 237 }; 238 239 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS) 240 static int rt4505_flash_external_strobe_set(struct v4l2_flash *v4l2_flash, 241 bool enable) 242 { 243 struct led_classdev_flash *flash = v4l2_flash->fled_cdev; 244 struct rt4505_priv *priv = 245 container_of(flash, struct rt4505_priv, flash); 246 u32 val = enable ? RT4505_EXT_FLASH_SET : 0; 247 int ret; 248 249 mutex_lock(&priv->lock); 250 ret = regmap_update_bits(priv->regmap, RT4505_REG_ENABLE, 251 RT4505_ENABLE_MASK, val); 252 mutex_unlock(&priv->lock); 253 254 return ret; 255 } 256 257 static const struct v4l2_flash_ops v4l2_flash_ops = { 258 .external_strobe_set = rt4505_flash_external_strobe_set, 259 }; 260 261 static void rt4505_init_v4l2_config(struct rt4505_priv *priv, 262 struct v4l2_flash_config *config) 263 { 264 struct led_classdev_flash *flash = &priv->flash; 265 struct led_classdev *lcdev = &flash->led_cdev; 266 struct led_flash_setting *s; 267 268 strscpy(config->dev_name, lcdev->dev->kobj.name, 269 sizeof(config->dev_name)); 270 271 s = &config->intensity; 272 s->min = RT4505_ITORCH_MINUA; 273 s->step = RT4505_ITORCH_STPUA; 274 s->max = s->val = s->min + (lcdev->max_brightness - 1) * s->step; 275 276 config->flash_faults = LED_FAULT_OVER_VOLTAGE | 277 LED_FAULT_SHORT_CIRCUIT | 278 LED_FAULT_LED_OVER_TEMPERATURE | 279 LED_FAULT_TIMEOUT; 280 config->has_external_strobe = 1; 281 } 282 #else 283 static const struct v4l2_flash_ops v4l2_flash_ops; 284 static void rt4505_init_v4l2_config(struct rt4505_priv *priv, 285 struct v4l2_flash_config *config) 286 { 287 } 288 #endif 289 290 static void rt4505_init_flash_properties(struct rt4505_priv *priv, 291 struct fwnode_handle *child) 292 { 293 struct led_classdev_flash *flash = &priv->flash; 294 struct led_classdev *lcdev = &flash->led_cdev; 295 struct led_flash_setting *s; 296 u32 val; 297 int ret; 298 299 ret = fwnode_property_read_u32(child, "led-max-microamp", &val); 300 if (ret) { 301 dev_warn(priv->dev, "led-max-microamp DT property missing\n"); 302 val = RT4505_ITORCH_MINUA; 303 } else 304 val = clamp_val(val, RT4505_ITORCH_MINUA, RT4505_ITORCH_MAXUA); 305 306 lcdev->max_brightness = 307 (val - RT4505_ITORCH_MINUA) / RT4505_ITORCH_STPUA + 1; 308 lcdev->brightness_set_blocking = rt4505_torch_brightness_set; 309 lcdev->brightness_get = rt4505_torch_brightness_get; 310 lcdev->flags |= LED_DEV_CAP_FLASH; 311 312 ret = fwnode_property_read_u32(child, "flash-max-microamp", &val); 313 if (ret) { 314 dev_warn(priv->dev, "flash-max-microamp DT property missing\n"); 315 val = RT4505_IFLASH_MINUA; 316 } else 317 val = clamp_val(val, RT4505_IFLASH_MINUA, RT4505_IFLASH_MAXUA); 318 319 s = &flash->brightness; 320 s->min = RT4505_IFLASH_MINUA; 321 s->step = RT4505_IFLASH_STPUA; 322 s->max = s->val = val; 323 324 ret = fwnode_property_read_u32(child, "flash-max-timeout-us", &val); 325 if (ret) { 326 dev_warn(priv->dev, 327 "flash-max-timeout-us DT property missing\n"); 328 val = RT4505_FLASHTO_MINUS; 329 } else 330 val = clamp_val(val, RT4505_FLASHTO_MINUS, 331 RT4505_FLASHTO_MAXUS); 332 333 s = &flash->timeout; 334 s->min = RT4505_FLASHTO_MINUS; 335 s->step = RT4505_FLASHTO_STPUS; 336 s->max = s->val = val; 337 338 flash->ops = &rt4505_flash_ops; 339 } 340 341 static int rt4505_probe(struct i2c_client *client) 342 { 343 struct rt4505_priv *priv; 344 struct fwnode_handle *child; 345 struct led_init_data init_data = {}; 346 struct v4l2_flash_config v4l2_config = {}; 347 int ret; 348 349 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); 350 if (!priv) 351 return -ENOMEM; 352 353 priv->dev = &client->dev; 354 mutex_init(&priv->lock); 355 356 priv->regmap = devm_regmap_init_i2c(client, &rt4505_regmap_config); 357 if (IS_ERR(priv->regmap)) { 358 dev_err(priv->dev, "Failed to allocate register map\n"); 359 return PTR_ERR(priv->regmap); 360 } 361 362 ret = regmap_write(priv->regmap, RT4505_REG_RESET, RT4505_RESET_MASK); 363 if (ret) { 364 dev_err(priv->dev, "Failed to reset registers\n"); 365 return ret; 366 } 367 368 child = fwnode_get_next_available_child_node(client->dev.fwnode, NULL); 369 if (!child) { 370 dev_err(priv->dev, "Failed to get child node\n"); 371 return -EINVAL; 372 } 373 init_data.fwnode = child; 374 375 rt4505_init_flash_properties(priv, child); 376 ret = devm_led_classdev_flash_register_ext(priv->dev, &priv->flash, 377 &init_data); 378 if (ret) { 379 dev_err(priv->dev, "Failed to register flash\n"); 380 return ret; 381 } 382 383 rt4505_init_v4l2_config(priv, &v4l2_config); 384 priv->v4l2_flash = v4l2_flash_init(priv->dev, init_data.fwnode, 385 &priv->flash, &v4l2_flash_ops, 386 &v4l2_config); 387 if (IS_ERR(priv->v4l2_flash)) { 388 dev_err(priv->dev, "Failed to register v4l2 flash\n"); 389 return PTR_ERR(priv->v4l2_flash); 390 } 391 392 i2c_set_clientdata(client, priv); 393 return 0; 394 } 395 396 static int rt4505_remove(struct i2c_client *client) 397 { 398 struct rt4505_priv *priv = i2c_get_clientdata(client); 399 400 v4l2_flash_release(priv->v4l2_flash); 401 return 0; 402 } 403 404 static void rt4505_shutdown(struct i2c_client *client) 405 { 406 struct rt4505_priv *priv = i2c_get_clientdata(client); 407 408 /* Reset registers to make sure all off before shutdown */ 409 regmap_write(priv->regmap, RT4505_REG_RESET, RT4505_RESET_MASK); 410 } 411 412 static const struct of_device_id __maybe_unused rt4505_leds_match[] = { 413 { .compatible = "richtek,rt4505", }, 414 {} 415 }; 416 MODULE_DEVICE_TABLE(of, rt4505_leds_match); 417 418 static struct i2c_driver rt4505_driver = { 419 .driver = { 420 .name = "rt4505", 421 .of_match_table = of_match_ptr(rt4505_leds_match), 422 }, 423 .probe_new = rt4505_probe, 424 .remove = rt4505_remove, 425 .shutdown = rt4505_shutdown, 426 }; 427 module_i2c_driver(rt4505_driver); 428 429 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 430 MODULE_LICENSE("GPL v2"); 431