diff options
author | Pawel Moll <pawel.moll@arm.com> | 2013-01-30 05:33:16 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-02-13 18:22:58 -0500 |
commit | 8ea402f5646e6e36c8cd0a62053ba8939204dceb (patch) | |
tree | b276a577a1964b3c61a19594a94a26e34ddf4d13 | |
parent | 151621a704fc7b8eaa1d6905bec0c6388b0a57af (diff) |
mfd: vexpress: Add pseudo-GPIO based LEDs
The LEDs on the Versatile Express motherboard are controlled
through simple memory-mapped register. This patch extends
the pseudo-GPIO controller definition for these lines and
creates generic "leds-gpio" device using them
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/vexpress-sysreg.c | 73 | ||||
-rw-r--r-- | include/linux/vexpress.h | 8 |
2 files changed, 63 insertions, 18 deletions
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 77048b18439e..51c3ca263bf5 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #define SYS_ID_HBI_SHIFT 16 | 49 | #define SYS_ID_HBI_SHIFT 16 |
50 | #define SYS_PROCIDx_HBI_SHIFT 0 | 50 | #define SYS_PROCIDx_HBI_SHIFT 0 |
51 | 51 | ||
52 | #define SYS_LED_LED(n) (1 << (n)) | ||
53 | |||
52 | #define SYS_MCI_CARDIN (1 << 0) | 54 | #define SYS_MCI_CARDIN (1 << 0) |
53 | #define SYS_MCI_WPROT (1 << 1) | 55 | #define SYS_MCI_WPROT (1 << 1) |
54 | 56 | ||
@@ -348,22 +350,27 @@ void __init vexpress_sysreg_of_early_init(void) | |||
348 | } | 350 | } |
349 | 351 | ||
350 | 352 | ||
353 | #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \ | ||
354 | [VEXPRESS_GPIO_##_name] = { \ | ||
355 | .reg = _reg, \ | ||
356 | .value = _reg##_##_value, \ | ||
357 | } | ||
358 | |||
351 | static struct vexpress_sysreg_gpio { | 359 | static struct vexpress_sysreg_gpio { |
352 | unsigned long reg; | 360 | unsigned long reg; |
353 | u32 value; | 361 | u32 value; |
354 | } vexpress_sysreg_gpios[] = { | 362 | } vexpress_sysreg_gpios[] = { |
355 | [VEXPRESS_GPIO_MMC_CARDIN] = { | 363 | VEXPRESS_SYSREG_GPIO(MMC_CARDIN, SYS_MCI, CARDIN), |
356 | .reg = SYS_MCI, | 364 | VEXPRESS_SYSREG_GPIO(MMC_WPROT, SYS_MCI, WPROT), |
357 | .value = SYS_MCI_CARDIN, | 365 | VEXPRESS_SYSREG_GPIO(FLASH_WPn, SYS_FLASH, WPn), |
358 | }, | 366 | VEXPRESS_SYSREG_GPIO(LED0, SYS_LED, LED(0)), |
359 | [VEXPRESS_GPIO_MMC_WPROT] = { | 367 | VEXPRESS_SYSREG_GPIO(LED1, SYS_LED, LED(1)), |
360 | .reg = SYS_MCI, | 368 | VEXPRESS_SYSREG_GPIO(LED2, SYS_LED, LED(2)), |
361 | .value = SYS_MCI_WPROT, | 369 | VEXPRESS_SYSREG_GPIO(LED3, SYS_LED, LED(3)), |
362 | }, | 370 | VEXPRESS_SYSREG_GPIO(LED4, SYS_LED, LED(4)), |
363 | [VEXPRESS_GPIO_FLASH_WPn] = { | 371 | VEXPRESS_SYSREG_GPIO(LED5, SYS_LED, LED(5)), |
364 | .reg = SYS_FLASH, | 372 | VEXPRESS_SYSREG_GPIO(LED6, SYS_LED, LED(6)), |
365 | .value = SYS_FLASH_WPn, | 373 | VEXPRESS_SYSREG_GPIO(LED7, SYS_LED, LED(7)), |
366 | }, | ||
367 | }; | 374 | }; |
368 | 375 | ||
369 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | 376 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, |
@@ -372,12 +379,6 @@ static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | |||
372 | return 0; | 379 | return 0; |
373 | } | 380 | } |
374 | 381 | ||
375 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
376 | unsigned offset, int value) | ||
377 | { | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, | 382 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, |
382 | unsigned offset) | 383 | unsigned offset) |
383 | { | 384 | { |
@@ -401,6 +402,14 @@ static void vexpress_sysreg_gpio_set(struct gpio_chip *chip, | |||
401 | writel(reg_value, vexpress_sysreg_base + gpio->reg); | 402 | writel(reg_value, vexpress_sysreg_base + gpio->reg); |
402 | } | 403 | } |
403 | 404 | ||
405 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
406 | unsigned offset, int value) | ||
407 | { | ||
408 | vexpress_sysreg_gpio_set(chip, offset, value); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
404 | static struct gpio_chip vexpress_sysreg_gpio_chip = { | 413 | static struct gpio_chip vexpress_sysreg_gpio_chip = { |
405 | .label = "vexpress-sysreg", | 414 | .label = "vexpress-sysreg", |
406 | .direction_input = vexpress_sysreg_gpio_direction_input, | 415 | .direction_input = vexpress_sysreg_gpio_direction_input, |
@@ -412,6 +421,30 @@ static struct gpio_chip vexpress_sysreg_gpio_chip = { | |||
412 | }; | 421 | }; |
413 | 422 | ||
414 | 423 | ||
424 | #define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \ | ||
425 | { \ | ||
426 | .name = "v2m:green:"_name, \ | ||
427 | .default_trigger = _default_trigger, \ | ||
428 | .gpio = VEXPRESS_GPIO_##_gpio, \ | ||
429 | } | ||
430 | |||
431 | struct gpio_led vexpress_sysreg_leds[] = { | ||
432 | VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0), | ||
433 | VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1), | ||
434 | VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2), | ||
435 | VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3), | ||
436 | VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4), | ||
437 | VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5), | ||
438 | VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6), | ||
439 | VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7), | ||
440 | }; | ||
441 | |||
442 | struct gpio_led_platform_data vexpress_sysreg_leds_pdata = { | ||
443 | .num_leds = ARRAY_SIZE(vexpress_sysreg_leds), | ||
444 | .leds = vexpress_sysreg_leds, | ||
445 | }; | ||
446 | |||
447 | |||
415 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, | 448 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, |
416 | struct device_attribute *attr, char *buf) | 449 | struct device_attribute *attr, char *buf) |
417 | { | 450 | { |
@@ -456,6 +489,10 @@ static int vexpress_sysreg_probe(struct platform_device *pdev) | |||
456 | return err; | 489 | return err; |
457 | } | 490 | } |
458 | 491 | ||
492 | platform_device_register_data(vexpress_sysreg_dev, "leds-gpio", | ||
493 | PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata, | ||
494 | sizeof(vexpress_sysreg_leds_pdata)); | ||
495 | |||
459 | vexpress_sysreg_dev = &pdev->dev; | 496 | vexpress_sysreg_dev = &pdev->dev; |
460 | 497 | ||
461 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); | 498 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); |
diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h index c52215ff4245..75818744ab59 100644 --- a/include/linux/vexpress.h +++ b/include/linux/vexpress.h | |||
@@ -27,6 +27,14 @@ | |||
27 | #define VEXPRESS_GPIO_MMC_CARDIN 0 | 27 | #define VEXPRESS_GPIO_MMC_CARDIN 0 |
28 | #define VEXPRESS_GPIO_MMC_WPROT 1 | 28 | #define VEXPRESS_GPIO_MMC_WPROT 1 |
29 | #define VEXPRESS_GPIO_FLASH_WPn 2 | 29 | #define VEXPRESS_GPIO_FLASH_WPn 2 |
30 | #define VEXPRESS_GPIO_LED0 3 | ||
31 | #define VEXPRESS_GPIO_LED1 4 | ||
32 | #define VEXPRESS_GPIO_LED2 5 | ||
33 | #define VEXPRESS_GPIO_LED3 6 | ||
34 | #define VEXPRESS_GPIO_LED4 7 | ||
35 | #define VEXPRESS_GPIO_LED5 8 | ||
36 | #define VEXPRESS_GPIO_LED6 9 | ||
37 | #define VEXPRESS_GPIO_LED7 10 | ||
30 | 38 | ||
31 | #define VEXPRESS_RES_FUNC(_site, _func) \ | 39 | #define VEXPRESS_RES_FUNC(_site, _func) \ |
32 | { \ | 40 | { \ |