0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/delay.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/i2c.h>
0012 #include <linux/io.h>
0013 #include <linux/kernel.h>
0014 #include <linux/leds.h>
0015 #include <linux/leds-lp3952.h>
0016 #include <linux/module.h>
0017 #include <linux/notifier.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm.h>
0020 #include <linux/reboot.h>
0021 #include <linux/regmap.h>
0022
0023 static int lp3952_register_write(struct i2c_client *client, u8 reg, u8 val)
0024 {
0025 int ret;
0026 struct lp3952_led_array *priv = i2c_get_clientdata(client);
0027
0028 ret = regmap_write(priv->regmap, reg, val);
0029
0030 if (ret)
0031 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
0032 __func__, reg, val, ret);
0033 return ret;
0034 }
0035
0036 static void lp3952_on_off(struct lp3952_led_array *priv,
0037 enum lp3952_leds led_id, bool on)
0038 {
0039 int ret, val;
0040
0041 dev_dbg(&priv->client->dev, "%s LED %d to %d\n", __func__, led_id, on);
0042
0043 val = 1 << led_id;
0044 if (led_id == LP3952_LED_ALL)
0045 val = LP3952_LED_MASK_ALL;
0046
0047 ret = regmap_update_bits(priv->regmap, LP3952_REG_LED_CTRL, val,
0048 on ? val : 0);
0049 if (ret)
0050 dev_err(&priv->client->dev, "%s, Error %d\n", __func__, ret);
0051 }
0052
0053
0054
0055
0056
0057
0058 static int lp3952_set_brightness(struct led_classdev *cdev,
0059 enum led_brightness value)
0060 {
0061 unsigned int reg, shift_val;
0062 struct lp3952_ctrl_hdl *led = container_of(cdev,
0063 struct lp3952_ctrl_hdl,
0064 cdev);
0065 struct lp3952_led_array *priv = (struct lp3952_led_array *)led->priv;
0066
0067 dev_dbg(cdev->dev, "Brightness request: %d on %d\n", value,
0068 led->channel);
0069
0070 if (value == LED_OFF) {
0071 lp3952_on_off(priv, led->channel, false);
0072 return 0;
0073 }
0074
0075 if (led->channel > LP3952_RED_1) {
0076 dev_err(cdev->dev, " %s Invalid LED requested", __func__);
0077 return -EINVAL;
0078 }
0079
0080 if (led->channel >= LP3952_BLUE_1) {
0081 reg = LP3952_REG_RGB1_MAX_I_CTRL;
0082 shift_val = (led->channel - LP3952_BLUE_1) * 2;
0083 } else {
0084 reg = LP3952_REG_RGB2_MAX_I_CTRL;
0085 shift_val = led->channel * 2;
0086 }
0087
0088
0089 lp3952_on_off(priv, led->channel, true);
0090
0091 return regmap_update_bits(priv->regmap, reg, 3 << shift_val,
0092 --value << shift_val);
0093 }
0094
0095 static int lp3952_get_label(struct device *dev, const char *label, char *dest)
0096 {
0097 int ret;
0098 const char *str;
0099
0100 ret = device_property_read_string(dev, label, &str);
0101 if (ret)
0102 return ret;
0103
0104 strncpy(dest, str, LP3952_LABEL_MAX_LEN);
0105 return 0;
0106 }
0107
0108 static int lp3952_register_led_classdev(struct lp3952_led_array *priv)
0109 {
0110 int i, acpi_ret, ret = -ENODEV;
0111 static const char *led_name_hdl[LP3952_LED_ALL] = {
0112 "blue2",
0113 "green2",
0114 "red2",
0115 "blue1",
0116 "green1",
0117 "red1"
0118 };
0119
0120 for (i = 0; i < LP3952_LED_ALL; i++) {
0121 acpi_ret = lp3952_get_label(&priv->client->dev, led_name_hdl[i],
0122 priv->leds[i].name);
0123 if (acpi_ret)
0124 continue;
0125
0126 priv->leds[i].cdev.name = priv->leds[i].name;
0127 priv->leds[i].cdev.brightness = LED_OFF;
0128 priv->leds[i].cdev.max_brightness = LP3952_BRIGHT_MAX;
0129 priv->leds[i].cdev.brightness_set_blocking =
0130 lp3952_set_brightness;
0131 priv->leds[i].channel = i;
0132 priv->leds[i].priv = priv;
0133
0134 ret = devm_led_classdev_register(&priv->client->dev,
0135 &priv->leds[i].cdev);
0136 if (ret < 0) {
0137 dev_err(&priv->client->dev,
0138 "couldn't register LED %s\n",
0139 priv->leds[i].cdev.name);
0140 break;
0141 }
0142 }
0143 return ret;
0144 }
0145
0146 static int lp3952_set_pattern_gen_cmd(struct lp3952_led_array *priv,
0147 u8 cmd_index, u8 r, u8 g, u8 b,
0148 enum lp3952_tt tt, enum lp3952_cet cet)
0149 {
0150 int ret;
0151 struct ptrn_gen_cmd line = {
0152 {
0153 {
0154 .r = r,
0155 .g = g,
0156 .b = b,
0157 .cet = cet,
0158 .tt = tt
0159 }
0160 }
0161 };
0162
0163 if (cmd_index >= LP3952_CMD_REG_COUNT)
0164 return -EINVAL;
0165
0166 ret = lp3952_register_write(priv->client,
0167 LP3952_REG_CMD_0 + cmd_index * 2,
0168 line.bytes.msb);
0169 if (ret)
0170 return ret;
0171
0172 return lp3952_register_write(priv->client,
0173 LP3952_REG_CMD_0 + cmd_index * 2 + 1,
0174 line.bytes.lsb);
0175 }
0176
0177 static int lp3952_configure(struct lp3952_led_array *priv)
0178 {
0179 int ret;
0180
0181
0182 ret = lp3952_register_write(priv->client, LP3952_REG_LED_CTRL, 0);
0183 if (ret)
0184 return ret;
0185
0186
0187 ret = lp3952_register_write(priv->client, LP3952_REG_PAT_GEN_CTRL,
0188 LP3952_PATRN_LOOP | LP3952_PATRN_GEN_EN);
0189 if (ret)
0190 return ret;
0191
0192
0193 ret = lp3952_register_write(priv->client, LP3952_REG_ENABLES,
0194 LP3952_ACTIVE_MODE | LP3952_INT_B00ST_LDR);
0195 if (ret)
0196 return ret;
0197
0198
0199 return lp3952_set_pattern_gen_cmd(priv, 0, I46, I71, I100, TT0,
0200 CET197);
0201 }
0202
0203 static const struct regmap_config lp3952_regmap = {
0204 .reg_bits = 8,
0205 .val_bits = 8,
0206 .max_register = REG_MAX,
0207 .cache_type = REGCACHE_RBTREE,
0208 };
0209
0210 static int lp3952_probe(struct i2c_client *client,
0211 const struct i2c_device_id *id)
0212 {
0213 int status;
0214 struct lp3952_led_array *priv;
0215
0216 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
0217 if (!priv)
0218 return -ENOMEM;
0219
0220 priv->client = client;
0221
0222 priv->enable_gpio = devm_gpiod_get(&client->dev, "nrst",
0223 GPIOD_OUT_HIGH);
0224 if (IS_ERR(priv->enable_gpio)) {
0225 status = PTR_ERR(priv->enable_gpio);
0226 dev_err(&client->dev, "Failed to enable gpio: %d\n", status);
0227 return status;
0228 }
0229
0230 priv->regmap = devm_regmap_init_i2c(client, &lp3952_regmap);
0231 if (IS_ERR(priv->regmap)) {
0232 int err = PTR_ERR(priv->regmap);
0233
0234 dev_err(&client->dev, "Failed to allocate register map: %d\n",
0235 err);
0236 return err;
0237 }
0238
0239 i2c_set_clientdata(client, priv);
0240
0241 status = lp3952_configure(priv);
0242 if (status) {
0243 dev_err(&client->dev, "Probe failed. Device not found (%d)\n",
0244 status);
0245 return status;
0246 }
0247
0248 status = lp3952_register_led_classdev(priv);
0249 if (status) {
0250 dev_err(&client->dev, "Unable to register led_classdev: %d\n",
0251 status);
0252 return status;
0253 }
0254
0255 return 0;
0256 }
0257
0258 static int lp3952_remove(struct i2c_client *client)
0259 {
0260 struct lp3952_led_array *priv;
0261
0262 priv = i2c_get_clientdata(client);
0263 lp3952_on_off(priv, LP3952_LED_ALL, false);
0264 gpiod_set_value(priv->enable_gpio, 0);
0265
0266 return 0;
0267 }
0268
0269 static const struct i2c_device_id lp3952_id[] = {
0270 {LP3952_NAME, 0},
0271 {}
0272 };
0273 MODULE_DEVICE_TABLE(i2c, lp3952_id);
0274
0275 static struct i2c_driver lp3952_i2c_driver = {
0276 .driver = {
0277 .name = LP3952_NAME,
0278 },
0279 .probe = lp3952_probe,
0280 .remove = lp3952_remove,
0281 .id_table = lp3952_id,
0282 };
0283
0284 module_i2c_driver(lp3952_i2c_driver);
0285
0286 MODULE_AUTHOR("Tony Makkiel <tony.makkiel@daqri.com>");
0287 MODULE_DESCRIPTION("lp3952 I2C LED controller driver");
0288 MODULE_LICENSE("GPL v2");