diff options
Diffstat (limited to 'drivers/video/backlight/ld9040.c')
-rw-r--r-- | drivers/video/backlight/ld9040.c | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c index da9a5ce0ccb8..78dafc0c8fc5 100644 --- a/drivers/video/backlight/ld9040.c +++ b/drivers/video/backlight/ld9040.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/lcd.h> | 31 | #include <linux/lcd.h> |
32 | #include <linux/backlight.h> | 32 | #include <linux/backlight.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/regulator/consumer.h> | ||
34 | 35 | ||
35 | #include "ld9040_gamma.h" | 36 | #include "ld9040_gamma.h" |
36 | 37 | ||
@@ -53,8 +54,51 @@ struct ld9040 { | |||
53 | struct lcd_device *ld; | 54 | struct lcd_device *ld; |
54 | struct backlight_device *bd; | 55 | struct backlight_device *bd; |
55 | struct lcd_platform_data *lcd_pd; | 56 | struct lcd_platform_data *lcd_pd; |
57 | |||
58 | struct mutex lock; | ||
59 | bool enabled; | ||
60 | }; | ||
61 | |||
62 | static struct regulator_bulk_data supplies[] = { | ||
63 | { .supply = "vdd3", }, | ||
64 | { .supply = "vci", }, | ||
56 | }; | 65 | }; |
57 | 66 | ||
67 | static void ld9040_regulator_enable(struct ld9040 *lcd) | ||
68 | { | ||
69 | int ret = 0; | ||
70 | struct lcd_platform_data *pd = NULL; | ||
71 | |||
72 | pd = lcd->lcd_pd; | ||
73 | mutex_lock(&lcd->lock); | ||
74 | if (!lcd->enabled) { | ||
75 | ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies); | ||
76 | if (ret) | ||
77 | goto out; | ||
78 | |||
79 | lcd->enabled = true; | ||
80 | } | ||
81 | mdelay(pd->power_on_delay); | ||
82 | out: | ||
83 | mutex_unlock(&lcd->lock); | ||
84 | } | ||
85 | |||
86 | static void ld9040_regulator_disable(struct ld9040 *lcd) | ||
87 | { | ||
88 | int ret = 0; | ||
89 | |||
90 | mutex_lock(&lcd->lock); | ||
91 | if (lcd->enabled) { | ||
92 | ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies); | ||
93 | if (ret) | ||
94 | goto out; | ||
95 | |||
96 | lcd->enabled = false; | ||
97 | } | ||
98 | out: | ||
99 | mutex_unlock(&lcd->lock); | ||
100 | } | ||
101 | |||
58 | static const unsigned short seq_swreset[] = { | 102 | static const unsigned short seq_swreset[] = { |
59 | 0x01, COMMAND_ONLY, | 103 | 0x01, COMMAND_ONLY, |
60 | ENDDEF, 0x00 | 104 | ENDDEF, 0x00 |
@@ -532,13 +576,8 @@ static int ld9040_power_on(struct ld9040 *lcd) | |||
532 | return -EFAULT; | 576 | return -EFAULT; |
533 | } | 577 | } |
534 | 578 | ||
535 | if (!pd->power_on) { | 579 | /* lcd power on */ |
536 | dev_err(lcd->dev, "power_on is NULL.\n"); | 580 | ld9040_regulator_enable(lcd); |
537 | return -EFAULT; | ||
538 | } else { | ||
539 | pd->power_on(lcd->ld, 1); | ||
540 | mdelay(pd->power_on_delay); | ||
541 | } | ||
542 | 581 | ||
543 | if (!pd->reset) { | 582 | if (!pd->reset) { |
544 | dev_err(lcd->dev, "reset is NULL.\n"); | 583 | dev_err(lcd->dev, "reset is NULL.\n"); |
@@ -582,11 +621,8 @@ static int ld9040_power_off(struct ld9040 *lcd) | |||
582 | 621 | ||
583 | mdelay(pd->power_off_delay); | 622 | mdelay(pd->power_off_delay); |
584 | 623 | ||
585 | if (!pd->power_on) { | 624 | /* lcd power off */ |
586 | dev_err(lcd->dev, "power_on is NULL.\n"); | 625 | ld9040_regulator_disable(lcd); |
587 | return -EFAULT; | ||
588 | } else | ||
589 | pd->power_on(lcd->ld, 0); | ||
590 | 626 | ||
591 | return 0; | 627 | return 0; |
592 | } | 628 | } |
@@ -693,6 +729,14 @@ static int ld9040_probe(struct spi_device *spi) | |||
693 | goto out_free_lcd; | 729 | goto out_free_lcd; |
694 | } | 730 | } |
695 | 731 | ||
732 | mutex_init(&lcd->lock); | ||
733 | |||
734 | ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies); | ||
735 | if (ret) { | ||
736 | dev_err(lcd->dev, "Failed to get regulators: %d\n", ret); | ||
737 | goto out_free_lcd; | ||
738 | } | ||
739 | |||
696 | ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops); | 740 | ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops); |
697 | if (IS_ERR(ld)) { | 741 | if (IS_ERR(ld)) { |
698 | ret = PTR_ERR(ld); | 742 | ret = PTR_ERR(ld); |
@@ -739,6 +783,8 @@ static int ld9040_probe(struct spi_device *spi) | |||
739 | out_unregister_lcd: | 783 | out_unregister_lcd: |
740 | lcd_device_unregister(lcd->ld); | 784 | lcd_device_unregister(lcd->ld); |
741 | out_free_lcd: | 785 | out_free_lcd: |
786 | regulator_bulk_free(ARRAY_SIZE(supplies), supplies); | ||
787 | |||
742 | kfree(lcd); | 788 | kfree(lcd); |
743 | return ret; | 789 | return ret; |
744 | } | 790 | } |
@@ -750,6 +796,7 @@ static int __devexit ld9040_remove(struct spi_device *spi) | |||
750 | ld9040_power(lcd, FB_BLANK_POWERDOWN); | 796 | ld9040_power(lcd, FB_BLANK_POWERDOWN); |
751 | backlight_device_unregister(lcd->bd); | 797 | backlight_device_unregister(lcd->bd); |
752 | lcd_device_unregister(lcd->ld); | 798 | lcd_device_unregister(lcd->ld); |
799 | regulator_bulk_free(ARRAY_SIZE(supplies), supplies); | ||
753 | kfree(lcd); | 800 | kfree(lcd); |
754 | 801 | ||
755 | return 0; | 802 | return 0; |