leds-lp55xx: use lp55xx common init function - post int
[deliverable/linux.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);
147
148 return 0;
149
a85908dd
MWK
150err:
151 return ret;
152}
153EXPORT_SYMBOL_GPL(lp55xx_init_device);
154
c93d08fa
MWK
155MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
156MODULE_DESCRIPTION("LP55xx Common Driver");
157MODULE_LICENSE("GPL");
This page took 0.042195 seconds and 5 git commands to generate.