]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/leds/leds-lp55xx-common.c
leds-lp55xx: use lp55xx common deinit function
[mirror_ubuntu-artful-kernel.git] / drivers / leds / leds-lp55xx-common.c
CommitLineData
c93d08fa
MWK
1/*
2 * LP5521/LP5523/LP55231 Common Driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Derived from leds-lp5521.c, leds-lp5523.c
13 */
14
a85908dd 15#include <linux/delay.h>
c93d08fa
MWK
16#include <linux/i2c.h>
17#include <linux/leds.h>
18#include <linux/module.h>
19#include <linux/platform_data/leds-lp55xx.h>
20
21#include "leds-lp55xx-common.h"
22
48068d5d
MWK
23static void lp55xx_reset_device(struct lp55xx_chip *chip)
24{
25 struct lp55xx_device_config *cfg = chip->cfg;
26 u8 addr = cfg->reset.addr;
27 u8 val = cfg->reset.val;
28
29 /* no error checking here because no ACK from the device after reset */
30 lp55xx_write(chip, addr, val);
31}
32
e3a700d8
MWK
33static int lp55xx_detect_device(struct lp55xx_chip *chip)
34{
35 struct lp55xx_device_config *cfg = chip->cfg;
36 u8 addr = cfg->enable.addr;
37 u8 val = cfg->enable.val;
38 int ret;
39
40 ret = lp55xx_write(chip, addr, val);
41 if (ret)
42 return ret;
43
44 usleep_range(1000, 2000);
45
46 ret = lp55xx_read(chip, addr, &val);
47 if (ret)
48 return ret;
49
50 if (val != cfg->enable.val)
51 return -ENODEV;
52
53 return 0;
54}
55
ffbdccdb
MWK
56static int lp55xx_post_init_device(struct lp55xx_chip *chip)
57{
58 struct lp55xx_device_config *cfg = chip->cfg;
59
60 if (!cfg->post_init_device)
61 return 0;
62
63 return cfg->post_init_device(chip);
64}
65
c93d08fa
MWK
66int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)
67{
68 return i2c_smbus_write_byte_data(chip->cl, reg, val);
69}
70EXPORT_SYMBOL_GPL(lp55xx_write);
71
72int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val)
73{
74 s32 ret;
75
76 ret = i2c_smbus_read_byte_data(chip->cl, reg);
77 if (ret < 0)
78 return ret;
79
80 *val = ret;
81 return 0;
82}
83EXPORT_SYMBOL_GPL(lp55xx_read);
84
85int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
86{
87 int ret;
88 u8 tmp;
89
90 ret = lp55xx_read(chip, reg, &tmp);
91 if (ret)
92 return ret;
93
94 tmp &= ~mask;
95 tmp |= val & mask;
96
97 return lp55xx_write(chip, reg, tmp);
98}
99EXPORT_SYMBOL_GPL(lp55xx_update_bits);
100
a85908dd
MWK
101int lp55xx_init_device(struct lp55xx_chip *chip)
102{
103 struct lp55xx_platform_data *pdata;
48068d5d 104 struct lp55xx_device_config *cfg;
a85908dd
MWK
105 struct device *dev = &chip->cl->dev;
106 int ret = 0;
107
108 WARN_ON(!chip);
109
110 pdata = chip->pdata;
48068d5d 111 cfg = chip->cfg;
a85908dd 112
48068d5d 113 if (!pdata || !cfg)
a85908dd
MWK
114 return -EINVAL;
115
116 if (pdata->setup_resources) {
117 ret = pdata->setup_resources();
118 if (ret < 0) {
119 dev_err(dev, "setup resoure err: %d\n", ret);
120 goto err;
121 }
122 }
123
124 if (pdata->enable) {
125 pdata->enable(0);
126 usleep_range(1000, 2000); /* Keep enable down at least 1ms */
127 pdata->enable(1);
128 usleep_range(1000, 2000); /* 500us abs min. */
129 }
130
48068d5d
MWK
131 lp55xx_reset_device(chip);
132
133 /*
134 * Exact value is not available. 10 - 20ms
135 * appears to be enough for reset.
136 */
137 usleep_range(10000, 20000);
138
e3a700d8
MWK
139 ret = lp55xx_detect_device(chip);
140 if (ret) {
141 dev_err(dev, "device detection err: %d\n", ret);
142 goto err;
143 }
144
ffbdccdb
MWK
145 /* chip specific initialization */
146 ret = lp55xx_post_init_device(chip);
22ebeb48
MWK
147 if (ret) {
148 dev_err(dev, "post init device err: %d\n", ret);
149 goto err_post_init;
150 }
ffbdccdb
MWK
151
152 return 0;
153
22ebeb48 154err_post_init:
6ce61762
MWK
155 lp55xx_deinit_device(chip);
156err:
157 return ret;
158}
159EXPORT_SYMBOL_GPL(lp55xx_init_device);
160
161void lp55xx_deinit_device(struct lp55xx_chip *chip)
162{
163 struct lp55xx_platform_data *pdata = chip->pdata;
164
22ebeb48
MWK
165 if (pdata->enable)
166 pdata->enable(0);
6ce61762 167
22ebeb48
MWK
168 if (pdata->release_resources)
169 pdata->release_resources();
a85908dd 170}
6ce61762 171EXPORT_SYMBOL_GPL(lp55xx_deinit_device);
a85908dd 172
c93d08fa
MWK
173MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
174MODULE_DESCRIPTION("LP55xx Common Driver");
175MODULE_LICENSE("GPL");