xref: /openbmc/linux/drivers/mfd/twl4030-power.c (revision 637d6895)
1 /*
2  * linux/drivers/i2c/chips/twl4030-power.c
3  *
4  * Handle TWL4030 Power initialization
5  *
6  * Copyright (C) 2008 Nokia Corporation
7  * Copyright (C) 2006 Texas Instruments, Inc
8  *
9  * Written by 	Kalle Jokiniemi
10  *		Peter De Schrijver <peter.de-schrijver@nokia.com>
11  * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com>
12  *
13  * This file is subject to the terms and conditions of the GNU General
14  * Public License. See the file "COPYING" in the main directory of this
15  * archive for more details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26 
27 #include <linux/module.h>
28 #include <linux/pm.h>
29 #include <linux/i2c/twl.h>
30 #include <linux/platform_device.h>
31 
32 #include <asm/mach-types.h>
33 
34 static u8 twl4030_start_script_address = 0x2b;
35 
36 #define PWR_P1_SW_EVENTS	0x10
37 #define PWR_DEVOFF		(1 << 0)
38 #define SEQ_OFFSYNC		(1 << 0)
39 
40 #define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
41 #define PHY_TO_OFF_PM_RECEIVER(p)	(p - 0x5b)
42 
43 /* resource - hfclk */
44 #define R_HFCLKOUT_DEV_GRP 	PHY_TO_OFF_PM_RECEIVER(0xe6)
45 
46 /* PM events */
47 #define R_P1_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x46)
48 #define R_P2_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x47)
49 #define R_P3_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x48)
50 #define R_CFG_P1_TRANSITION	PHY_TO_OFF_PM_MASTER(0x36)
51 #define R_CFG_P2_TRANSITION	PHY_TO_OFF_PM_MASTER(0x37)
52 #define R_CFG_P3_TRANSITION	PHY_TO_OFF_PM_MASTER(0x38)
53 
54 #define LVL_WAKEUP	0x08
55 
56 #define ENABLE_WARMRESET (1<<4)
57 
58 #define END_OF_SCRIPT		0x3f
59 
60 #define R_SEQ_ADD_A2S		PHY_TO_OFF_PM_MASTER(0x55)
61 #define R_SEQ_ADD_S2A12		PHY_TO_OFF_PM_MASTER(0x56)
62 #define	R_SEQ_ADD_S2A3		PHY_TO_OFF_PM_MASTER(0x57)
63 #define	R_SEQ_ADD_WARM		PHY_TO_OFF_PM_MASTER(0x58)
64 #define R_MEMORY_ADDRESS	PHY_TO_OFF_PM_MASTER(0x59)
65 #define R_MEMORY_DATA		PHY_TO_OFF_PM_MASTER(0x5a)
66 
67 /* resource configuration registers
68    <RESOURCE>_DEV_GRP   at address 'n+0'
69    <RESOURCE>_TYPE      at address 'n+1'
70    <RESOURCE>_REMAP     at address 'n+2'
71    <RESOURCE>_DEDICATED at address 'n+3'
72 */
73 #define DEV_GRP_OFFSET		0
74 #define TYPE_OFFSET		1
75 #define REMAP_OFFSET		2
76 #define DEDICATED_OFFSET	3
77 
78 /* Bit positions in the registers */
79 
80 /* <RESOURCE>_DEV_GRP */
81 #define DEV_GRP_SHIFT		5
82 #define DEV_GRP_MASK		(7 << DEV_GRP_SHIFT)
83 
84 /* <RESOURCE>_TYPE */
85 #define TYPE_SHIFT		0
86 #define TYPE_MASK		(7 << TYPE_SHIFT)
87 #define TYPE2_SHIFT		3
88 #define TYPE2_MASK		(3 << TYPE2_SHIFT)
89 
90 /* <RESOURCE>_REMAP */
91 #define SLEEP_STATE_SHIFT	0
92 #define SLEEP_STATE_MASK	(0xf << SLEEP_STATE_SHIFT)
93 #define OFF_STATE_SHIFT		4
94 #define OFF_STATE_MASK		(0xf << OFF_STATE_SHIFT)
95 
96 static u8 res_config_addrs[] = {
97 	[RES_VAUX1]	= 0x17,
98 	[RES_VAUX2]	= 0x1b,
99 	[RES_VAUX3]	= 0x1f,
100 	[RES_VAUX4]	= 0x23,
101 	[RES_VMMC1]	= 0x27,
102 	[RES_VMMC2]	= 0x2b,
103 	[RES_VPLL1]	= 0x2f,
104 	[RES_VPLL2]	= 0x33,
105 	[RES_VSIM]	= 0x37,
106 	[RES_VDAC]	= 0x3b,
107 	[RES_VINTANA1]	= 0x3f,
108 	[RES_VINTANA2]	= 0x43,
109 	[RES_VINTDIG]	= 0x47,
110 	[RES_VIO]	= 0x4b,
111 	[RES_VDD1]	= 0x55,
112 	[RES_VDD2]	= 0x63,
113 	[RES_VUSB_1V5]	= 0x71,
114 	[RES_VUSB_1V8]	= 0x74,
115 	[RES_VUSB_3V1]	= 0x77,
116 	[RES_VUSBCP]	= 0x7a,
117 	[RES_REGEN]	= 0x7f,
118 	[RES_NRES_PWRON] = 0x82,
119 	[RES_CLKEN]	= 0x85,
120 	[RES_SYSEN]	= 0x88,
121 	[RES_HFCLKOUT]	= 0x8b,
122 	[RES_32KCLKOUT]	= 0x8e,
123 	[RES_RESET]	= 0x91,
124 	[RES_MAIN_REF]	= 0x94,
125 };
126 
127 static int twl4030_write_script_byte(u8 address, u8 byte)
128 {
129 	int err;
130 
131 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
132 	if (err)
133 		goto out;
134 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
135 out:
136 	return err;
137 }
138 
139 static int twl4030_write_script_ins(u8 address, u16 pmb_message,
140 					   u8 delay, u8 next)
141 {
142 	int err;
143 
144 	address *= 4;
145 	err = twl4030_write_script_byte(address++, pmb_message >> 8);
146 	if (err)
147 		goto out;
148 	err = twl4030_write_script_byte(address++, pmb_message & 0xff);
149 	if (err)
150 		goto out;
151 	err = twl4030_write_script_byte(address++, delay);
152 	if (err)
153 		goto out;
154 	err = twl4030_write_script_byte(address++, next);
155 out:
156 	return err;
157 }
158 
159 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
160 				       int len)
161 {
162 	int err = -EINVAL;
163 
164 	for (; len; len--, address++, script++) {
165 		if (len == 1) {
166 			err = twl4030_write_script_ins(address,
167 						script->pmb_message,
168 						script->delay,
169 						END_OF_SCRIPT);
170 			if (err)
171 				break;
172 		} else {
173 			err = twl4030_write_script_ins(address,
174 						script->pmb_message,
175 						script->delay,
176 						address + 1);
177 			if (err)
178 				break;
179 		}
180 	}
181 	return err;
182 }
183 
184 static int twl4030_config_wakeup3_sequence(u8 address)
185 {
186 	int err;
187 	u8 data;
188 
189 	/* Set SLEEP to ACTIVE SEQ address for P3 */
190 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
191 	if (err)
192 		goto out;
193 
194 	/* P3 LVL_WAKEUP should be on LEVEL */
195 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
196 	if (err)
197 		goto out;
198 	data |= LVL_WAKEUP;
199 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
200 out:
201 	if (err)
202 		pr_err("TWL4030 wakeup sequence for P3 config error\n");
203 	return err;
204 }
205 
206 static int twl4030_config_wakeup12_sequence(u8 address)
207 {
208 	int err = 0;
209 	u8 data;
210 
211 	/* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
212 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
213 	if (err)
214 		goto out;
215 
216 	/* P1/P2 LVL_WAKEUP should be on LEVEL */
217 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
218 	if (err)
219 		goto out;
220 
221 	data |= LVL_WAKEUP;
222 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
223 	if (err)
224 		goto out;
225 
226 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
227 	if (err)
228 		goto out;
229 
230 	data |= LVL_WAKEUP;
231 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
232 	if (err)
233 		goto out;
234 
235 	if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
236 		/* Disabling AC charger effect on sleep-active transitions */
237 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
238 				      R_CFG_P1_TRANSITION);
239 		if (err)
240 			goto out;
241 		data &= ~(1<<1);
242 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
243 				       R_CFG_P1_TRANSITION);
244 		if (err)
245 			goto out;
246 	}
247 
248 out:
249 	if (err)
250 		pr_err("TWL4030 wakeup sequence for P1 and P2" \
251 			"config error\n");
252 	return err;
253 }
254 
255 static int twl4030_config_sleep_sequence(u8 address)
256 {
257 	int err;
258 
259 	/* Set ACTIVE to SLEEP SEQ address in T2 memory*/
260 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
261 
262 	if (err)
263 		pr_err("TWL4030 sleep sequence config error\n");
264 
265 	return err;
266 }
267 
268 static int twl4030_config_warmreset_sequence(u8 address)
269 {
270 	int err;
271 	u8 rd_data;
272 
273 	/* Set WARM RESET SEQ address for P1 */
274 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
275 	if (err)
276 		goto out;
277 
278 	/* P1/P2/P3 enable WARMRESET */
279 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
280 	if (err)
281 		goto out;
282 
283 	rd_data |= ENABLE_WARMRESET;
284 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
285 	if (err)
286 		goto out;
287 
288 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
289 	if (err)
290 		goto out;
291 
292 	rd_data |= ENABLE_WARMRESET;
293 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
294 	if (err)
295 		goto out;
296 
297 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
298 	if (err)
299 		goto out;
300 
301 	rd_data |= ENABLE_WARMRESET;
302 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
303 out:
304 	if (err)
305 		pr_err("TWL4030 warmreset seq config error\n");
306 	return err;
307 }
308 
309 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
310 {
311 	int rconfig_addr;
312 	int err;
313 	u8 type;
314 	u8 grp;
315 	u8 remap;
316 
317 	if (rconfig->resource > TOTAL_RESOURCES) {
318 		pr_err("TWL4030 Resource %d does not exist\n",
319 			rconfig->resource);
320 		return -EINVAL;
321 	}
322 
323 	rconfig_addr = res_config_addrs[rconfig->resource];
324 
325 	/* Set resource group */
326 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
327 			      rconfig_addr + DEV_GRP_OFFSET);
328 	if (err) {
329 		pr_err("TWL4030 Resource %d group could not be read\n",
330 			rconfig->resource);
331 		return err;
332 	}
333 
334 	if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
335 		grp &= ~DEV_GRP_MASK;
336 		grp |= rconfig->devgroup << DEV_GRP_SHIFT;
337 		err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
338 				       grp, rconfig_addr + DEV_GRP_OFFSET);
339 		if (err < 0) {
340 			pr_err("TWL4030 failed to program devgroup\n");
341 			return err;
342 		}
343 	}
344 
345 	/* Set resource types */
346 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
347 				rconfig_addr + TYPE_OFFSET);
348 	if (err < 0) {
349 		pr_err("TWL4030 Resource %d type could not be read\n",
350 			rconfig->resource);
351 		return err;
352 	}
353 
354 	if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
355 		type &= ~TYPE_MASK;
356 		type |= rconfig->type << TYPE_SHIFT;
357 	}
358 
359 	if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
360 		type &= ~TYPE2_MASK;
361 		type |= rconfig->type2 << TYPE2_SHIFT;
362 	}
363 
364 	err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
365 				type, rconfig_addr + TYPE_OFFSET);
366 	if (err < 0) {
367 		pr_err("TWL4030 failed to program resource type\n");
368 		return err;
369 	}
370 
371 	/* Set remap states */
372 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
373 			      rconfig_addr + REMAP_OFFSET);
374 	if (err < 0) {
375 		pr_err("TWL4030 Resource %d remap could not be read\n",
376 			rconfig->resource);
377 		return err;
378 	}
379 
380 	if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
381 		remap &= ~OFF_STATE_MASK;
382 		remap |= rconfig->remap_off << OFF_STATE_SHIFT;
383 	}
384 
385 	if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
386 		remap &= ~SLEEP_STATE_MASK;
387 		remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
388 	}
389 
390 	err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
391 			       remap,
392 			       rconfig_addr + REMAP_OFFSET);
393 	if (err < 0) {
394 		pr_err("TWL4030 failed to program remap\n");
395 		return err;
396 	}
397 
398 	return 0;
399 }
400 
401 static int load_twl4030_script(struct twl4030_script *tscript,
402 	       u8 address)
403 {
404 	int err;
405 	static int order;
406 
407 	/* Make sure the script isn't going beyond last valid address (0x3f) */
408 	if ((address + tscript->size) > END_OF_SCRIPT) {
409 		pr_err("TWL4030 scripts too big error\n");
410 		return -EINVAL;
411 	}
412 
413 	err = twl4030_write_script(address, tscript->script, tscript->size);
414 	if (err)
415 		goto out;
416 
417 	if (tscript->flags & TWL4030_WRST_SCRIPT) {
418 		err = twl4030_config_warmreset_sequence(address);
419 		if (err)
420 			goto out;
421 	}
422 	if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
423 		err = twl4030_config_wakeup12_sequence(address);
424 		if (err)
425 			goto out;
426 		order = 1;
427 	}
428 	if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
429 		err = twl4030_config_wakeup3_sequence(address);
430 		if (err)
431 			goto out;
432 	}
433 	if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
434 		if (!order)
435 			pr_warning("TWL4030: Bad order of scripts (sleep "\
436 					"script before wakeup) Leads to boot"\
437 					"failure on some boards\n");
438 		err = twl4030_config_sleep_sequence(address);
439 	}
440 out:
441 	return err;
442 }
443 
444 int twl4030_remove_script(u8 flags)
445 {
446 	int err = 0;
447 
448 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
449 			       TWL4030_PM_MASTER_PROTECT_KEY);
450 	if (err) {
451 		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
452 		return err;
453 	}
454 
455 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
456 			       TWL4030_PM_MASTER_PROTECT_KEY);
457 	if (err) {
458 		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
459 		return err;
460 	}
461 
462 	if (flags & TWL4030_WRST_SCRIPT) {
463 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
464 				       R_SEQ_ADD_WARM);
465 		if (err)
466 			return err;
467 	}
468 	if (flags & TWL4030_WAKEUP12_SCRIPT) {
469 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
470 				       R_SEQ_ADD_S2A12);
471 		if (err)
472 			return err;
473 	}
474 	if (flags & TWL4030_WAKEUP3_SCRIPT) {
475 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
476 				       R_SEQ_ADD_S2A3);
477 		if (err)
478 			return err;
479 	}
480 	if (flags & TWL4030_SLEEP_SCRIPT) {
481 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
482 				       R_SEQ_ADD_A2S);
483 		if (err)
484 			return err;
485 	}
486 
487 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
488 			       TWL4030_PM_MASTER_PROTECT_KEY);
489 	if (err)
490 		pr_err("TWL4030 Unable to relock registers\n");
491 
492 	return err;
493 }
494 
495 /*
496  * In master mode, start the power off sequence.
497  * After a successful execution, TWL shuts down the power to the SoC
498  * and all peripherals connected to it.
499  */
500 void twl4030_power_off(void)
501 {
502 	int err;
503 
504 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
505 			       TWL4030_PM_MASTER_P1_SW_EVENTS);
506 	if (err)
507 		pr_err("TWL4030 Unable to power off\n");
508 }
509 
510 int twl4030_power_probe(struct platform_device *pdev)
511 {
512 	struct twl4030_power_data *pdata = pdev->dev.platform_data;
513 	int err = 0;
514 	int i;
515 	struct twl4030_resconfig *resconfig;
516 	u8 val, address = twl4030_start_script_address;
517 
518 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
519 			       TWL4030_PM_MASTER_PROTECT_KEY);
520 	if (err)
521 		goto unlock;
522 
523 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
524 			       TWL4030_PM_MASTER_PROTECT_KEY);
525 	if (err)
526 		goto unlock;
527 
528 	for (i = 0; i < pdata->num; i++) {
529 		err = load_twl4030_script(pdata->scripts[i], address);
530 		if (err)
531 			goto load;
532 		address += pdata->scripts[i]->size;
533 	}
534 
535 	resconfig = pdata->resource_config;
536 	if (resconfig) {
537 		while (resconfig->resource) {
538 			err = twl4030_configure_resource(resconfig);
539 			if (err)
540 				goto resource;
541 			resconfig++;
542 
543 		}
544 	}
545 
546 	/* Board has to be wired properly to use this feature */
547 	if (pdata->use_poweroff && !pm_power_off) {
548 		/* Default for SEQ_OFFSYNC is set, lets ensure this */
549 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
550 				      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
551 		if (err) {
552 			pr_warning("TWL4030 Unable to read registers\n");
553 
554 		} else if (!(val & SEQ_OFFSYNC)) {
555 			val |= SEQ_OFFSYNC;
556 			err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
557 					TWL4030_PM_MASTER_CFG_P123_TRANSITION);
558 			if (err) {
559 				pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
560 				goto relock;
561 			}
562 		}
563 
564 		pm_power_off = twl4030_power_off;
565 	}
566 
567 relock:
568 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
569 			       TWL4030_PM_MASTER_PROTECT_KEY);
570 	if (err)
571 		pr_err("TWL4030 Unable to relock registers\n");
572 	return err;
573 
574 unlock:
575 	if (err)
576 		pr_err("TWL4030 Unable to unlock registers\n");
577 	return err;
578 load:
579 	if (err)
580 		pr_err("TWL4030 failed to load scripts\n");
581 	return err;
582 resource:
583 	if (err)
584 		pr_err("TWL4030 failed to configure resource\n");
585 	return err;
586 }
587 
588 static int twl4030_power_remove(struct platform_device *pdev)
589 {
590 	return 0;
591 }
592 
593 static struct platform_driver twl4030_power_driver = {
594 	.driver = {
595 		.name	= "twl4030_power",
596 		.owner	= THIS_MODULE,
597 	},
598 	.probe		= twl4030_power_probe,
599 	.remove		= twl4030_power_remove,
600 };
601 
602 module_platform_driver(twl4030_power_driver);
603 
604 MODULE_AUTHOR("Nokia Corporation");
605 MODULE_AUTHOR("Texas Instruments, Inc.");
606 MODULE_DESCRIPTION("Power management for TWL4030");
607 MODULE_LICENSE("GPL");
608 MODULE_ALIAS("platform:twl4030_power");
609