471 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2011 bct electronic GmbH4 * Copyright 2013 Qtechnology/AS5 *6 * Author: Peter Meerwald <p.meerwald@bct-electronic.com>7 * Author: Ricardo Ribalda <ribalda@kernel.org>8 *9 * Based on leds-pca955x.c10 *11 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)12 * LED driver for the PCA9634/5 I2C LED driver (7-bit slave address set by hw.)13 *14 * Note that hardware blinking violates the leds infrastructure driver15 * interface since the hardware only supports blinking all LEDs with the16 * same delay_on/delay_off rates. That is, only the LEDs that are set to17 * blink will actually blink but all LEDs that are set to blink will blink18 * in identical fashion. The delay_on/delay_off values of the last LED19 * that is set to blink will be used for all of the blinking LEDs.20 * Hardware blinking is disabled by default but can be enabled by setting21 * the 'blink_type' member in the platform_data struct to 'PCA963X_HW_BLINK'22 * or by adding the 'nxp,hw-blink' property to the DTS.23 */24 25#include <linux/module.h>26#include <linux/delay.h>27#include <linux/string.h>28#include <linux/ctype.h>29#include <linux/leds.h>30#include <linux/err.h>31#include <linux/i2c.h>32#include <linux/property.h>33#include <linux/slab.h>34#include <linux/of.h>35 36/* LED select registers determine the source that drives LED outputs */37#define PCA963X_LED_OFF 0x0 /* LED driver off */38#define PCA963X_LED_ON 0x1 /* LED driver on */39#define PCA963X_LED_PWM 0x2 /* Controlled through PWM */40#define PCA963X_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */41 42#define PCA963X_MODE1_SLEEP 0x04 /* Normal mode or Low Power mode, oscillator off */43#define PCA963X_MODE2_OUTDRV 0x04 /* Open-drain or totem pole */44#define PCA963X_MODE2_INVRT 0x10 /* Normal or inverted direction */45#define PCA963X_MODE2_DMBLNK 0x20 /* Enable blinking */46 47#define PCA963X_MODE1 0x0048#define PCA963X_MODE2 0x0149#define PCA963X_PWM_BASE 0x0250 51enum pca963x_type {52 pca9633,53 pca9634,54 pca9635,55};56 57struct pca963x_chipdef {58 u8 grppwm;59 u8 grpfreq;60 u8 ledout_base;61 int n_leds;62 unsigned int scaling;63};64 65static struct pca963x_chipdef pca963x_chipdefs[] = {66 [pca9633] = {67 .grppwm = 0x6,68 .grpfreq = 0x7,69 .ledout_base = 0x8,70 .n_leds = 4,71 },72 [pca9634] = {73 .grppwm = 0xa,74 .grpfreq = 0xb,75 .ledout_base = 0xc,76 .n_leds = 8,77 },78 [pca9635] = {79 .grppwm = 0x12,80 .grpfreq = 0x13,81 .ledout_base = 0x14,82 .n_leds = 16,83 },84};85 86/* Total blink period in milliseconds */87#define PCA963X_BLINK_PERIOD_MIN 4288#define PCA963X_BLINK_PERIOD_MAX 1066789 90static const struct i2c_device_id pca963x_id[] = {91 { "pca9632", pca9633 },92 { "pca9633", pca9633 },93 { "pca9634", pca9634 },94 { "pca9635", pca9635 },95 { }96};97MODULE_DEVICE_TABLE(i2c, pca963x_id);98 99struct pca963x;100 101struct pca963x_led {102 struct pca963x *chip;103 struct led_classdev led_cdev;104 int led_num; /* 0 .. 15 potentially */105 bool blinking;106 u8 gdc;107 u8 gfrq;108};109 110struct pca963x {111 struct pca963x_chipdef *chipdef;112 struct mutex mutex;113 struct i2c_client *client;114 unsigned long leds_on;115 struct pca963x_led leds[];116};117 118static int pca963x_brightness(struct pca963x_led *led,119 enum led_brightness brightness)120{121 struct i2c_client *client = led->chip->client;122 struct pca963x_chipdef *chipdef = led->chip->chipdef;123 u8 ledout_addr, ledout, mask, val;124 int shift;125 int ret;126 127 ledout_addr = chipdef->ledout_base + (led->led_num / 4);128 shift = 2 * (led->led_num % 4);129 mask = 0x3 << shift;130 ledout = i2c_smbus_read_byte_data(client, ledout_addr);131 132 switch (brightness) {133 case LED_FULL:134 if (led->blinking) {135 val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift);136 ret = i2c_smbus_write_byte_data(client,137 PCA963X_PWM_BASE +138 led->led_num,139 LED_FULL);140 } else {141 val = (ledout & ~mask) | (PCA963X_LED_ON << shift);142 }143 ret = i2c_smbus_write_byte_data(client, ledout_addr, val);144 break;145 case LED_OFF:146 val = ledout & ~mask;147 ret = i2c_smbus_write_byte_data(client, ledout_addr, val);148 led->blinking = false;149 break;150 default:151 ret = i2c_smbus_write_byte_data(client,152 PCA963X_PWM_BASE +153 led->led_num,154 brightness);155 if (ret < 0)156 return ret;157 158 if (led->blinking)159 val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift);160 else161 val = (ledout & ~mask) | (PCA963X_LED_PWM << shift);162 163 ret = i2c_smbus_write_byte_data(client, ledout_addr, val);164 break;165 }166 167 return ret;168}169 170static void pca963x_blink(struct pca963x_led *led)171{172 struct i2c_client *client = led->chip->client;173 struct pca963x_chipdef *chipdef = led->chip->chipdef;174 u8 ledout_addr, ledout, mask, val, mode2;175 int shift;176 177 ledout_addr = chipdef->ledout_base + (led->led_num / 4);178 shift = 2 * (led->led_num % 4);179 mask = 0x3 << shift;180 mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);181 182 i2c_smbus_write_byte_data(client, chipdef->grppwm, led->gdc);183 184 i2c_smbus_write_byte_data(client, chipdef->grpfreq, led->gfrq);185 186 if (!(mode2 & PCA963X_MODE2_DMBLNK))187 i2c_smbus_write_byte_data(client, PCA963X_MODE2,188 mode2 | PCA963X_MODE2_DMBLNK);189 190 mutex_lock(&led->chip->mutex);191 192 ledout = i2c_smbus_read_byte_data(client, ledout_addr);193 if ((ledout & mask) != (PCA963X_LED_GRP_PWM << shift)) {194 val = (ledout & ~mask) | (PCA963X_LED_GRP_PWM << shift);195 i2c_smbus_write_byte_data(client, ledout_addr, val);196 }197 198 mutex_unlock(&led->chip->mutex);199 led->blinking = true;200}201 202static int pca963x_power_state(struct pca963x_led *led)203{204 struct i2c_client *client = led->chip->client;205 unsigned long *leds_on = &led->chip->leds_on;206 unsigned long cached_leds = *leds_on;207 208 if (led->led_cdev.brightness)209 set_bit(led->led_num, leds_on);210 else211 clear_bit(led->led_num, leds_on);212 213 if (!(*leds_on) != !cached_leds)214 return i2c_smbus_write_byte_data(client, PCA963X_MODE1,215 *leds_on ? 0 : BIT(4));216 217 return 0;218}219 220static int pca963x_led_set(struct led_classdev *led_cdev,221 enum led_brightness value)222{223 struct pca963x_led *led;224 int ret;225 226 led = container_of(led_cdev, struct pca963x_led, led_cdev);227 228 mutex_lock(&led->chip->mutex);229 230 ret = pca963x_brightness(led, value);231 if (ret < 0)232 goto unlock;233 ret = pca963x_power_state(led);234 235unlock:236 mutex_unlock(&led->chip->mutex);237 return ret;238}239 240static unsigned int pca963x_period_scale(struct pca963x_led *led,241 unsigned int val)242{243 unsigned int scaling = led->chip->chipdef->scaling;244 245 return scaling ? DIV_ROUND_CLOSEST(val * scaling, 1000) : val;246}247 248static int pca963x_blink_set(struct led_classdev *led_cdev,249 unsigned long *delay_on, unsigned long *delay_off)250{251 unsigned long time_on, time_off, period;252 struct pca963x_led *led;253 u8 gdc, gfrq;254 255 led = container_of(led_cdev, struct pca963x_led, led_cdev);256 257 time_on = *delay_on;258 time_off = *delay_off;259 260 /* If both zero, pick reasonable defaults of 500ms each */261 if (!time_on && !time_off) {262 time_on = 500;263 time_off = 500;264 }265 266 period = pca963x_period_scale(led, time_on + time_off);267 268 /* If period not supported by hardware, default to someting sane. */269 if ((period < PCA963X_BLINK_PERIOD_MIN) ||270 (period > PCA963X_BLINK_PERIOD_MAX)) {271 time_on = 500;272 time_off = 500;273 period = pca963x_period_scale(led, 1000);274 }275 276 /*277 * From manual: duty cycle = (GDC / 256) ->278 * (time_on / period) = (GDC / 256) ->279 * GDC = ((time_on * 256) / period)280 */281 gdc = (pca963x_period_scale(led, time_on) * 256) / period;282 283 /*284 * From manual: period = ((GFRQ + 1) / 24) in seconds.285 * So, period (in ms) = (((GFRQ + 1) / 24) * 1000) ->286 * GFRQ = ((period * 24 / 1000) - 1)287 */288 gfrq = (period * 24 / 1000) - 1;289 290 led->gdc = gdc;291 led->gfrq = gfrq;292 293 pca963x_blink(led);294 led->led_cdev.brightness = LED_FULL;295 pca963x_led_set(led_cdev, LED_FULL);296 297 *delay_on = time_on;298 *delay_off = time_off;299 300 return 0;301}302 303static int pca963x_register_leds(struct i2c_client *client,304 struct pca963x *chip)305{306 struct pca963x_chipdef *chipdef = chip->chipdef;307 struct pca963x_led *led = chip->leds;308 struct device *dev = &client->dev;309 struct fwnode_handle *child;310 bool hw_blink;311 s32 mode2;312 u32 reg;313 int ret;314 315 if (device_property_read_u32(dev, "nxp,period-scale",316 &chipdef->scaling))317 chipdef->scaling = 1000;318 319 hw_blink = device_property_read_bool(dev, "nxp,hw-blink");320 321 mode2 = i2c_smbus_read_byte_data(client, PCA963X_MODE2);322 if (mode2 < 0)323 return mode2;324 325 /* default to open-drain unless totem pole (push-pull) is specified */326 if (device_property_read_bool(dev, "nxp,totem-pole"))327 mode2 |= PCA963X_MODE2_OUTDRV;328 else329 mode2 &= ~PCA963X_MODE2_OUTDRV;330 331 /* default to non-inverted output, unless inverted is specified */332 if (device_property_read_bool(dev, "nxp,inverted-out"))333 mode2 |= PCA963X_MODE2_INVRT;334 else335 mode2 &= ~PCA963X_MODE2_INVRT;336 337 ret = i2c_smbus_write_byte_data(client, PCA963X_MODE2, mode2);338 if (ret < 0)339 return ret;340 341 device_for_each_child_node(dev, child) {342 struct led_init_data init_data = {};343 char default_label[32];344 345 ret = fwnode_property_read_u32(child, "reg", ®);346 if (ret || reg >= chipdef->n_leds) {347 dev_err(dev, "Invalid 'reg' property for node %pfw\n",348 child);349 ret = -EINVAL;350 goto err;351 }352 353 led->led_num = reg;354 led->chip = chip;355 led->led_cdev.brightness_set_blocking = pca963x_led_set;356 if (hw_blink)357 led->led_cdev.blink_set = pca963x_blink_set;358 led->blinking = false;359 360 init_data.fwnode = child;361 /* for backwards compatibility */362 init_data.devicename = "pca963x";363 snprintf(default_label, sizeof(default_label), "%d:%.2x:%u",364 client->adapter->nr, client->addr, reg);365 init_data.default_label = default_label;366 367 ret = devm_led_classdev_register_ext(dev, &led->led_cdev,368 &init_data);369 if (ret) {370 dev_err(dev, "Failed to register LED for node %pfw\n",371 child);372 goto err;373 }374 375 ++led;376 }377 378 return 0;379err:380 fwnode_handle_put(child);381 return ret;382}383 384static int pca963x_suspend(struct device *dev)385{386 struct pca963x *chip = dev_get_drvdata(dev);387 u8 reg;388 389 reg = i2c_smbus_read_byte_data(chip->client, PCA963X_MODE1);390 reg = reg | BIT(PCA963X_MODE1_SLEEP);391 i2c_smbus_write_byte_data(chip->client, PCA963X_MODE1, reg);392 393 return 0;394}395 396static int pca963x_resume(struct device *dev)397{398 struct pca963x *chip = dev_get_drvdata(dev);399 u8 reg;400 401 reg = i2c_smbus_read_byte_data(chip->client, PCA963X_MODE1);402 reg = reg & ~BIT(PCA963X_MODE1_SLEEP);403 i2c_smbus_write_byte_data(chip->client, PCA963X_MODE1, reg);404 405 return 0;406}407 408static DEFINE_SIMPLE_DEV_PM_OPS(pca963x_pm, pca963x_suspend, pca963x_resume);409 410static const struct of_device_id of_pca963x_match[] = {411 { .compatible = "nxp,pca9632", },412 { .compatible = "nxp,pca9633", },413 { .compatible = "nxp,pca9634", },414 { .compatible = "nxp,pca9635", },415 {},416};417MODULE_DEVICE_TABLE(of, of_pca963x_match);418 419static int pca963x_probe(struct i2c_client *client)420{421 const struct i2c_device_id *id = i2c_client_get_device_id(client);422 struct device *dev = &client->dev;423 struct pca963x_chipdef *chipdef;424 struct pca963x *chip;425 int i, count;426 427 chipdef = &pca963x_chipdefs[id->driver_data];428 429 count = device_get_child_node_count(dev);430 if (!count || count > chipdef->n_leds) {431 dev_err(dev, "Node %pfw must define between 1 and %d LEDs\n",432 dev_fwnode(dev), chipdef->n_leds);433 return -EINVAL;434 }435 436 chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL);437 if (!chip)438 return -ENOMEM;439 440 i2c_set_clientdata(client, chip);441 442 mutex_init(&chip->mutex);443 chip->chipdef = chipdef;444 chip->client = client;445 446 /* Turn off LEDs by default*/447 for (i = 0; i < chipdef->n_leds / 4; i++)448 i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00);449 450 /* Disable LED all-call address, and power down initially */451 i2c_smbus_write_byte_data(client, PCA963X_MODE1, BIT(4));452 453 return pca963x_register_leds(client, chip);454}455 456static struct i2c_driver pca963x_driver = {457 .driver = {458 .name = "leds-pca963x",459 .of_match_table = of_pca963x_match,460 .pm = pm_sleep_ptr(&pca963x_pm)461 },462 .probe = pca963x_probe,463 .id_table = pca963x_id,464};465 466module_i2c_driver(pca963x_driver);467 468MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");469MODULE_DESCRIPTION("PCA963X LED driver");470MODULE_LICENSE("GPL v2");471