0001
0002
0003
0004
0005 #include <linux/delay.h>
0006 #include <linux/leds.h>
0007 #include <linux/mod_devicetable.h>
0008 #include <linux/module.h>
0009 #include <linux/property.h>
0010 #include <linux/spi/spi.h>
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #define EL_FW_DELAY_USEC 20000ul
0052 #define EL_PATTERN_DELAY_MSEC 800u
0053 #define EL_PATTERN_LEN 10u
0054 #define EL_PATTERN_HALF_LEN (EL_PATTERN_LEN / 2)
0055
0056 enum el15203000_command {
0057
0058 EL_OFF = '0',
0059 EL_ON = '1',
0060
0061
0062 EL_SCREEN_BREATHING = '2',
0063
0064
0065 EL_PIPE_CASCADE = '2',
0066 EL_PIPE_INV_CASCADE = '3',
0067 EL_PIPE_BOUNCE = '4',
0068 EL_PIPE_INV_BOUNCE = '5',
0069 };
0070
0071 struct el15203000_led {
0072 struct led_classdev ldev;
0073 struct el15203000 *priv;
0074 u32 reg;
0075 };
0076
0077 struct el15203000 {
0078 struct device *dev;
0079 struct mutex lock;
0080 struct spi_device *spi;
0081 unsigned long delay;
0082 size_t count;
0083 struct el15203000_led leds[];
0084 };
0085
0086 #define to_el15203000_led(d) container_of(d, struct el15203000_led, ldev)
0087
0088 static int el15203000_cmd(struct el15203000_led *led, u8 brightness)
0089 {
0090 int ret;
0091 u8 cmd[2];
0092 size_t i;
0093
0094 mutex_lock(&led->priv->lock);
0095
0096 dev_dbg(led->priv->dev, "Set brightness of 0x%02x(%c) to 0x%02x(%c)",
0097 led->reg, led->reg, brightness, brightness);
0098
0099
0100 if (time_after(led->priv->delay, jiffies)) {
0101 dev_dbg(led->priv->dev, "Wait %luus to sync",
0102 EL_FW_DELAY_USEC);
0103
0104 usleep_range(EL_FW_DELAY_USEC,
0105 EL_FW_DELAY_USEC + 1);
0106 }
0107
0108 cmd[0] = led->reg;
0109 cmd[1] = brightness;
0110
0111 for (i = 0; i < ARRAY_SIZE(cmd); i++) {
0112 if (i)
0113 usleep_range(EL_FW_DELAY_USEC,
0114 EL_FW_DELAY_USEC + 1);
0115
0116 ret = spi_write(led->priv->spi, &cmd[i], sizeof(cmd[i]));
0117 if (ret) {
0118 dev_err(led->priv->dev,
0119 "spi_write() error %d", ret);
0120 break;
0121 }
0122 }
0123
0124 led->priv->delay = jiffies + usecs_to_jiffies(EL_FW_DELAY_USEC);
0125
0126 mutex_unlock(&led->priv->lock);
0127
0128 return ret;
0129 }
0130
0131 static int el15203000_set_blocking(struct led_classdev *ldev,
0132 enum led_brightness brightness)
0133 {
0134 struct el15203000_led *led = to_el15203000_led(ldev);
0135
0136 return el15203000_cmd(led, brightness == LED_OFF ? EL_OFF : EL_ON);
0137 }
0138
0139 static int el15203000_pattern_set_S(struct led_classdev *ldev,
0140 struct led_pattern *pattern,
0141 u32 len, int repeat)
0142 {
0143 struct el15203000_led *led = to_el15203000_led(ldev);
0144
0145 if (repeat > 0 || len != 2 ||
0146 pattern[0].delta_t != 4000 || pattern[0].brightness != 0 ||
0147 pattern[1].delta_t != 4000 || pattern[1].brightness != 1)
0148 return -EINVAL;
0149
0150 dev_dbg(led->priv->dev, "Breathing mode for 0x%02x(%c)",
0151 led->reg, led->reg);
0152
0153 return el15203000_cmd(led, EL_SCREEN_BREATHING);
0154 }
0155
0156 static bool is_cascade(const struct led_pattern *pattern, u32 len,
0157 bool inv, bool right)
0158 {
0159 int val, t;
0160 u32 i;
0161
0162 if (len != EL_PATTERN_HALF_LEN)
0163 return false;
0164
0165 val = right ? BIT(4) : BIT(0);
0166
0167 for (i = 0; i < len; i++) {
0168 t = inv ? ~val & GENMASK(4, 0) : val;
0169
0170 if (pattern[i].delta_t != EL_PATTERN_DELAY_MSEC ||
0171 pattern[i].brightness != t)
0172 return false;
0173
0174 val = right ? val >> 1 : val << 1;
0175 }
0176
0177 return true;
0178 }
0179
0180 static bool is_bounce(const struct led_pattern *pattern, u32 len, bool inv)
0181 {
0182 if (len != EL_PATTERN_LEN)
0183 return false;
0184
0185 return is_cascade(pattern, EL_PATTERN_HALF_LEN, inv, false) &&
0186 is_cascade(pattern + EL_PATTERN_HALF_LEN,
0187 EL_PATTERN_HALF_LEN, inv, true);
0188 }
0189
0190 static int el15203000_pattern_set_P(struct led_classdev *ldev,
0191 struct led_pattern *pattern,
0192 u32 len, int repeat)
0193 {
0194 struct el15203000_led *led = to_el15203000_led(ldev);
0195 u8 cmd;
0196
0197 if (repeat > 0)
0198 return -EINVAL;
0199
0200 if (is_cascade(pattern, len, false, false)) {
0201 dev_dbg(led->priv->dev, "Cascade mode for 0x%02x(%c)",
0202 led->reg, led->reg);
0203
0204 cmd = EL_PIPE_CASCADE;
0205 } else if (is_cascade(pattern, len, true, false)) {
0206 dev_dbg(led->priv->dev, "Inverse cascade mode for 0x%02x(%c)",
0207 led->reg, led->reg);
0208
0209 cmd = EL_PIPE_INV_CASCADE;
0210 } else if (is_bounce(pattern, len, false)) {
0211 dev_dbg(led->priv->dev, "Bounce mode for 0x%02x(%c)",
0212 led->reg, led->reg);
0213
0214 cmd = EL_PIPE_BOUNCE;
0215 } else if (is_bounce(pattern, len, true)) {
0216 dev_dbg(led->priv->dev, "Inverse bounce mode for 0x%02x(%c)",
0217 led->reg, led->reg);
0218
0219 cmd = EL_PIPE_INV_BOUNCE;
0220 } else {
0221 dev_err(led->priv->dev, "Invalid hw_pattern for 0x%02x(%c)!",
0222 led->reg, led->reg);
0223
0224 return -EINVAL;
0225 }
0226
0227 return el15203000_cmd(led, cmd);
0228 }
0229
0230 static int el15203000_pattern_clear(struct led_classdev *ldev)
0231 {
0232 struct el15203000_led *led = to_el15203000_led(ldev);
0233
0234 return el15203000_cmd(led, EL_OFF);
0235 }
0236
0237 static int el15203000_probe_dt(struct el15203000 *priv)
0238 {
0239 struct el15203000_led *led = priv->leds;
0240 struct fwnode_handle *child;
0241 int ret;
0242
0243 device_for_each_child_node(priv->dev, child) {
0244 struct led_init_data init_data = {};
0245
0246 ret = fwnode_property_read_u32(child, "reg", &led->reg);
0247 if (ret) {
0248 dev_err(priv->dev, "LED without ID number");
0249 goto err_child_out;
0250 }
0251
0252 if (led->reg > U8_MAX) {
0253 dev_err(priv->dev, "LED value %d is invalid", led->reg);
0254 ret = -EINVAL;
0255 goto err_child_out;
0256 }
0257
0258 led->priv = priv;
0259 led->ldev.max_brightness = LED_ON;
0260 led->ldev.brightness_set_blocking = el15203000_set_blocking;
0261
0262 if (led->reg == 'S') {
0263 led->ldev.pattern_set = el15203000_pattern_set_S;
0264 led->ldev.pattern_clear = el15203000_pattern_clear;
0265 } else if (led->reg == 'P') {
0266 led->ldev.pattern_set = el15203000_pattern_set_P;
0267 led->ldev.pattern_clear = el15203000_pattern_clear;
0268 }
0269
0270 init_data.fwnode = child;
0271 ret = devm_led_classdev_register_ext(priv->dev, &led->ldev,
0272 &init_data);
0273 if (ret) {
0274 dev_err(priv->dev,
0275 "failed to register LED device %s, err %d",
0276 led->ldev.name, ret);
0277 goto err_child_out;
0278 }
0279
0280 led++;
0281 }
0282
0283 return 0;
0284
0285 err_child_out:
0286 fwnode_handle_put(child);
0287 return ret;
0288 }
0289
0290 static int el15203000_probe(struct spi_device *spi)
0291 {
0292 struct el15203000 *priv;
0293 size_t count;
0294
0295 count = device_get_child_node_count(&spi->dev);
0296 if (!count) {
0297 dev_err(&spi->dev, "LEDs are not defined in device tree!");
0298 return -ENODEV;
0299 }
0300
0301 priv = devm_kzalloc(&spi->dev, struct_size(priv, leds, count),
0302 GFP_KERNEL);
0303 if (!priv)
0304 return -ENOMEM;
0305
0306 mutex_init(&priv->lock);
0307 priv->count = count;
0308 priv->dev = &spi->dev;
0309 priv->spi = spi;
0310 priv->delay = jiffies -
0311 usecs_to_jiffies(EL_FW_DELAY_USEC);
0312
0313 spi_set_drvdata(spi, priv);
0314
0315 return el15203000_probe_dt(priv);
0316 }
0317
0318 static void el15203000_remove(struct spi_device *spi)
0319 {
0320 struct el15203000 *priv = spi_get_drvdata(spi);
0321
0322 mutex_destroy(&priv->lock);
0323 }
0324
0325 static const struct of_device_id el15203000_dt_ids[] = {
0326 { .compatible = "crane,el15203000", },
0327 {},
0328 };
0329
0330 MODULE_DEVICE_TABLE(of, el15203000_dt_ids);
0331
0332 static struct spi_driver el15203000_driver = {
0333 .probe = el15203000_probe,
0334 .remove = el15203000_remove,
0335 .driver = {
0336 .name = KBUILD_MODNAME,
0337 .of_match_table = el15203000_dt_ids,
0338 },
0339 };
0340
0341 module_spi_driver(el15203000_driver);
0342
0343 MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
0344 MODULE_DESCRIPTION("el15203000 LED driver");
0345 MODULE_LICENSE("GPL v2");
0346 MODULE_ALIAS("spi:el15203000");