0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/clk.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/gpio/driver.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/leds.h>
0015 #include <linux/mfd/syscon.h>
0016 #include <linux/module.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/property.h>
0019 #include <linux/regmap.h>
0020 #include <linux/sizes.h>
0021 #include <linux/uaccess.h>
0022
0023 #define SSO_DEV_NAME "lgm-sso"
0024
0025 #define LED_BLINK_H8_0 0x0
0026 #define LED_BLINK_H8_1 0x4
0027 #define GET_FREQ_OFFSET(pin, src) (((pin) * 6) + ((src) * 2))
0028 #define GET_SRC_OFFSET(pinc) (((pin) * 6) + 4)
0029
0030 #define DUTY_CYCLE(x) (0x8 + ((x) * 4))
0031 #define SSO_CON0 0x2B0
0032 #define SSO_CON0_RZFL BIT(26)
0033 #define SSO_CON0_BLINK_R BIT(30)
0034 #define SSO_CON0_SWU BIT(31)
0035
0036 #define SSO_CON1 0x2B4
0037 #define SSO_CON1_FCDSC GENMASK(21, 20)
0038 #define SSO_CON1_FPID GENMASK(24, 23)
0039 #define SSO_CON1_GPTD GENMASK(26, 25)
0040 #define SSO_CON1_US GENMASK(31, 30)
0041
0042 #define SSO_CPU 0x2B8
0043 #define SSO_CON2 0x2C4
0044 #define SSO_CON3 0x2C8
0045
0046
0047 #define MAX_PIN_NUM_PER_BANK SZ_32
0048 #define MAX_GROUP_NUM SZ_4
0049 #define PINS_PER_GROUP SZ_8
0050 #define FPID_FREQ_RANK_MAX SZ_4
0051 #define SSO_LED_MAX_NUM SZ_32
0052 #define MAX_FREQ_RANK 10
0053 #define DEF_GPTC_CLK_RATE 200000000
0054 #define SSO_DEF_BRIGHTNESS LED_HALF
0055 #define DATA_CLK_EDGE 0
0056
0057 static const u32 freq_div_tbl[] = {4000, 2000, 1000, 800};
0058 static const int freq_tbl[] = {2, 4, 8, 10, 50000, 100000, 200000, 250000};
0059 static const int shift_clk_freq_tbl[] = {25000000, 12500000, 6250000, 3125000};
0060
0061
0062
0063
0064
0065
0066
0067 enum {
0068 US_SW = 0,
0069 US_GPTC = 1,
0070 US_FPID = 2
0071 };
0072
0073 enum {
0074 MAX_FPID_FREQ_RANK = 5,
0075 MAX_GPTC_FREQ_RANK = 9,
0076 MAX_GPTC_HS_FREQ_RANK = 10,
0077 };
0078
0079 enum {
0080 LED_GRP0_PIN_MAX = 24,
0081 LED_GRP1_PIN_MAX = 29,
0082 LED_GRP2_PIN_MAX = 32,
0083 };
0084
0085 enum {
0086 LED_GRP0_0_23,
0087 LED_GRP1_24_28,
0088 LED_GRP2_29_31,
0089 LED_GROUP_MAX,
0090 };
0091
0092 enum {
0093 CLK_SRC_FPID = 0,
0094 CLK_SRC_GPTC = 1,
0095 CLK_SRC_GPTC_HS = 2,
0096 };
0097
0098 struct sso_led_priv;
0099
0100 struct sso_led_desc {
0101 const char *name;
0102 const char *default_trigger;
0103 unsigned int brightness;
0104 unsigned int blink_rate;
0105 unsigned int retain_state_suspended:1;
0106 unsigned int retain_state_shutdown:1;
0107 unsigned int panic_indicator:1;
0108 unsigned int hw_blink:1;
0109 unsigned int hw_trig:1;
0110 unsigned int blinking:1;
0111 int freq_idx;
0112 u32 pin;
0113 };
0114
0115 struct sso_led {
0116 struct list_head list;
0117 struct led_classdev cdev;
0118 struct gpio_desc *gpiod;
0119 struct sso_led_desc desc;
0120 struct sso_led_priv *priv;
0121 };
0122
0123 struct sso_gpio {
0124 struct gpio_chip chip;
0125 int shift_clk_freq;
0126 int edge;
0127 int freq;
0128 u32 pins;
0129 u32 alloc_bitmap;
0130 };
0131
0132 struct sso_led_priv {
0133 struct regmap *mmap;
0134 struct device *dev;
0135 struct platform_device *pdev;
0136 struct clk_bulk_data clocks[2];
0137 u32 fpid_clkrate;
0138 u32 gptc_clkrate;
0139 u32 freq[MAX_FREQ_RANK];
0140 struct list_head led_list;
0141 struct sso_gpio gpio;
0142 };
0143
0144 static int sso_get_blink_rate_idx(struct sso_led_priv *priv, u32 rate)
0145 {
0146 int i;
0147
0148 for (i = 0; i < MAX_FREQ_RANK; i++) {
0149 if (rate <= priv->freq[i])
0150 return i;
0151 }
0152
0153 return -1;
0154 }
0155
0156 static unsigned int sso_led_pin_to_group(u32 pin)
0157 {
0158 if (pin < LED_GRP0_PIN_MAX)
0159 return LED_GRP0_0_23;
0160 else if (pin < LED_GRP1_PIN_MAX)
0161 return LED_GRP1_24_28;
0162 else
0163 return LED_GRP2_29_31;
0164 }
0165
0166 static u32 sso_led_get_freq_src(int freq_idx)
0167 {
0168 if (freq_idx < MAX_FPID_FREQ_RANK)
0169 return CLK_SRC_FPID;
0170 else if (freq_idx < MAX_GPTC_FREQ_RANK)
0171 return CLK_SRC_GPTC;
0172 else
0173 return CLK_SRC_GPTC_HS;
0174 }
0175
0176 static u32 sso_led_pin_blink_off(u32 pin, unsigned int group)
0177 {
0178 if (group == LED_GRP2_29_31)
0179 return pin - LED_GRP1_PIN_MAX;
0180 else if (group == LED_GRP1_24_28)
0181 return pin - LED_GRP0_PIN_MAX;
0182 else
0183 return SSO_LED_MAX_NUM - LED_GRP1_PIN_MAX;
0184 }
0185
0186 static struct sso_led
0187 *cdev_to_sso_led_data(struct led_classdev *led_cdev)
0188 {
0189 return container_of(led_cdev, struct sso_led, cdev);
0190 }
0191
0192 static void sso_led_freq_set(struct sso_led_priv *priv, u32 pin, int freq_idx)
0193 {
0194 u32 reg, off, freq_src, val_freq;
0195 u32 low, high, val;
0196 unsigned int group;
0197
0198 if (!freq_idx)
0199 return;
0200
0201 group = sso_led_pin_to_group(pin);
0202 freq_src = sso_led_get_freq_src(freq_idx);
0203 off = sso_led_pin_blink_off(pin, group);
0204
0205 if (group == LED_GRP0_0_23)
0206 return;
0207 else if (group == LED_GRP1_24_28)
0208 reg = LED_BLINK_H8_0;
0209 else
0210 reg = LED_BLINK_H8_1;
0211
0212 if (freq_src == CLK_SRC_FPID)
0213 val_freq = freq_idx - 1;
0214 else if (freq_src == CLK_SRC_GPTC)
0215 val_freq = freq_idx - MAX_FPID_FREQ_RANK;
0216
0217
0218 if (freq_src != CLK_SRC_GPTC_HS) {
0219 low = GET_FREQ_OFFSET(off, freq_src);
0220 high = low + 2;
0221 val = val_freq << high;
0222 regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val);
0223 }
0224
0225
0226 low = GET_SRC_OFFSET(off);
0227 high = low + 2;
0228 val = freq_src << high;
0229 regmap_update_bits(priv->mmap, reg, GENMASK(high, low), val);
0230 }
0231
0232 static void sso_led_brightness_set(struct led_classdev *led_cdev,
0233 enum led_brightness brightness)
0234 {
0235 struct sso_led_priv *priv;
0236 struct sso_led_desc *desc;
0237 struct sso_led *led;
0238 int val;
0239
0240 led = cdev_to_sso_led_data(led_cdev);
0241 priv = led->priv;
0242 desc = &led->desc;
0243
0244 desc->brightness = brightness;
0245 regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), brightness);
0246
0247 if (brightness == LED_OFF)
0248 val = 0;
0249 else
0250 val = 1;
0251
0252
0253 if (desc->hw_blink && !val && desc->blinking) {
0254 desc->blinking = 0;
0255 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin), 0);
0256 } else if (desc->hw_blink && val && !desc->blinking) {
0257 desc->blinking = 1;
0258 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin),
0259 1 << desc->pin);
0260 }
0261
0262 if (!desc->hw_trig)
0263 gpiod_set_value(led->gpiod, val);
0264 }
0265
0266 static enum led_brightness sso_led_brightness_get(struct led_classdev *led_cdev)
0267 {
0268 struct sso_led *led = cdev_to_sso_led_data(led_cdev);
0269
0270 return (enum led_brightness)led->desc.brightness;
0271 }
0272
0273 static int
0274 delay_to_freq_idx(struct sso_led *led, unsigned long *delay_on,
0275 unsigned long *delay_off)
0276 {
0277 struct sso_led_priv *priv = led->priv;
0278 unsigned long delay;
0279 int freq_idx;
0280 u32 freq;
0281
0282 if (!*delay_on && !*delay_off) {
0283 *delay_on = *delay_off = (1000 / priv->freq[0]) / 2;
0284 return 0;
0285 }
0286
0287 delay = *delay_on + *delay_off;
0288 freq = 1000 / delay;
0289
0290 freq_idx = sso_get_blink_rate_idx(priv, freq);
0291 if (freq_idx == -1)
0292 freq_idx = MAX_FREQ_RANK - 1;
0293
0294 delay = 1000 / priv->freq[freq_idx];
0295 *delay_on = *delay_off = delay / 2;
0296
0297 if (!*delay_on)
0298 *delay_on = *delay_off = 1;
0299
0300 return freq_idx;
0301 }
0302
0303 static int
0304 sso_led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on,
0305 unsigned long *delay_off)
0306 {
0307 struct sso_led_priv *priv;
0308 struct sso_led *led;
0309 int freq_idx;
0310
0311 led = cdev_to_sso_led_data(led_cdev);
0312 priv = led->priv;
0313 freq_idx = delay_to_freq_idx(led, delay_on, delay_off);
0314
0315 sso_led_freq_set(priv, led->desc.pin, freq_idx);
0316 regmap_update_bits(priv->mmap, SSO_CON2, BIT(led->desc.pin),
0317 1 << led->desc.pin);
0318 led->desc.freq_idx = freq_idx;
0319 led->desc.blink_rate = priv->freq[freq_idx];
0320 led->desc.blinking = 1;
0321
0322 return 1;
0323 }
0324
0325 static void sso_led_hw_cfg(struct sso_led_priv *priv, struct sso_led *led)
0326 {
0327 struct sso_led_desc *desc = &led->desc;
0328
0329
0330 if (desc->hw_blink) {
0331 sso_led_freq_set(priv, desc->pin, desc->freq_idx);
0332 regmap_update_bits(priv->mmap, SSO_CON2, BIT(desc->pin),
0333 1 << desc->pin);
0334 }
0335
0336 if (desc->hw_trig)
0337 regmap_update_bits(priv->mmap, SSO_CON3, BIT(desc->pin),
0338 1 << desc->pin);
0339
0340
0341 regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), desc->brightness);
0342
0343
0344 if (!desc->hw_trig && desc->brightness)
0345 gpiod_set_value(led->gpiod, 1);
0346 }
0347
0348 static int sso_create_led(struct sso_led_priv *priv, struct sso_led *led,
0349 struct fwnode_handle *child)
0350 {
0351 struct sso_led_desc *desc = &led->desc;
0352 struct led_init_data init_data;
0353 int err;
0354
0355 init_data.fwnode = child;
0356 init_data.devicename = SSO_DEV_NAME;
0357 init_data.default_label = ":";
0358
0359 led->cdev.default_trigger = desc->default_trigger;
0360 led->cdev.brightness_set = sso_led_brightness_set;
0361 led->cdev.brightness_get = sso_led_brightness_get;
0362 led->cdev.brightness = desc->brightness;
0363 led->cdev.max_brightness = LED_FULL;
0364
0365 if (desc->retain_state_shutdown)
0366 led->cdev.flags |= LED_RETAIN_AT_SHUTDOWN;
0367 if (desc->retain_state_suspended)
0368 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
0369 if (desc->panic_indicator)
0370 led->cdev.flags |= LED_PANIC_INDICATOR;
0371
0372 if (desc->hw_blink)
0373 led->cdev.blink_set = sso_led_blink_set;
0374
0375 sso_led_hw_cfg(priv, led);
0376
0377 err = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
0378 if (err)
0379 return err;
0380
0381 list_add(&led->list, &priv->led_list);
0382
0383 return 0;
0384 }
0385
0386 static void sso_init_freq(struct sso_led_priv *priv)
0387 {
0388 int i;
0389
0390 priv->freq[0] = 0;
0391 for (i = 1; i < MAX_FREQ_RANK; i++) {
0392 if (i < MAX_FPID_FREQ_RANK) {
0393 priv->freq[i] = priv->fpid_clkrate / freq_div_tbl[i - 1];
0394 } else if (i < MAX_GPTC_FREQ_RANK) {
0395 priv->freq[i] = priv->gptc_clkrate /
0396 freq_div_tbl[i - MAX_FPID_FREQ_RANK];
0397 } else if (i < MAX_GPTC_HS_FREQ_RANK) {
0398 priv->freq[i] = priv->gptc_clkrate;
0399 }
0400 }
0401 }
0402
0403 static int sso_gpio_request(struct gpio_chip *chip, unsigned int offset)
0404 {
0405 struct sso_led_priv *priv = gpiochip_get_data(chip);
0406
0407 if (priv->gpio.alloc_bitmap & BIT(offset))
0408 return -EINVAL;
0409
0410 priv->gpio.alloc_bitmap |= BIT(offset);
0411 regmap_write(priv->mmap, DUTY_CYCLE(offset), 0xFF);
0412
0413 return 0;
0414 }
0415
0416 static void sso_gpio_free(struct gpio_chip *chip, unsigned int offset)
0417 {
0418 struct sso_led_priv *priv = gpiochip_get_data(chip);
0419
0420 priv->gpio.alloc_bitmap &= ~BIT(offset);
0421 regmap_write(priv->mmap, DUTY_CYCLE(offset), 0x0);
0422 }
0423
0424 static int sso_gpio_get_dir(struct gpio_chip *chip, unsigned int offset)
0425 {
0426 return GPIO_LINE_DIRECTION_OUT;
0427 }
0428
0429 static int
0430 sso_gpio_dir_out(struct gpio_chip *chip, unsigned int offset, int value)
0431 {
0432 struct sso_led_priv *priv = gpiochip_get_data(chip);
0433 bool bit = !!value;
0434
0435 regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), bit << offset);
0436 if (!priv->gpio.freq)
0437 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU,
0438 SSO_CON0_SWU);
0439
0440 return 0;
0441 }
0442
0443 static int sso_gpio_get(struct gpio_chip *chip, unsigned int offset)
0444 {
0445 struct sso_led_priv *priv = gpiochip_get_data(chip);
0446 u32 reg_val;
0447
0448 regmap_read(priv->mmap, SSO_CPU, ®_val);
0449
0450 return !!(reg_val & BIT(offset));
0451 }
0452
0453 static void sso_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
0454 {
0455 struct sso_led_priv *priv = gpiochip_get_data(chip);
0456
0457 regmap_update_bits(priv->mmap, SSO_CPU, BIT(offset), value << offset);
0458 if (!priv->gpio.freq)
0459 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_SWU,
0460 SSO_CON0_SWU);
0461 }
0462
0463 static int sso_gpio_gc_init(struct device *dev, struct sso_led_priv *priv)
0464 {
0465 struct gpio_chip *gc = &priv->gpio.chip;
0466
0467 gc->request = sso_gpio_request;
0468 gc->free = sso_gpio_free;
0469 gc->get_direction = sso_gpio_get_dir;
0470 gc->direction_output = sso_gpio_dir_out;
0471 gc->get = sso_gpio_get;
0472 gc->set = sso_gpio_set;
0473
0474 gc->label = "lgm-sso";
0475 gc->base = -1;
0476
0477 gc->ngpio = priv->gpio.pins;
0478 gc->parent = dev;
0479 gc->owner = THIS_MODULE;
0480
0481 return devm_gpiochip_add_data(dev, gc, priv);
0482 }
0483
0484 static int sso_gpio_get_freq_idx(int freq)
0485 {
0486 int idx;
0487
0488 for (idx = 0; idx < ARRAY_SIZE(freq_tbl); idx++) {
0489 if (freq <= freq_tbl[idx])
0490 return idx;
0491 }
0492
0493 return -1;
0494 }
0495
0496 static void sso_register_shift_clk(struct sso_led_priv *priv)
0497 {
0498 int idx, size = ARRAY_SIZE(shift_clk_freq_tbl);
0499 u32 val = 0;
0500
0501 for (idx = 0; idx < size; idx++) {
0502 if (shift_clk_freq_tbl[idx] <= priv->gpio.shift_clk_freq) {
0503 val = idx;
0504 break;
0505 }
0506 }
0507
0508 if (idx == size)
0509 dev_warn(priv->dev, "%s: Invalid freq %d\n",
0510 __func__, priv->gpio.shift_clk_freq);
0511
0512 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FCDSC,
0513 FIELD_PREP(SSO_CON1_FCDSC, val));
0514 }
0515
0516 static int sso_gpio_freq_set(struct sso_led_priv *priv)
0517 {
0518 int freq_idx;
0519 u32 val;
0520
0521 freq_idx = sso_gpio_get_freq_idx(priv->gpio.freq);
0522 if (freq_idx == -1)
0523 freq_idx = ARRAY_SIZE(freq_tbl) - 1;
0524
0525 val = freq_idx % FPID_FREQ_RANK_MAX;
0526
0527 if (!priv->gpio.freq) {
0528 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R, 0);
0529 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
0530 FIELD_PREP(SSO_CON1_US, US_SW));
0531 } else if (freq_idx < FPID_FREQ_RANK_MAX) {
0532 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R,
0533 SSO_CON0_BLINK_R);
0534 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
0535 FIELD_PREP(SSO_CON1_US, US_FPID));
0536 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_FPID,
0537 FIELD_PREP(SSO_CON1_FPID, val));
0538 } else {
0539 regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_BLINK_R,
0540 SSO_CON0_BLINK_R);
0541 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_US,
0542 FIELD_PREP(SSO_CON1_US, US_GPTC));
0543 regmap_update_bits(priv->mmap, SSO_CON1, SSO_CON1_GPTD,
0544 FIELD_PREP(SSO_CON1_GPTD, val));
0545 }
0546
0547 return 0;
0548 }
0549
0550 static int sso_gpio_hw_init(struct sso_led_priv *priv)
0551 {
0552 u32 activate;
0553 int i, err;
0554
0555
0556 for (i = 0; i < priv->gpio.pins; i++) {
0557 err = regmap_write(priv->mmap, DUTY_CYCLE(i), 0);
0558 if (err)
0559 return err;
0560 }
0561
0562
0563 for (i = 1; i <= MAX_GROUP_NUM; i++) {
0564 activate = !!(i * PINS_PER_GROUP <= priv->gpio.pins ||
0565 priv->gpio.pins > (i - 1) * PINS_PER_GROUP);
0566 err = regmap_update_bits(priv->mmap, SSO_CON1, BIT(i - 1),
0567 activate << (i - 1));
0568 if (err)
0569 return err;
0570 }
0571
0572
0573 err = regmap_write(priv->mmap, SSO_CON3, 0);
0574 if (err)
0575 return err;
0576
0577
0578 err = regmap_write(priv->mmap, SSO_CON2, 0);
0579 if (err)
0580 return err;
0581
0582
0583 err = regmap_write(priv->mmap, SSO_CPU, 0);
0584 if (err)
0585 return err;
0586
0587
0588 err = regmap_update_bits(priv->mmap, SSO_CON0, SSO_CON0_RZFL,
0589 FIELD_PREP(SSO_CON0_RZFL, priv->gpio.edge));
0590 if (err)
0591 return err;
0592
0593
0594 sso_gpio_freq_set(priv);
0595
0596
0597 sso_register_shift_clk(priv);
0598
0599 return 0;
0600 }
0601
0602 static void sso_led_shutdown(struct sso_led *led)
0603 {
0604 struct sso_led_priv *priv = led->priv;
0605
0606
0607 devm_led_classdev_unregister(priv->dev, &led->cdev);
0608
0609
0610 if (led->desc.hw_trig)
0611 regmap_update_bits(priv->mmap, SSO_CON3, BIT(led->desc.pin), 0);
0612
0613 led->priv = NULL;
0614 }
0615
0616 static int
0617 __sso_led_dt_parse(struct sso_led_priv *priv, struct fwnode_handle *fw_ssoled)
0618 {
0619 struct fwnode_handle *fwnode_child;
0620 struct device *dev = priv->dev;
0621 struct sso_led_desc *desc;
0622 struct sso_led *led;
0623 const char *tmp;
0624 u32 prop;
0625 int ret;
0626
0627 fwnode_for_each_child_node(fw_ssoled, fwnode_child) {
0628 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
0629 if (!led) {
0630 ret = -ENOMEM;
0631 goto __dt_err;
0632 }
0633
0634 INIT_LIST_HEAD(&led->list);
0635 led->priv = priv;
0636 desc = &led->desc;
0637
0638 led->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
0639 fwnode_child,
0640 GPIOD_ASIS, NULL);
0641 if (IS_ERR(led->gpiod)) {
0642 ret = dev_err_probe(dev, PTR_ERR(led->gpiod), "led: get gpio fail!\n");
0643 goto __dt_err;
0644 }
0645
0646 fwnode_property_read_string(fwnode_child,
0647 "linux,default-trigger",
0648 &desc->default_trigger);
0649
0650 if (fwnode_property_present(fwnode_child,
0651 "retain-state-suspended"))
0652 desc->retain_state_suspended = 1;
0653
0654 if (fwnode_property_present(fwnode_child,
0655 "retain-state-shutdown"))
0656 desc->retain_state_shutdown = 1;
0657
0658 if (fwnode_property_present(fwnode_child, "panic-indicator"))
0659 desc->panic_indicator = 1;
0660
0661 ret = fwnode_property_read_u32(fwnode_child, "reg", &prop);
0662 if (ret)
0663 goto __dt_err;
0664 if (prop >= SSO_LED_MAX_NUM) {
0665 dev_err(dev, "invalid LED pin:%u\n", prop);
0666 ret = -EINVAL;
0667 goto __dt_err;
0668 }
0669 desc->pin = prop;
0670
0671 if (fwnode_property_present(fwnode_child, "intel,sso-hw-blink"))
0672 desc->hw_blink = 1;
0673
0674 desc->hw_trig = fwnode_property_read_bool(fwnode_child,
0675 "intel,sso-hw-trigger");
0676 if (desc->hw_trig) {
0677 desc->default_trigger = NULL;
0678 desc->retain_state_shutdown = 0;
0679 desc->retain_state_suspended = 0;
0680 desc->panic_indicator = 0;
0681 desc->hw_blink = 0;
0682 }
0683
0684 if (fwnode_property_read_u32(fwnode_child,
0685 "intel,sso-blink-rate-hz", &prop)) {
0686
0687 desc->freq_idx = 0;
0688 desc->blink_rate = priv->freq[desc->freq_idx];
0689 } else {
0690 desc->freq_idx = sso_get_blink_rate_idx(priv, prop);
0691 if (desc->freq_idx == -1)
0692 desc->freq_idx = MAX_FREQ_RANK - 1;
0693
0694 desc->blink_rate = priv->freq[desc->freq_idx];
0695 }
0696
0697 if (!fwnode_property_read_string(fwnode_child, "default-state", &tmp)) {
0698 if (!strcmp(tmp, "on"))
0699 desc->brightness = LED_FULL;
0700 }
0701
0702 ret = sso_create_led(priv, led, fwnode_child);
0703 if (ret)
0704 goto __dt_err;
0705 }
0706
0707 return 0;
0708
0709 __dt_err:
0710 fwnode_handle_put(fwnode_child);
0711
0712 list_for_each_entry(led, &priv->led_list, list)
0713 sso_led_shutdown(led);
0714
0715 return ret;
0716 }
0717
0718 static int sso_led_dt_parse(struct sso_led_priv *priv)
0719 {
0720 struct fwnode_handle *fwnode = dev_fwnode(priv->dev);
0721 struct fwnode_handle *fw_ssoled;
0722 struct device *dev = priv->dev;
0723 int count;
0724 int ret;
0725
0726 count = device_get_child_node_count(dev);
0727 if (!count)
0728 return 0;
0729
0730 fw_ssoled = fwnode_get_named_child_node(fwnode, "ssoled");
0731 if (fw_ssoled) {
0732 ret = __sso_led_dt_parse(priv, fw_ssoled);
0733 fwnode_handle_put(fw_ssoled);
0734 if (ret)
0735 return ret;
0736 }
0737
0738 return 0;
0739 }
0740
0741 static int sso_probe_gpios(struct sso_led_priv *priv)
0742 {
0743 struct device *dev = priv->dev;
0744 int ret;
0745
0746 if (device_property_read_u32(dev, "ngpios", &priv->gpio.pins))
0747 priv->gpio.pins = MAX_PIN_NUM_PER_BANK;
0748
0749 if (priv->gpio.pins > MAX_PIN_NUM_PER_BANK)
0750 return -EINVAL;
0751
0752 if (device_property_read_u32(dev, "intel,sso-update-rate-hz",
0753 &priv->gpio.freq))
0754 priv->gpio.freq = 0;
0755
0756 priv->gpio.edge = DATA_CLK_EDGE;
0757 priv->gpio.shift_clk_freq = -1;
0758
0759 ret = sso_gpio_hw_init(priv);
0760 if (ret)
0761 return ret;
0762
0763 return sso_gpio_gc_init(dev, priv);
0764 }
0765
0766 static void sso_clock_disable_unprepare(void *data)
0767 {
0768 struct sso_led_priv *priv = data;
0769
0770 clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
0771 }
0772
0773 static int intel_sso_led_probe(struct platform_device *pdev)
0774 {
0775 struct device *dev = &pdev->dev;
0776 struct sso_led_priv *priv;
0777 int ret;
0778
0779 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0780 if (!priv)
0781 return -ENOMEM;
0782
0783 priv->pdev = pdev;
0784 priv->dev = dev;
0785
0786
0787 priv->clocks[0].id = "sso";
0788
0789
0790 priv->clocks[1].id = "fpid";
0791
0792 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks);
0793 if (ret) {
0794 dev_err(dev, "Getting clocks failed!\n");
0795 return ret;
0796 }
0797
0798 ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
0799 if (ret) {
0800 dev_err(dev, "Failed to prepare and enable clocks!\n");
0801 return ret;
0802 }
0803
0804 ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv);
0805 if (ret)
0806 return ret;
0807
0808 priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk);
0809
0810 priv->mmap = syscon_node_to_regmap(dev->of_node);
0811
0812 priv->mmap = syscon_node_to_regmap(dev->of_node);
0813 if (IS_ERR(priv->mmap)) {
0814 dev_err(dev, "Failed to map iomem!\n");
0815 return PTR_ERR(priv->mmap);
0816 }
0817
0818 ret = sso_probe_gpios(priv);
0819 if (ret) {
0820 regmap_exit(priv->mmap);
0821 return ret;
0822 }
0823
0824 INIT_LIST_HEAD(&priv->led_list);
0825
0826 platform_set_drvdata(pdev, priv);
0827 sso_init_freq(priv);
0828
0829 priv->gptc_clkrate = DEF_GPTC_CLK_RATE;
0830
0831 ret = sso_led_dt_parse(priv);
0832 if (ret) {
0833 regmap_exit(priv->mmap);
0834 return ret;
0835 }
0836 dev_info(priv->dev, "sso LED init success!\n");
0837
0838 return 0;
0839 }
0840
0841 static int intel_sso_led_remove(struct platform_device *pdev)
0842 {
0843 struct sso_led_priv *priv;
0844 struct sso_led *led, *n;
0845
0846 priv = platform_get_drvdata(pdev);
0847
0848 list_for_each_entry_safe(led, n, &priv->led_list, list) {
0849 list_del(&led->list);
0850 sso_led_shutdown(led);
0851 }
0852
0853 regmap_exit(priv->mmap);
0854
0855 return 0;
0856 }
0857
0858 static const struct of_device_id of_sso_led_match[] = {
0859 { .compatible = "intel,lgm-ssoled" },
0860 {}
0861 };
0862
0863 MODULE_DEVICE_TABLE(of, of_sso_led_match);
0864
0865 static struct platform_driver intel_sso_led_driver = {
0866 .probe = intel_sso_led_probe,
0867 .remove = intel_sso_led_remove,
0868 .driver = {
0869 .name = "lgm-ssoled",
0870 .of_match_table = of_sso_led_match,
0871 },
0872 };
0873
0874 module_platform_driver(intel_sso_led_driver);
0875
0876 MODULE_DESCRIPTION("Intel SSO LED/GPIO driver");
0877 MODULE_LICENSE("GPL v2");