diff options
author | Mark Brown <broonie@linaro.org> | 2013-08-09 06:41:52 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-12 15:20:26 -0400 |
commit | 68b14134be55eca7340b9a8b3ec4cb8f79622a3c (patch) | |
tree | 9680d2c2dc0296d2e896c05827d941c4360931f8 /drivers/usb/misc/usb3503.c | |
parent | 8e7245b8386cb1dc941e10a4c97307e3f48da5da (diff) |
usb: misc: usb3503: Convert to regmap
This will give access to the diagnostic infrastructure regmap has but
the main point is to support future refactoring.
Signed-off-by: Mark Brown <broonie@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/misc/usb3503.c')
-rw-r--r-- | drivers/usb/misc/usb3503.c | 93 |
1 files changed, 36 insertions, 57 deletions
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index 4b6572a37e87..f2c0356b7148 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/of_gpio.h> | 26 | #include <linux/of_gpio.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/platform_data/usb3503.h> | 28 | #include <linux/platform_data/usb3503.h> |
29 | #include <linux/regmap.h> | ||
29 | 30 | ||
30 | #define USB3503_VIDL 0x00 | 31 | #define USB3503_VIDL 0x00 |
31 | #define USB3503_VIDM 0x01 | 32 | #define USB3503_VIDM 0x01 |
@@ -50,56 +51,18 @@ | |||
50 | #define USB3503_CFGP 0xee | 51 | #define USB3503_CFGP 0xee |
51 | #define USB3503_CLKSUSP (1 << 7) | 52 | #define USB3503_CLKSUSP (1 << 7) |
52 | 53 | ||
54 | #define USB3503_RESET 0xff | ||
55 | |||
53 | struct usb3503 { | 56 | struct usb3503 { |
54 | enum usb3503_mode mode; | 57 | enum usb3503_mode mode; |
55 | struct i2c_client *client; | 58 | struct regmap *regmap; |
59 | struct device *dev; | ||
56 | u8 port_off_mask; | 60 | u8 port_off_mask; |
57 | int gpio_intn; | 61 | int gpio_intn; |
58 | int gpio_reset; | 62 | int gpio_reset; |
59 | int gpio_connect; | 63 | int gpio_connect; |
60 | }; | 64 | }; |
61 | 65 | ||
62 | static int usb3503_write_register(struct i2c_client *client, | ||
63 | char reg, char data) | ||
64 | { | ||
65 | return i2c_smbus_write_byte_data(client, reg, data); | ||
66 | } | ||
67 | |||
68 | static int usb3503_read_register(struct i2c_client *client, char reg) | ||
69 | { | ||
70 | return i2c_smbus_read_byte_data(client, reg); | ||
71 | } | ||
72 | |||
73 | static int usb3503_set_bits(struct i2c_client *client, char reg, char req) | ||
74 | { | ||
75 | int err; | ||
76 | |||
77 | err = usb3503_read_register(client, reg); | ||
78 | if (err < 0) | ||
79 | return err; | ||
80 | |||
81 | err = usb3503_write_register(client, reg, err | req); | ||
82 | if (err < 0) | ||
83 | return err; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int usb3503_clear_bits(struct i2c_client *client, char reg, char req) | ||
89 | { | ||
90 | int err; | ||
91 | |||
92 | err = usb3503_read_register(client, reg); | ||
93 | if (err < 0) | ||
94 | return err; | ||
95 | |||
96 | err = usb3503_write_register(client, reg, err & ~req); | ||
97 | if (err < 0) | ||
98 | return err; | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int usb3503_reset(struct usb3503 *hub, int state) | 66 | static int usb3503_reset(struct usb3503 *hub, int state) |
104 | { | 67 | { |
105 | if (!state && gpio_is_valid(hub->gpio_connect)) | 68 | if (!state && gpio_is_valid(hub->gpio_connect)) |
@@ -117,7 +80,7 @@ static int usb3503_reset(struct usb3503 *hub, int state) | |||
117 | 80 | ||
118 | static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) | 81 | static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) |
119 | { | 82 | { |
120 | struct i2c_client *i2c = hub->client; | 83 | struct device *dev = hub->dev; |
121 | int err = 0; | 84 | int err = 0; |
122 | 85 | ||
123 | switch (mode) { | 86 | switch (mode) { |
@@ -125,37 +88,40 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) | |||
125 | usb3503_reset(hub, 1); | 88 | usb3503_reset(hub, 1); |
126 | 89 | ||
127 | /* SP_ILOCK: set connect_n, config_n for config */ | 90 | /* SP_ILOCK: set connect_n, config_n for config */ |
128 | err = usb3503_write_register(i2c, USB3503_SP_ILOCK, | 91 | err = regmap_write(hub->regmap, USB3503_SP_ILOCK, |
129 | (USB3503_SPILOCK_CONNECT | 92 | (USB3503_SPILOCK_CONNECT |
130 | | USB3503_SPILOCK_CONFIG)); | 93 | | USB3503_SPILOCK_CONFIG)); |
131 | if (err < 0) { | 94 | if (err < 0) { |
132 | dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); | 95 | dev_err(dev, "SP_ILOCK failed (%d)\n", err); |
133 | goto err_hubmode; | 96 | goto err_hubmode; |
134 | } | 97 | } |
135 | 98 | ||
136 | /* PDS : Disable For Self Powered Operation */ | 99 | /* PDS : Disable For Self Powered Operation */ |
137 | if (hub->port_off_mask) { | 100 | if (hub->port_off_mask) { |
138 | err = usb3503_set_bits(i2c, USB3503_PDS, | 101 | err = regmap_update_bits(hub->regmap, USB3503_PDS, |
102 | hub->port_off_mask, | ||
139 | hub->port_off_mask); | 103 | hub->port_off_mask); |
140 | if (err < 0) { | 104 | if (err < 0) { |
141 | dev_err(&i2c->dev, "PDS failed (%d)\n", err); | 105 | dev_err(dev, "PDS failed (%d)\n", err); |
142 | goto err_hubmode; | 106 | goto err_hubmode; |
143 | } | 107 | } |
144 | } | 108 | } |
145 | 109 | ||
146 | /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */ | 110 | /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */ |
147 | err = usb3503_set_bits(i2c, USB3503_CFG1, USB3503_SELF_BUS_PWR); | 111 | err = regmap_update_bits(hub->regmap, USB3503_CFG1, |
112 | USB3503_SELF_BUS_PWR, | ||
113 | USB3503_SELF_BUS_PWR); | ||
148 | if (err < 0) { | 114 | if (err < 0) { |
149 | dev_err(&i2c->dev, "CFG1 failed (%d)\n", err); | 115 | dev_err(dev, "CFG1 failed (%d)\n", err); |
150 | goto err_hubmode; | 116 | goto err_hubmode; |
151 | } | 117 | } |
152 | 118 | ||
153 | /* SP_LOCK: clear connect_n, config_n for hub connect */ | 119 | /* SP_LOCK: clear connect_n, config_n for hub connect */ |
154 | err = usb3503_clear_bits(i2c, USB3503_SP_ILOCK, | 120 | err = regmap_update_bits(hub->regmap, USB3503_SP_ILOCK, |
155 | (USB3503_SPILOCK_CONNECT | 121 | (USB3503_SPILOCK_CONNECT |
156 | | USB3503_SPILOCK_CONFIG)); | 122 | | USB3503_SPILOCK_CONFIG), 0); |
157 | if (err < 0) { | 123 | if (err < 0) { |
158 | dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); | 124 | dev_err(dev, "SP_ILOCK failed (%d)\n", err); |
159 | goto err_hubmode; | 125 | goto err_hubmode; |
160 | } | 126 | } |
161 | 127 | ||
@@ -163,18 +129,18 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) | |||
163 | gpio_set_value_cansleep(hub->gpio_connect, 1); | 129 | gpio_set_value_cansleep(hub->gpio_connect, 1); |
164 | 130 | ||
165 | hub->mode = mode; | 131 | hub->mode = mode; |
166 | dev_info(&i2c->dev, "switched to HUB mode\n"); | 132 | dev_info(dev, "switched to HUB mode\n"); |
167 | break; | 133 | break; |
168 | 134 | ||
169 | case USB3503_MODE_STANDBY: | 135 | case USB3503_MODE_STANDBY: |
170 | usb3503_reset(hub, 0); | 136 | usb3503_reset(hub, 0); |
171 | 137 | ||
172 | hub->mode = mode; | 138 | hub->mode = mode; |
173 | dev_info(&i2c->dev, "switched to STANDBY mode\n"); | 139 | dev_info(dev, "switched to STANDBY mode\n"); |
174 | break; | 140 | break; |
175 | 141 | ||
176 | default: | 142 | default: |
177 | dev_err(&i2c->dev, "unknown mode is request\n"); | 143 | dev_err(dev, "unknown mode is request\n"); |
178 | err = -EINVAL; | 144 | err = -EINVAL; |
179 | break; | 145 | break; |
180 | } | 146 | } |
@@ -183,6 +149,13 @@ err_hubmode: | |||
183 | return err; | 149 | return err; |
184 | } | 150 | } |
185 | 151 | ||
152 | static const struct regmap_config usb3503_regmap_config = { | ||
153 | .reg_bits = 8, | ||
154 | .val_bits = 8, | ||
155 | |||
156 | .max_register = USB3503_RESET, | ||
157 | }; | ||
158 | |||
186 | static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | 159 | static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id) |
187 | { | 160 | { |
188 | struct usb3503_platform_data *pdata = dev_get_platdata(&i2c->dev); | 161 | struct usb3503_platform_data *pdata = dev_get_platdata(&i2c->dev); |
@@ -200,7 +173,13 @@ static int usb3503_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
200 | } | 173 | } |
201 | 174 | ||
202 | i2c_set_clientdata(i2c, hub); | 175 | i2c_set_clientdata(i2c, hub); |
203 | hub->client = i2c; | 176 | hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config); |
177 | if (IS_ERR(hub->regmap)) { | ||
178 | err = PTR_ERR(hub->regmap); | ||
179 | dev_err(&i2c->dev, "Failed to initialise regmap: %d\n", err); | ||
180 | return err; | ||
181 | } | ||
182 | hub->dev = &i2c->dev; | ||
204 | 183 | ||
205 | if (pdata) { | 184 | if (pdata) { |
206 | hub->port_off_mask = pdata->port_off_mask; | 185 | hub->port_off_mask = pdata->port_off_mask; |