diff options
Diffstat (limited to 'drivers/extcon/extcon-max8997.c')
-rw-r--r-- | drivers/extcon/extcon-max8997.c | 734 |
1 files changed, 496 insertions, 238 deletions
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 93009fe6ef05..e636d950ad6c 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c | |||
@@ -29,51 +29,14 @@ | |||
29 | #include <linux/irqdomain.h> | 29 | #include <linux/irqdomain.h> |
30 | 30 | ||
31 | #define DEV_NAME "max8997-muic" | 31 | #define DEV_NAME "max8997-muic" |
32 | #define DELAY_MS_DEFAULT 20000 /* unit: millisecond */ | ||
32 | 33 | ||
33 | /* MAX8997-MUIC STATUS1 register */ | 34 | enum max8997_muic_adc_debounce_time { |
34 | #define STATUS1_ADC_SHIFT 0 | 35 | ADC_DEBOUNCE_TIME_0_5MS = 0, /* 0.5ms */ |
35 | #define STATUS1_ADCLOW_SHIFT 5 | 36 | ADC_DEBOUNCE_TIME_10MS, /* 10ms */ |
36 | #define STATUS1_ADCERR_SHIFT 6 | 37 | ADC_DEBOUNCE_TIME_25MS, /* 25ms */ |
37 | #define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT) | 38 | ADC_DEBOUNCE_TIME_38_62MS, /* 38.62ms */ |
38 | #define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT) | 39 | }; |
39 | #define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT) | ||
40 | |||
41 | /* MAX8997-MUIC STATUS2 register */ | ||
42 | #define STATUS2_CHGTYP_SHIFT 0 | ||
43 | #define STATUS2_CHGDETRUN_SHIFT 3 | ||
44 | #define STATUS2_DCDTMR_SHIFT 4 | ||
45 | #define STATUS2_DBCHG_SHIFT 5 | ||
46 | #define STATUS2_VBVOLT_SHIFT 6 | ||
47 | #define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT) | ||
48 | #define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT) | ||
49 | #define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT) | ||
50 | #define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT) | ||
51 | #define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT) | ||
52 | |||
53 | /* MAX8997-MUIC STATUS3 register */ | ||
54 | #define STATUS3_OVP_SHIFT 2 | ||
55 | #define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT) | ||
56 | |||
57 | /* MAX8997-MUIC CONTROL1 register */ | ||
58 | #define COMN1SW_SHIFT 0 | ||
59 | #define COMP2SW_SHIFT 3 | ||
60 | #define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) | ||
61 | #define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) | ||
62 | #define SW_MASK (COMP2SW_MASK | COMN1SW_MASK) | ||
63 | |||
64 | #define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT)) | ||
65 | #define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT)) | ||
66 | #define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT)) | ||
67 | #define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT)) | ||
68 | |||
69 | #define MAX8997_ADC_GROUND 0x00 | ||
70 | #define MAX8997_ADC_MHL 0x01 | ||
71 | #define MAX8997_ADC_JIG_USB_1 0x18 | ||
72 | #define MAX8997_ADC_JIG_USB_2 0x19 | ||
73 | #define MAX8997_ADC_DESKDOCK 0x1a | ||
74 | #define MAX8997_ADC_JIG_UART 0x1c | ||
75 | #define MAX8997_ADC_CARDOCK 0x1d | ||
76 | #define MAX8997_ADC_OPEN 0x1f | ||
77 | 40 | ||
78 | struct max8997_muic_irq { | 41 | struct max8997_muic_irq { |
79 | unsigned int irq; | 42 | unsigned int irq; |
@@ -82,61 +45,303 @@ struct max8997_muic_irq { | |||
82 | }; | 45 | }; |
83 | 46 | ||
84 | static struct max8997_muic_irq muic_irqs[] = { | 47 | static struct max8997_muic_irq muic_irqs[] = { |
85 | { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" }, | 48 | { MAX8997_MUICIRQ_ADCError, "muic-ADCERROR" }, |
86 | { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" }, | 49 | { MAX8997_MUICIRQ_ADCLow, "muic-ADCLOW" }, |
87 | { MAX8997_MUICIRQ_ADC, "muic-ADC" }, | 50 | { MAX8997_MUICIRQ_ADC, "muic-ADC" }, |
88 | { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" }, | 51 | { MAX8997_MUICIRQ_VBVolt, "muic-VBVOLT" }, |
89 | { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" }, | 52 | { MAX8997_MUICIRQ_DBChg, "muic-DBCHG" }, |
90 | { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" }, | 53 | { MAX8997_MUICIRQ_DCDTmr, "muic-DCDTMR" }, |
91 | { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" }, | 54 | { MAX8997_MUICIRQ_ChgDetRun, "muic-CHGDETRUN" }, |
92 | { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" }, | 55 | { MAX8997_MUICIRQ_ChgTyp, "muic-CHGTYP" }, |
93 | { MAX8997_MUICIRQ_OVP, "muic-over_voltage" }, | 56 | { MAX8997_MUICIRQ_OVP, "muic-OVP" }, |
57 | }; | ||
58 | |||
59 | /* Define supported cable type */ | ||
60 | enum max8997_muic_acc_type { | ||
61 | MAX8997_MUIC_ADC_GROUND = 0x0, | ||
62 | MAX8997_MUIC_ADC_MHL, /* MHL*/ | ||
63 | MAX8997_MUIC_ADC_REMOTE_S1_BUTTON, | ||
64 | MAX8997_MUIC_ADC_REMOTE_S2_BUTTON, | ||
65 | MAX8997_MUIC_ADC_REMOTE_S3_BUTTON, | ||
66 | MAX8997_MUIC_ADC_REMOTE_S4_BUTTON, | ||
67 | MAX8997_MUIC_ADC_REMOTE_S5_BUTTON, | ||
68 | MAX8997_MUIC_ADC_REMOTE_S6_BUTTON, | ||
69 | MAX8997_MUIC_ADC_REMOTE_S7_BUTTON, | ||
70 | MAX8997_MUIC_ADC_REMOTE_S8_BUTTON, | ||
71 | MAX8997_MUIC_ADC_REMOTE_S9_BUTTON, | ||
72 | MAX8997_MUIC_ADC_REMOTE_S10_BUTTON, | ||
73 | MAX8997_MUIC_ADC_REMOTE_S11_BUTTON, | ||
74 | MAX8997_MUIC_ADC_REMOTE_S12_BUTTON, | ||
75 | MAX8997_MUIC_ADC_RESERVED_ACC_1, | ||
76 | MAX8997_MUIC_ADC_RESERVED_ACC_2, | ||
77 | MAX8997_MUIC_ADC_RESERVED_ACC_3, | ||
78 | MAX8997_MUIC_ADC_RESERVED_ACC_4, | ||
79 | MAX8997_MUIC_ADC_RESERVED_ACC_5, | ||
80 | MAX8997_MUIC_ADC_CEA936_AUDIO, | ||
81 | MAX8997_MUIC_ADC_PHONE_POWERED_DEV, | ||
82 | MAX8997_MUIC_ADC_TTY_CONVERTER, | ||
83 | MAX8997_MUIC_ADC_UART_CABLE, | ||
84 | MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG, | ||
85 | MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF, /* JIG-USB-OFF */ | ||
86 | MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON, /* JIG-USB-ON */ | ||
87 | MAX8997_MUIC_ADC_AV_CABLE_NOLOAD, /* DESKDOCK */ | ||
88 | MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG, | ||
89 | MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF, /* JIG-UART */ | ||
90 | MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON, /* CARDOCK */ | ||
91 | MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE, | ||
92 | MAX8997_MUIC_ADC_OPEN, /* OPEN */ | ||
93 | }; | ||
94 | |||
95 | enum max8997_muic_cable_group { | ||
96 | MAX8997_CABLE_GROUP_ADC = 0, | ||
97 | MAX8997_CABLE_GROUP_ADC_GND, | ||
98 | MAX8997_CABLE_GROUP_CHG, | ||
99 | MAX8997_CABLE_GROUP_VBVOLT, | ||
100 | }; | ||
101 | |||
102 | enum max8997_muic_usb_type { | ||
103 | MAX8997_USB_HOST, | ||
104 | MAX8997_USB_DEVICE, | ||
105 | }; | ||
106 | |||
107 | enum max8997_muic_charger_type { | ||
108 | MAX8997_CHARGER_TYPE_NONE = 0, | ||
109 | MAX8997_CHARGER_TYPE_USB, | ||
110 | MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT, | ||
111 | MAX8997_CHARGER_TYPE_DEDICATED_CHG, | ||
112 | MAX8997_CHARGER_TYPE_500MA, | ||
113 | MAX8997_CHARGER_TYPE_1A, | ||
114 | MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7, | ||
94 | }; | 115 | }; |
95 | 116 | ||
96 | struct max8997_muic_info { | 117 | struct max8997_muic_info { |
97 | struct device *dev; | 118 | struct device *dev; |
98 | struct i2c_client *muic; | 119 | struct i2c_client *muic; |
99 | struct max8997_muic_platform_data *muic_pdata; | 120 | struct extcon_dev *edev; |
121 | int prev_cable_type; | ||
122 | int prev_chg_type; | ||
123 | u8 status[2]; | ||
100 | 124 | ||
101 | int irq; | 125 | int irq; |
102 | struct work_struct irq_work; | 126 | struct work_struct irq_work; |
127 | struct mutex mutex; | ||
103 | 128 | ||
129 | struct max8997_muic_platform_data *muic_pdata; | ||
104 | enum max8997_muic_charger_type pre_charger_type; | 130 | enum max8997_muic_charger_type pre_charger_type; |
105 | int pre_adc; | ||
106 | 131 | ||
107 | struct mutex mutex; | 132 | /* |
133 | * Use delayed workqueue to detect cable state and then | ||
134 | * notify cable state to notifiee/platform through uevent. | ||
135 | * After completing the booting of platform, the extcon provider | ||
136 | * driver should notify cable state to upper layer. | ||
137 | */ | ||
138 | struct delayed_work wq_detcable; | ||
139 | |||
140 | /* | ||
141 | * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB | ||
142 | * h/w path of COMP2/COMN1 on CONTROL1 register. | ||
143 | */ | ||
144 | int path_usb; | ||
145 | int path_uart; | ||
146 | }; | ||
108 | 147 | ||
109 | struct extcon_dev *edev; | 148 | enum { |
149 | EXTCON_CABLE_USB = 0, | ||
150 | EXTCON_CABLE_USB_HOST, | ||
151 | EXTCON_CABLE_TA, | ||
152 | EXTCON_CABLE_FAST_CHARGER, | ||
153 | EXTCON_CABLE_SLOW_CHARGER, | ||
154 | EXTCON_CABLE_CHARGE_DOWNSTREAM, | ||
155 | EXTCON_CABLE_MHL, | ||
156 | EXTCON_CABLE_DOCK_DESK, | ||
157 | EXTCON_CABLE_DOCK_CARD, | ||
158 | EXTCON_CABLE_JIG, | ||
159 | |||
160 | _EXTCON_CABLE_NUM, | ||
110 | }; | 161 | }; |
111 | 162 | ||
112 | const char *max8997_extcon_cable[] = { | 163 | static const char *max8997_extcon_cable[] = { |
113 | [0] = "USB", | 164 | [EXTCON_CABLE_USB] = "USB", |
114 | [1] = "USB-Host", | 165 | [EXTCON_CABLE_USB_HOST] = "USB-Host", |
115 | [2] = "TA", | 166 | [EXTCON_CABLE_TA] = "TA", |
116 | [3] = "Fast-charger", | 167 | [EXTCON_CABLE_FAST_CHARGER] = "Fast-charger", |
117 | [4] = "Slow-charger", | 168 | [EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger", |
118 | [5] = "Charge-downstream", | 169 | [EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream", |
119 | [6] = "MHL", | 170 | [EXTCON_CABLE_MHL] = "MHL", |
120 | [7] = "Dock-desk", | 171 | [EXTCON_CABLE_DOCK_DESK] = "Dock-Desk", |
121 | [8] = "Dock-card", | 172 | [EXTCON_CABLE_DOCK_CARD] = "Dock-Card", |
122 | [9] = "JIG", | 173 | [EXTCON_CABLE_JIG] = "JIG", |
123 | 174 | ||
124 | NULL, | 175 | NULL, |
125 | }; | 176 | }; |
126 | 177 | ||
178 | /* | ||
179 | * max8997_muic_set_debounce_time - Set the debounce time of ADC | ||
180 | * @info: the instance including private data of max8997 MUIC | ||
181 | * @time: the debounce time of ADC | ||
182 | */ | ||
183 | static int max8997_muic_set_debounce_time(struct max8997_muic_info *info, | ||
184 | enum max8997_muic_adc_debounce_time time) | ||
185 | { | ||
186 | int ret; | ||
187 | |||
188 | switch (time) { | ||
189 | case ADC_DEBOUNCE_TIME_0_5MS: | ||
190 | case ADC_DEBOUNCE_TIME_10MS: | ||
191 | case ADC_DEBOUNCE_TIME_25MS: | ||
192 | case ADC_DEBOUNCE_TIME_38_62MS: | ||
193 | ret = max8997_update_reg(info->muic, | ||
194 | MAX8997_MUIC_REG_CONTROL3, | ||
195 | time << CONTROL3_ADCDBSET_SHIFT, | ||
196 | CONTROL3_ADCDBSET_MASK); | ||
197 | if (ret) { | ||
198 | dev_err(info->dev, "failed to set ADC debounce time\n"); | ||
199 | return -EAGAIN; | ||
200 | } | ||
201 | break; | ||
202 | default: | ||
203 | dev_err(info->dev, "invalid ADC debounce time\n"); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | }; | ||
209 | |||
210 | /* | ||
211 | * max8997_muic_set_path - Set hardware line according to attached cable | ||
212 | * @info: the instance including private data of max8997 MUIC | ||
213 | * @value: the path according to attached cable | ||
214 | * @attached: the state of cable (true:attached, false:detached) | ||
215 | * | ||
216 | * The max8997 MUIC device share outside H/W line among a varity of cables, | ||
217 | * so this function set internal path of H/W line according to the type of | ||
218 | * attached cable. | ||
219 | */ | ||
220 | static int max8997_muic_set_path(struct max8997_muic_info *info, | ||
221 | u8 val, bool attached) | ||
222 | { | ||
223 | int ret = 0; | ||
224 | u8 ctrl1, ctrl2 = 0; | ||
225 | |||
226 | if (attached) | ||
227 | ctrl1 = val; | ||
228 | else | ||
229 | ctrl1 = CONTROL1_SW_OPEN; | ||
230 | |||
231 | ret = max8997_update_reg(info->muic, | ||
232 | MAX8997_MUIC_REG_CONTROL1, ctrl1, COMP_SW_MASK); | ||
233 | if (ret < 0) { | ||
234 | dev_err(info->dev, "failed to update MUIC register\n"); | ||
235 | return -EAGAIN; | ||
236 | } | ||
237 | |||
238 | if (attached) | ||
239 | ctrl2 |= CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */ | ||
240 | else | ||
241 | ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ | ||
242 | |||
243 | ret = max8997_update_reg(info->muic, | ||
244 | MAX8997_MUIC_REG_CONTROL2, ctrl2, | ||
245 | CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); | ||
246 | if (ret < 0) { | ||
247 | dev_err(info->dev, "failed to update MUIC register\n"); | ||
248 | return -EAGAIN; | ||
249 | } | ||
250 | |||
251 | dev_info(info->dev, | ||
252 | "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n", | ||
253 | ctrl1, ctrl2, attached ? "attached" : "detached"); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * max8997_muic_get_cable_type - Return cable type and check cable state | ||
260 | * @info: the instance including private data of max8997 MUIC | ||
261 | * @group: the path according to attached cable | ||
262 | * @attached: store cable state and return | ||
263 | * | ||
264 | * This function check the cable state either attached or detached, | ||
265 | * and then divide precise type of cable according to cable group. | ||
266 | * - MAX8997_CABLE_GROUP_ADC | ||
267 | * - MAX8997_CABLE_GROUP_CHG | ||
268 | */ | ||
269 | static int max8997_muic_get_cable_type(struct max8997_muic_info *info, | ||
270 | enum max8997_muic_cable_group group, bool *attached) | ||
271 | { | ||
272 | int cable_type = 0; | ||
273 | int adc; | ||
274 | int chg_type; | ||
275 | |||
276 | switch (group) { | ||
277 | case MAX8997_CABLE_GROUP_ADC: | ||
278 | /* | ||
279 | * Read ADC value to check cable type and decide cable state | ||
280 | * according to cable type | ||
281 | */ | ||
282 | adc = info->status[0] & STATUS1_ADC_MASK; | ||
283 | adc >>= STATUS1_ADC_SHIFT; | ||
284 | |||
285 | /* | ||
286 | * Check current cable state/cable type and store cable type | ||
287 | * (info->prev_cable_type) for handling cable when cable is | ||
288 | * detached. | ||
289 | */ | ||
290 | if (adc == MAX8997_MUIC_ADC_OPEN) { | ||
291 | *attached = false; | ||
292 | |||
293 | cable_type = info->prev_cable_type; | ||
294 | info->prev_cable_type = MAX8997_MUIC_ADC_OPEN; | ||
295 | } else { | ||
296 | *attached = true; | ||
297 | |||
298 | cable_type = info->prev_cable_type = adc; | ||
299 | } | ||
300 | break; | ||
301 | case MAX8997_CABLE_GROUP_CHG: | ||
302 | /* | ||
303 | * Read charger type to check cable type and decide cable state | ||
304 | * according to type of charger cable. | ||
305 | */ | ||
306 | chg_type = info->status[1] & STATUS2_CHGTYP_MASK; | ||
307 | chg_type >>= STATUS2_CHGTYP_SHIFT; | ||
308 | |||
309 | if (chg_type == MAX8997_CHARGER_TYPE_NONE) { | ||
310 | *attached = false; | ||
311 | |||
312 | cable_type = info->prev_chg_type; | ||
313 | info->prev_chg_type = MAX8997_CHARGER_TYPE_NONE; | ||
314 | } else { | ||
315 | *attached = true; | ||
316 | |||
317 | /* | ||
318 | * Check current cable state/cable type and store cable | ||
319 | * type(info->prev_chg_type) for handling cable when | ||
320 | * charger cable is detached. | ||
321 | */ | ||
322 | cable_type = info->prev_chg_type = chg_type; | ||
323 | } | ||
324 | |||
325 | break; | ||
326 | default: | ||
327 | dev_err(info->dev, "Unknown cable group (%d)\n", group); | ||
328 | cable_type = -EINVAL; | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | return cable_type; | ||
333 | } | ||
334 | |||
127 | static int max8997_muic_handle_usb(struct max8997_muic_info *info, | 335 | static int max8997_muic_handle_usb(struct max8997_muic_info *info, |
128 | enum max8997_muic_usb_type usb_type, bool attached) | 336 | enum max8997_muic_usb_type usb_type, bool attached) |
129 | { | 337 | { |
130 | int ret = 0; | 338 | int ret = 0; |
131 | 339 | ||
132 | if (usb_type == MAX8997_USB_HOST) { | 340 | if (usb_type == MAX8997_USB_HOST) { |
133 | /* switch to USB */ | 341 | ret = max8997_muic_set_path(info, info->path_usb, attached); |
134 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | 342 | if (ret < 0) { |
135 | attached ? MAX8997_SW_USB : MAX8997_SW_OPEN, | ||
136 | SW_MASK); | ||
137 | if (ret) { | ||
138 | dev_err(info->dev, "failed to update muic register\n"); | 343 | dev_err(info->dev, "failed to update muic register\n"); |
139 | goto out; | 344 | return ret; |
140 | } | 345 | } |
141 | } | 346 | } |
142 | 347 | ||
@@ -148,41 +353,39 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, | |||
148 | extcon_set_cable_state(info->edev, "USB", attached); | 353 | extcon_set_cable_state(info->edev, "USB", attached); |
149 | break; | 354 | break; |
150 | default: | 355 | default: |
151 | ret = -EINVAL; | 356 | dev_err(info->dev, "failed to detect %s usb cable\n", |
152 | break; | 357 | attached ? "attached" : "detached"); |
358 | return -EINVAL; | ||
153 | } | 359 | } |
154 | 360 | ||
155 | out: | 361 | return 0; |
156 | return ret; | ||
157 | } | 362 | } |
158 | 363 | ||
159 | static int max8997_muic_handle_dock(struct max8997_muic_info *info, | 364 | static int max8997_muic_handle_dock(struct max8997_muic_info *info, |
160 | int adc, bool attached) | 365 | int cable_type, bool attached) |
161 | { | 366 | { |
162 | int ret = 0; | 367 | int ret = 0; |
163 | 368 | ||
164 | /* switch to AUDIO */ | 369 | ret = max8997_muic_set_path(info, CONTROL1_SW_AUDIO, attached); |
165 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | ||
166 | attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN, | ||
167 | SW_MASK); | ||
168 | if (ret) { | 370 | if (ret) { |
169 | dev_err(info->dev, "failed to update muic register\n"); | 371 | dev_err(info->dev, "failed to update muic register\n"); |
170 | goto out; | 372 | return ret; |
171 | } | 373 | } |
172 | 374 | ||
173 | switch (adc) { | 375 | switch (cable_type) { |
174 | case MAX8997_ADC_DESKDOCK: | 376 | case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: |
175 | extcon_set_cable_state(info->edev, "Dock-desk", attached); | 377 | extcon_set_cable_state(info->edev, "Dock-desk", attached); |
176 | break; | 378 | break; |
177 | case MAX8997_ADC_CARDOCK: | 379 | case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: |
178 | extcon_set_cable_state(info->edev, "Dock-card", attached); | 380 | extcon_set_cable_state(info->edev, "Dock-card", attached); |
179 | break; | 381 | break; |
180 | default: | 382 | default: |
181 | ret = -EINVAL; | 383 | dev_err(info->dev, "failed to detect %s dock device\n", |
182 | break; | 384 | attached ? "attached" : "detached"); |
385 | return -EINVAL; | ||
183 | } | 386 | } |
184 | out: | 387 | |
185 | return ret; | 388 | return 0; |
186 | } | 389 | } |
187 | 390 | ||
188 | static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | 391 | static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, |
@@ -191,199 +394,188 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | |||
191 | int ret = 0; | 394 | int ret = 0; |
192 | 395 | ||
193 | /* switch to UART */ | 396 | /* switch to UART */ |
194 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | 397 | ret = max8997_muic_set_path(info, info->path_uart, attached); |
195 | attached ? MAX8997_SW_UART : MAX8997_SW_OPEN, | ||
196 | SW_MASK); | ||
197 | if (ret) { | 398 | if (ret) { |
198 | dev_err(info->dev, "failed to update muic register\n"); | 399 | dev_err(info->dev, "failed to update muic register\n"); |
199 | goto out; | 400 | return -EINVAL; |
200 | } | 401 | } |
201 | 402 | ||
202 | extcon_set_cable_state(info->edev, "JIG", attached); | 403 | extcon_set_cable_state(info->edev, "JIG", attached); |
203 | out: | ||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info) | ||
208 | { | ||
209 | int ret = 0; | ||
210 | 404 | ||
211 | switch (info->pre_adc) { | 405 | return 0; |
212 | case MAX8997_ADC_GROUND: | ||
213 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false); | ||
214 | break; | ||
215 | case MAX8997_ADC_MHL: | ||
216 | extcon_set_cable_state(info->edev, "MHL", false); | ||
217 | break; | ||
218 | case MAX8997_ADC_JIG_USB_1: | ||
219 | case MAX8997_ADC_JIG_USB_2: | ||
220 | ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false); | ||
221 | break; | ||
222 | case MAX8997_ADC_DESKDOCK: | ||
223 | case MAX8997_ADC_CARDOCK: | ||
224 | ret = max8997_muic_handle_dock(info, info->pre_adc, false); | ||
225 | break; | ||
226 | case MAX8997_ADC_JIG_UART: | ||
227 | ret = max8997_muic_handle_jig_uart(info, false); | ||
228 | break; | ||
229 | default: | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | return ret; | ||
234 | } | 406 | } |
235 | 407 | ||
236 | static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) | 408 | static int max8997_muic_adc_handler(struct max8997_muic_info *info) |
237 | { | 409 | { |
410 | int cable_type; | ||
411 | bool attached; | ||
238 | int ret = 0; | 412 | int ret = 0; |
239 | 413 | ||
240 | switch (adc) { | 414 | /* Check cable state which is either detached or attached */ |
241 | case MAX8997_ADC_GROUND: | 415 | cable_type = max8997_muic_get_cable_type(info, |
242 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true); | 416 | MAX8997_CABLE_GROUP_ADC, &attached); |
243 | break; | 417 | |
244 | case MAX8997_ADC_MHL: | 418 | switch (cable_type) { |
245 | extcon_set_cable_state(info->edev, "MHL", true); | 419 | case MAX8997_MUIC_ADC_GROUND: |
246 | break; | 420 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, attached); |
247 | case MAX8997_ADC_JIG_USB_1: | 421 | if (ret < 0) |
248 | case MAX8997_ADC_JIG_USB_2: | 422 | return ret; |
249 | ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true); | 423 | break; |
250 | break; | 424 | case MAX8997_MUIC_ADC_MHL: |
251 | case MAX8997_ADC_DESKDOCK: | 425 | extcon_set_cable_state(info->edev, "MHL", attached); |
252 | case MAX8997_ADC_CARDOCK: | 426 | break; |
253 | ret = max8997_muic_handle_dock(info, adc, true); | 427 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: |
254 | break; | 428 | case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: |
255 | case MAX8997_ADC_JIG_UART: | 429 | ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached); |
256 | ret = max8997_muic_handle_jig_uart(info, true); | 430 | if (ret < 0) |
257 | break; | 431 | return ret; |
258 | case MAX8997_ADC_OPEN: | 432 | break; |
259 | ret = max8997_muic_handle_adc_detach(info); | 433 | case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: |
260 | break; | 434 | case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: |
261 | default: | 435 | ret = max8997_muic_handle_dock(info, cable_type, attached); |
262 | ret = -EINVAL; | 436 | if (ret < 0) |
263 | goto out; | 437 | return ret; |
264 | } | 438 | break; |
265 | 439 | case MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF: | |
266 | info->pre_adc = adc; | 440 | ret = max8997_muic_handle_jig_uart(info, attached); |
267 | out: | 441 | break; |
268 | return ret; | 442 | case MAX8997_MUIC_ADC_REMOTE_S1_BUTTON: |
269 | } | 443 | case MAX8997_MUIC_ADC_REMOTE_S2_BUTTON: |
270 | 444 | case MAX8997_MUIC_ADC_REMOTE_S3_BUTTON: | |
271 | static int max8997_muic_handle_charger_type_detach( | 445 | case MAX8997_MUIC_ADC_REMOTE_S4_BUTTON: |
272 | struct max8997_muic_info *info) | 446 | case MAX8997_MUIC_ADC_REMOTE_S5_BUTTON: |
273 | { | 447 | case MAX8997_MUIC_ADC_REMOTE_S6_BUTTON: |
274 | switch (info->pre_charger_type) { | 448 | case MAX8997_MUIC_ADC_REMOTE_S7_BUTTON: |
275 | case MAX8997_CHARGER_TYPE_USB: | 449 | case MAX8997_MUIC_ADC_REMOTE_S8_BUTTON: |
276 | extcon_set_cable_state(info->edev, "USB", false); | 450 | case MAX8997_MUIC_ADC_REMOTE_S9_BUTTON: |
277 | break; | 451 | case MAX8997_MUIC_ADC_REMOTE_S10_BUTTON: |
278 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | 452 | case MAX8997_MUIC_ADC_REMOTE_S11_BUTTON: |
279 | extcon_set_cable_state(info->edev, "Charge-downstream", false); | 453 | case MAX8997_MUIC_ADC_REMOTE_S12_BUTTON: |
280 | break; | 454 | case MAX8997_MUIC_ADC_RESERVED_ACC_1: |
281 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | 455 | case MAX8997_MUIC_ADC_RESERVED_ACC_2: |
282 | extcon_set_cable_state(info->edev, "TA", false); | 456 | case MAX8997_MUIC_ADC_RESERVED_ACC_3: |
283 | break; | 457 | case MAX8997_MUIC_ADC_RESERVED_ACC_4: |
284 | case MAX8997_CHARGER_TYPE_500MA: | 458 | case MAX8997_MUIC_ADC_RESERVED_ACC_5: |
285 | extcon_set_cable_state(info->edev, "Slow-charger", false); | 459 | case MAX8997_MUIC_ADC_CEA936_AUDIO: |
286 | break; | 460 | case MAX8997_MUIC_ADC_PHONE_POWERED_DEV: |
287 | case MAX8997_CHARGER_TYPE_1A: | 461 | case MAX8997_MUIC_ADC_TTY_CONVERTER: |
288 | extcon_set_cable_state(info->edev, "Fast-charger", false); | 462 | case MAX8997_MUIC_ADC_UART_CABLE: |
289 | break; | 463 | case MAX8997_MUIC_ADC_CEA936A_TYPE1_CHG: |
464 | case MAX8997_MUIC_ADC_CEA936A_TYPE2_CHG: | ||
465 | case MAX8997_MUIC_ADC_AUDIO_MODE_REMOTE: | ||
466 | /* | ||
467 | * This cable isn't used in general case if it is specially | ||
468 | * needed to detect additional cable, should implement | ||
469 | * proper operation when this cable is attached/detached. | ||
470 | */ | ||
471 | dev_info(info->dev, | ||
472 | "cable is %s but it isn't used (type:0x%x)\n", | ||
473 | attached ? "attached" : "detached", cable_type); | ||
474 | return -EAGAIN; | ||
290 | default: | 475 | default: |
476 | dev_err(info->dev, | ||
477 | "failed to detect %s unknown cable (type:0x%x)\n", | ||
478 | attached ? "attached" : "detached", cable_type); | ||
291 | return -EINVAL; | 479 | return -EINVAL; |
292 | break; | ||
293 | } | 480 | } |
294 | 481 | ||
295 | return 0; | 482 | return 0; |
296 | } | 483 | } |
297 | 484 | ||
298 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, | 485 | static int max8997_muic_chg_handler(struct max8997_muic_info *info) |
299 | enum max8997_muic_charger_type charger_type) | ||
300 | { | 486 | { |
301 | u8 adc; | 487 | int chg_type; |
302 | int ret; | 488 | bool attached; |
489 | int adc; | ||
303 | 490 | ||
304 | ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc); | 491 | chg_type = max8997_muic_get_cable_type(info, |
305 | if (ret) { | 492 | MAX8997_CABLE_GROUP_CHG, &attached); |
306 | dev_err(info->dev, "failed to read muic register\n"); | ||
307 | goto out; | ||
308 | } | ||
309 | 493 | ||
310 | switch (charger_type) { | 494 | switch (chg_type) { |
311 | case MAX8997_CHARGER_TYPE_NONE: | 495 | case MAX8997_CHARGER_TYPE_NONE: |
312 | ret = max8997_muic_handle_charger_type_detach(info); | ||
313 | break; | 496 | break; |
314 | case MAX8997_CHARGER_TYPE_USB: | 497 | case MAX8997_CHARGER_TYPE_USB: |
315 | if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) { | 498 | adc = info->status[0] & STATUS1_ADC_MASK; |
499 | adc >>= STATUS1_ADC_SHIFT; | ||
500 | |||
501 | if ((adc & STATUS1_ADC_MASK) == MAX8997_MUIC_ADC_OPEN) { | ||
316 | max8997_muic_handle_usb(info, | 502 | max8997_muic_handle_usb(info, |
317 | MAX8997_USB_DEVICE, true); | 503 | MAX8997_USB_DEVICE, attached); |
318 | } | 504 | } |
319 | break; | 505 | break; |
320 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | 506 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: |
321 | extcon_set_cable_state(info->edev, "Charge-downstream", true); | 507 | extcon_set_cable_state(info->edev, "Charge-downstream", attached); |
322 | break; | 508 | break; |
323 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | 509 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: |
324 | extcon_set_cable_state(info->edev, "TA", true); | 510 | extcon_set_cable_state(info->edev, "TA", attached); |
325 | break; | 511 | break; |
326 | case MAX8997_CHARGER_TYPE_500MA: | 512 | case MAX8997_CHARGER_TYPE_500MA: |
327 | extcon_set_cable_state(info->edev, "Slow-charger", true); | 513 | extcon_set_cable_state(info->edev, "Slow-charger", attached); |
328 | break; | 514 | break; |
329 | case MAX8997_CHARGER_TYPE_1A: | 515 | case MAX8997_CHARGER_TYPE_1A: |
330 | extcon_set_cable_state(info->edev, "Fast-charger", true); | 516 | extcon_set_cable_state(info->edev, "Fast-charger", attached); |
331 | break; | 517 | break; |
332 | default: | 518 | default: |
333 | ret = -EINVAL; | 519 | dev_err(info->dev, |
334 | goto out; | 520 | "failed to detect %s unknown chg cable (type:0x%x)\n", |
521 | attached ? "attached" : "detached", chg_type); | ||
522 | return -EINVAL; | ||
335 | } | 523 | } |
336 | 524 | ||
337 | info->pre_charger_type = charger_type; | 525 | return 0; |
338 | out: | ||
339 | return ret; | ||
340 | } | 526 | } |
341 | 527 | ||
342 | static void max8997_muic_irq_work(struct work_struct *work) | 528 | static void max8997_muic_irq_work(struct work_struct *work) |
343 | { | 529 | { |
344 | struct max8997_muic_info *info = container_of(work, | 530 | struct max8997_muic_info *info = container_of(work, |
345 | struct max8997_muic_info, irq_work); | 531 | struct max8997_muic_info, irq_work); |
346 | u8 status[2]; | ||
347 | u8 adc, chg_type; | ||
348 | int irq_type = 0; | 532 | int irq_type = 0; |
349 | int i, ret; | 533 | int i, ret; |
350 | 534 | ||
535 | if (!info->edev) | ||
536 | return; | ||
537 | |||
351 | mutex_lock(&info->mutex); | 538 | mutex_lock(&info->mutex); |
352 | 539 | ||
540 | for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) | ||
541 | if (info->irq == muic_irqs[i].virq) | ||
542 | irq_type = muic_irqs[i].irq; | ||
543 | |||
353 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, | 544 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, |
354 | 2, status); | 545 | 2, info->status); |
355 | if (ret) { | 546 | if (ret) { |
356 | dev_err(info->dev, "failed to read muic register\n"); | 547 | dev_err(info->dev, "failed to read muic register\n"); |
357 | mutex_unlock(&info->mutex); | 548 | mutex_unlock(&info->mutex); |
358 | return; | 549 | return; |
359 | } | 550 | } |
360 | 551 | ||
361 | dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__, | ||
362 | status[0], status[1]); | ||
363 | |||
364 | for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++) | ||
365 | if (info->irq == muic_irqs[i].virq) | ||
366 | irq_type = muic_irqs[i].irq; | ||
367 | |||
368 | switch (irq_type) { | 552 | switch (irq_type) { |
553 | case MAX8997_MUICIRQ_ADCError: | ||
554 | case MAX8997_MUICIRQ_ADCLow: | ||
369 | case MAX8997_MUICIRQ_ADC: | 555 | case MAX8997_MUICIRQ_ADC: |
370 | adc = status[0] & STATUS1_ADC_MASK; | 556 | /* Handle all of cable except for charger cable */ |
371 | adc >>= STATUS1_ADC_SHIFT; | 557 | ret = max8997_muic_adc_handler(info); |
372 | |||
373 | max8997_muic_handle_adc(info, adc); | ||
374 | break; | 558 | break; |
559 | case MAX8997_MUICIRQ_VBVolt: | ||
560 | case MAX8997_MUICIRQ_DBChg: | ||
561 | case MAX8997_MUICIRQ_DCDTmr: | ||
562 | case MAX8997_MUICIRQ_ChgDetRun: | ||
375 | case MAX8997_MUICIRQ_ChgTyp: | 563 | case MAX8997_MUICIRQ_ChgTyp: |
376 | chg_type = status[1] & STATUS2_CHGTYP_MASK; | 564 | /* Handle charger cable */ |
377 | chg_type >>= STATUS2_CHGTYP_SHIFT; | 565 | ret = max8997_muic_chg_handler(info); |
378 | 566 | break; | |
379 | max8997_muic_handle_charger_type(info, chg_type); | 567 | case MAX8997_MUICIRQ_OVP: |
380 | break; | 568 | break; |
381 | default: | 569 | default: |
382 | dev_info(info->dev, "misc interrupt: irq %d occurred\n", | 570 | dev_info(info->dev, "misc interrupt: irq %d occurred\n", |
383 | irq_type); | 571 | irq_type); |
384 | break; | 572 | mutex_unlock(&info->mutex); |
573 | return; | ||
385 | } | 574 | } |
386 | 575 | ||
576 | if (ret < 0) | ||
577 | dev_err(info->dev, "failed to handle MUIC interrupt\n"); | ||
578 | |||
387 | mutex_unlock(&info->mutex); | 579 | mutex_unlock(&info->mutex); |
388 | 580 | ||
389 | return; | 581 | return; |
@@ -401,29 +593,60 @@ static irqreturn_t max8997_muic_irq_handler(int irq, void *data) | |||
401 | return IRQ_HANDLED; | 593 | return IRQ_HANDLED; |
402 | } | 594 | } |
403 | 595 | ||
404 | static void max8997_muic_detect_dev(struct max8997_muic_info *info) | 596 | static int max8997_muic_detect_dev(struct max8997_muic_info *info) |
405 | { | 597 | { |
406 | int ret; | 598 | int ret = 0; |
407 | u8 status[2], adc, chg_type; | 599 | int adc; |
600 | int chg_type; | ||
601 | bool attached; | ||
408 | 602 | ||
409 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, | 603 | mutex_lock(&info->mutex); |
410 | 2, status); | 604 | |
605 | /* Read STATUSx register to detect accessory */ | ||
606 | ret = max8997_bulk_read(info->muic, | ||
607 | MAX8997_MUIC_REG_STATUS1, 2, info->status); | ||
411 | if (ret) { | 608 | if (ret) { |
412 | dev_err(info->dev, "failed to read muic register\n"); | 609 | dev_err(info->dev, "failed to read MUIC register\n"); |
413 | return; | 610 | mutex_unlock(&info->mutex); |
611 | return -EINVAL; | ||
414 | } | 612 | } |
415 | 613 | ||
416 | dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n", | 614 | adc = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC, |
417 | status[0], status[1]); | 615 | &attached); |
616 | if (attached && adc != MAX8997_MUIC_ADC_OPEN) { | ||
617 | ret = max8997_muic_adc_handler(info); | ||
618 | if (ret < 0) { | ||
619 | dev_err(info->dev, "Cannot detect ADC cable\n"); | ||
620 | mutex_unlock(&info->mutex); | ||
621 | return ret; | ||
622 | } | ||
623 | } | ||
418 | 624 | ||
419 | adc = status[0] & STATUS1_ADC_MASK; | 625 | chg_type = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_CHG, |
420 | adc >>= STATUS1_ADC_SHIFT; | 626 | &attached); |
627 | if (attached && chg_type != MAX8997_CHARGER_TYPE_NONE) { | ||
628 | ret = max8997_muic_chg_handler(info); | ||
629 | if (ret < 0) { | ||
630 | dev_err(info->dev, "Cannot detect charger cable\n"); | ||
631 | mutex_unlock(&info->mutex); | ||
632 | return ret; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | mutex_unlock(&info->mutex); | ||
637 | |||
638 | return 0; | ||
639 | } | ||
421 | 640 | ||
422 | chg_type = status[1] & STATUS2_CHGTYP_MASK; | 641 | static void max8997_muic_detect_cable_wq(struct work_struct *work) |
423 | chg_type >>= STATUS2_CHGTYP_SHIFT; | 642 | { |
643 | struct max8997_muic_info *info = container_of(to_delayed_work(work), | ||
644 | struct max8997_muic_info, wq_detcable); | ||
645 | int ret; | ||
424 | 646 | ||
425 | max8997_muic_handle_adc(info, adc); | 647 | ret = max8997_muic_detect_dev(info); |
426 | max8997_muic_handle_charger_type(info, chg_type); | 648 | if (ret < 0) |
649 | pr_err("failed to detect cable type\n"); | ||
427 | } | 650 | } |
428 | 651 | ||
429 | static int max8997_muic_probe(struct platform_device *pdev) | 652 | static int max8997_muic_probe(struct platform_device *pdev) |
@@ -431,6 +654,7 @@ static int max8997_muic_probe(struct platform_device *pdev) | |||
431 | struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); | 654 | struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); |
432 | struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); | 655 | struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); |
433 | struct max8997_muic_info *info; | 656 | struct max8997_muic_info *info; |
657 | int delay_jiffies; | ||
434 | int ret, i; | 658 | int ret, i; |
435 | 659 | ||
436 | info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), | 660 | info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), |
@@ -459,8 +683,10 @@ static int max8997_muic_probe(struct platform_device *pdev) | |||
459 | } | 683 | } |
460 | muic_irq->virq = virq; | 684 | muic_irq->virq = virq; |
461 | 685 | ||
462 | ret = request_threaded_irq(virq, NULL, max8997_muic_irq_handler, | 686 | ret = request_threaded_irq(virq, NULL, |
463 | 0, muic_irq->name, info); | 687 | max8997_muic_irq_handler, |
688 | IRQF_NO_SUSPEND, | ||
689 | muic_irq->name, info); | ||
464 | if (ret) { | 690 | if (ret) { |
465 | dev_err(&pdev->dev, | 691 | dev_err(&pdev->dev, |
466 | "failed: irq request (IRQ: %d," | 692 | "failed: irq request (IRQ: %d," |
@@ -496,10 +722,42 @@ static int max8997_muic_probe(struct platform_device *pdev) | |||
496 | } | 722 | } |
497 | } | 723 | } |
498 | 724 | ||
499 | /* Initial device detection */ | 725 | /* |
500 | max8997_muic_detect_dev(info); | 726 | * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB |
727 | * h/w path of COMP2/COMN1 on CONTROL1 register. | ||
728 | */ | ||
729 | if (pdata->muic_pdata->path_uart) | ||
730 | info->path_uart = pdata->muic_pdata->path_uart; | ||
731 | else | ||
732 | info->path_uart = CONTROL1_SW_UART; | ||
733 | |||
734 | if (pdata->muic_pdata->path_usb) | ||
735 | info->path_usb = pdata->muic_pdata->path_usb; | ||
736 | else | ||
737 | info->path_usb = CONTROL1_SW_USB; | ||
738 | |||
739 | /* Set initial path for UART */ | ||
740 | max8997_muic_set_path(info, info->path_uart, true); | ||
741 | |||
742 | /* Set ADC debounce time */ | ||
743 | max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS); | ||
744 | |||
745 | /* | ||
746 | * Detect accessory after completing the initialization of platform | ||
747 | * | ||
748 | * - Use delayed workqueue to detect cable state and then | ||
749 | * notify cable state to notifiee/platform through uevent. | ||
750 | * After completing the booting of platform, the extcon provider | ||
751 | * driver should notify cable state to upper layer. | ||
752 | */ | ||
753 | INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); | ||
754 | if (pdata->muic_pdata->detcable_delay_ms) | ||
755 | delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms); | ||
756 | else | ||
757 | delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); | ||
758 | schedule_delayed_work(&info->wq_detcable, delay_jiffies); | ||
501 | 759 | ||
502 | return ret; | 760 | return 0; |
503 | 761 | ||
504 | err_irq: | 762 | err_irq: |
505 | while (--i >= 0) | 763 | while (--i >= 0) |