2 * OMAP and TPS6236x specific initialization
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
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.
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/gpio.h>
16 #include <linux/i2c/twl.h>
22 /* Voltage limits supported */
23 #define MIN_VOLTAGE_TPS62360_62_UV 770000
24 #define MAX_VOLTAGE_TPS62360_62_UV 1400000
26 #define MIN_VOLTAGE_TPS62361_UV 500000
27 #define MAX_VOLTAGE_TPS62361_UV 1770000
29 #define MAX_VOLTAGE_RAMP_TPS6236X_UV 32000
32 * This is the voltage delta between 2 values in voltage register.
33 * when switching voltage V1 to V2, TPS62361 can ramp up or down
34 * initially with step sizes of 20mV with a last step of 10mV.
35 * In the case of TPS6236[0|2], it is a constant 10mV steps
36 * we choose the 10mV step for linearity when SR is configured.
38 #define STEP_SIZE_TPS6236X 10000
40 /* I2C access parameters */
41 #define I2C_TPS6236X_SLAVE_ADDR 0x60
43 #define DEF_SET_REG(VSEL0, VSEL1) (((VSEL1) << 1| (VSEL0) << 0) & 0x3)
44 #define REG_TPS6236X_SET_0 0x00
45 #define REG_TPS6236X_SET_1 0x01
46 #define REG_TPS6236X_SET_2 0x02
47 #define REG_TPS6236X_SET_3 0x03
48 #define REG_TPS6236X_CTRL 0x04
49 #define REG_TPS6236X_TEMP 0x05
50 #define REG_TPS6236X_RAMP_CTRL 0x06
51 #define REG_TPS6236X_CHIP_ID0 0x08
52 #define REG_TPS6236X_CHIP_ID1 0x09
54 #define MODE_TPS6236X_AUTO_PFM_PWM 0x00
55 #define MODE_TPS6236X_FORCE_PWM BIT(7)
57 /* We use Auto PFM/PWM mode currently seems to have the best trade off */
58 #define VOLTAGE_PFM_MODE_VAL MODE_TPS6236X_AUTO_PFM_PWM
60 #define REG_TPS6236X_RAMP_CTRL_RMP_MASK (0x7 << 5)
61 #define REG_TPS6236X_RAMP_CTRL_EN_DISC BIT(2)
62 #define REG_TPS6236X_RAMP_CTRL_RAMP_PFM BIT(1)
64 #define REG_TPS6236X_CTRL_PD_EN BIT(7)
65 #define REG_TPS6236X_CTRL_PD_VSEL0 BIT(6)
66 #define REG_TPS6236X_CTRL_PD_VSEL1 BIT(5)
69 #define TWL6030_REG_SYSEN_CFG_GRP 0xB3
70 #define TWL6030_REG_SYSEN_CFG_TRANS 0xB4
71 #define TWL6030_REG_VCORE3_CFG_GRP 0x5E
72 #define TWL6030_REG_VMEM_CFG_GRP 0x64
73 #define TWL6030_REG_MSK_TRANSITION 0x20
74 #define TWL6030_BIT_APE_GRP BIT(0)
75 #define TWL6030_BIT_CON_GRP BIT(1)
76 #define TWL6030_BIT_MOD_GRP BIT(2)
77 #define TWL6030_MSK_PREQ1 BIT(5)
78 #define TWL6030_MSK_SYSEN_OFF (0x3 << 4)
79 #define TWL6030_MSK_SYSEN_SLEEP (0x3 << 2)
80 #define TWL6030_MSK_SYSEN_ACTIVE (0x3 << 0)
82 /* Voltage params of the attached device (all in uV) */
83 static unsigned long voltage_min
;
84 static unsigned long voltage_max
;
86 /* Which register do we use by default? */
87 static int __initdata default_reg
= -1;;
89 /* Do we need to setup internal pullups? */
90 static int __initdata pd_vsel0
= -1;
91 static int __initdata pd_vsel1
= -1;
93 static int __init
_bd_setup(char *name
,int gpio_vsel
, int *pull
, int *pd_vsel
)
98 if (gpio_vsel
== -1) {
100 *pd_vsel
= (*pull
== OMAP_PIN_OFF_OUTPUT_HIGH
);
108 /* if we have a pull gpio, with bad dir, pull low */
109 if (*pull
== -1 || (*pull
!= OMAP_PIN_OFF_OUTPUT_HIGH
&&
110 *pull
!= OMAP_PIN_OFF_OUTPUT_LOW
))
111 *pull
= OMAP_PIN_OFF_OUTPUT_LOW
;
113 r
= omap_mux_init_gpio(gpio_vsel
, *pull
);
115 pr_err("%s: unable to mux gpio%d=%d\n", __func__
,
120 pull_dir
= (*pull
== OMAP_PIN_OFF_OUTPUT_HIGH
);
123 r
= gpio_request(gpio_vsel
, name
);
125 pr_err("%s: unable to req gpio%d=%d\n", __func__
,
129 r
= gpio_direction_output(gpio_vsel
, pull_dir
);
131 pr_err("%s: unable to pull[%d] gpio%d=%d\n", __func__
,
132 gpio_vsel
, pull_dir
, r
);
133 gpio_free(gpio_vsel
);
140 /* Convert the ramp voltage to ramp value. */
141 static u8 __init
tps6236x_ramp_value(unsigned long uv
)
146 if (uv
> MAX_VOLTAGE_RAMP_TPS6236X_UV
) {
147 pr_err("%s: uv%ld greater than max %d\n", __func__
,
148 uv
, MAX_VOLTAGE_RAMP_TPS6236X_UV
);
149 uv
= MAX_VOLTAGE_RAMP_TPS6236X_UV
;
151 return fls(MAX_VOLTAGE_RAMP_TPS6236X_UV
/ uv
) - 1;
154 static unsigned long tps6236x_vsel_to_uv(const u8 vsel
)
156 return (voltage_min
+
157 (STEP_SIZE_TPS6236X
* (vsel
& ~VOLTAGE_PFM_MODE_VAL
)));
160 static u8
tps6236x_uv_to_vsel(unsigned long uv
)
165 /* Round off requests to limits */
166 if (uv
> voltage_max
) {
167 pr_err("%s:Request for overvoltage[%ld] than supported[%ld]\n",
168 __func__
, uv
, voltage_max
);
171 if (uv
< voltage_min
) {
172 pr_err("%s:Request for undervoltage[%ld] than supported[%ld]\n",
173 __func__
, uv
, voltage_min
);
176 return DIV_ROUND_UP(uv
- voltage_min
, STEP_SIZE_TPS6236X
) |
177 VOLTAGE_PFM_MODE_VAL
;
180 static struct omap_voltdm_pmic omap4_mpu_pmic
= {
182 .step_size
= STEP_SIZE_TPS6236X
,
184 .onlp_volt
= 1375000,
187 .volt_setup_time
= 0,
188 .switch_on_time
= 1000,
189 .vp_erroroffset
= OMAP4_VP_CONFIG_ERROROFFSET
,
190 .vp_vstepmin
= OMAP4_VP_VSTEPMIN_VSTEPMIN
,
191 .vp_vstepmax
= OMAP4_VP_VSTEPMAX_VSTEPMAX
,
192 .vp_vddmin
= OMAP4_VP_MPU_VLIMITTO_VDDMIN
,
193 .vp_vddmax
= OMAP4_VP_MPU_VLIMITTO_VDDMAX
,
194 .vp_timeout_us
= OMAP4_VP_VLIMITTO_TIMEOUT_US
,
195 .i2c_slave_addr
= I2C_TPS6236X_SLAVE_ADDR
,
196 .volt_reg_addr
= REG_TPS6236X_SET_0
,
197 .cmd_reg_addr
= REG_TPS6236X_SET_0
,
198 .i2c_high_speed
= true,
199 .i2c_scll_low
= 0x28,
200 .i2c_scll_high
= 0x2C,
201 .i2c_hscll_low
= 0x0B,
202 .i2c_hscll_high
= 0x00,
203 .vsel_to_uv
= tps6236x_vsel_to_uv
,
204 .uv_to_vsel
= tps6236x_uv_to_vsel
,
208 static __initdata
struct omap_pmic_description tps_pmic_desc
= {
209 .pmic_lp_tshut
= 1, /* T-OFF 1ns rounded */
210 .pmic_lp_tstart
= 500, /* T-start */
213 * _twl_i2c_rmw_u8() - Tiny helper function to do a read modify write for twl
214 * @mod_no: module number
215 * @mask: mask for the val
216 * @value: value to write
217 * @reg: register to write to
219 static int __init
_twl_i2c_rmw_u8(u8 mod_no
, u8 mask
, u8 value
, u8 reg
)
224 ret
= twl_i2c_read_u8(mod_no
, &val
, reg
);
229 val
|= (value
& mask
);
231 ret
= twl_i2c_write_u8(mod_no
, val
, reg
);
237 * omap4_twl_tps62361_enable() - Enable tps chip
239 * This function enables TPS chip by associating SYSEN signal
240 * to APE resource group of TWL6030.
242 * Returns 0 on sucess, error is returned if I2C read/write fails.
244 static int __init
omap4_twl_tps62361_enable(struct voltagedomain
*voltdm
)
250 /* Dont trust the bootloader. start with max, pm will set to proper */
251 val
= voltdm
->pmic
->uv_to_vsel(voltdm
->pmic
->vp_vddmax
);
252 ret
= omap_vc_bypass_send_i2c_msg(voltdm
, voltdm
->pmic
->i2c_slave_addr
,
256 val
= tps6236x_ramp_value(voltdm
->pmic
->slew_rate
) <<
257 __ffs(REG_TPS6236X_RAMP_CTRL_RMP_MASK
);
258 val
&= REG_TPS6236X_RAMP_CTRL_RMP_MASK
;
260 /* We would like to ramp the voltage asap */
261 val
|= REG_TPS6236X_RAMP_CTRL_RAMP_PFM
;
263 /* We would like to ramp down the voltage asap as well*/
264 val
|= REG_TPS6236X_RAMP_CTRL_EN_DISC
;
266 ret
= omap_vc_bypass_send_i2c_msg(voltdm
, voltdm
->pmic
->i2c_slave_addr
,
267 REG_TPS6236X_RAMP_CTRL
, val
);
271 /* Setup the internal pulls to select if needed */
272 if (pd_vsel0
!= -1 || pd_vsel1
!= -1) {
273 val
= REG_TPS6236X_CTRL_PD_EN
;
274 val
|= (pd_vsel0
) ? 0 : REG_TPS6236X_CTRL_PD_VSEL0
;
275 val
|= (pd_vsel1
) ? 0 : REG_TPS6236X_CTRL_PD_VSEL1
;
276 ret
= omap_vc_bypass_send_i2c_msg(voltdm
,
277 voltdm
->pmic
->i2c_slave_addr
,
278 REG_TPS6236X_CTRL
, val
);
283 /* Enable thermal shutdown - 0 is enable :) */
284 ret
= omap_vc_bypass_send_i2c_msg(voltdm
,
285 voltdm
->pmic
->i2c_slave_addr
,
286 REG_TPS6236X_TEMP
, 0x0);
290 /* if we have to work with TWL */
291 #ifdef CONFIG_TWL4030_CORE
293 /* unmask PREQ transition Executes ACT2SLP and SLP2ACT sleep sequence */
294 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_MSK_PREQ1
,
295 0x00, TWL6030_REG_MSK_TRANSITION
);
297 pr_err("%s:Err:TWL6030: map APE PREQ1(%d)\n", __func__
, ret1
);
301 /* Setup SYSEN to be 1 on Active and 0 for sleep and OFF states */
302 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_MSK_SYSEN_ACTIVE
,
303 0x01, TWL6030_REG_SYSEN_CFG_TRANS
);
305 pr_err("%s:Err:TWL6030: sysen active(%d)\n", __func__
, ret1
);
308 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_MSK_SYSEN_SLEEP
,
309 0x00, TWL6030_REG_SYSEN_CFG_TRANS
);
311 pr_err("%s:Err:TWL6030: sysen sleep(%d)\n", __func__
, ret1
);
314 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_MSK_SYSEN_OFF
,
315 0x00, TWL6030_REG_SYSEN_CFG_TRANS
);
317 pr_err("%s:Err:TWL6030: sysen off(%d)\n", __func__
, ret1
);
321 /* Map up SYSEN on TWL core to control TPS */
322 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_BIT_APE_GRP
|
323 TWL6030_BIT_MOD_GRP
| TWL6030_BIT_CON_GRP
,
324 TWL6030_BIT_APE_GRP
, TWL6030_REG_SYSEN_CFG_GRP
);
326 pr_err("%s:Err:TWL6030: map APE SYEN(%d)\n", __func__
, ret1
);
330 /* Since we dont use VCORE3, this should not be associated with APE */
331 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_BIT_APE_GRP
,
332 0x00, TWL6030_REG_VCORE3_CFG_GRP
);
334 pr_err("%s:Err:TWL6030:unmap APE VCORE3(%d)\n", __func__
, ret1
);
338 /* Since we dont use VMEM, this should not be associated with APE */
339 ret1
= _twl_i2c_rmw_u8(TWL6030_MODULE_ID0
, TWL6030_BIT_APE_GRP
,
340 0x00, TWL6030_REG_VMEM_CFG_GRP
);
342 pr_err("%s:Err:TWL6030: unmap APE VMEM(%d)\n", __func__
, ret1
);
349 pr_err("%s: Error enabling TPS(%d)\n", __func__
, ret
);
354 static __initdata
struct omap_pmic_map omap_tps_map
[] = {
357 .omap_chip
= OMAP_CHIP_INIT(CHIP_IS_OMAP446X
),
358 .pmic_data
= &omap4_mpu_pmic
,
359 .special_action
= omap4_twl_tps62361_enable
,
362 { .name
= NULL
,.pmic_data
= NULL
},
365 int __init
omap_tps6236x_init(void)
367 struct omap_pmic_map
*map
;
369 /* Without registers, I wont proceed */
370 if (default_reg
== -1)
375 /* setup all the pmic's voltage addresses to the default one */
377 map
->pmic_data
->volt_reg_addr
= default_reg
;
378 map
->pmic_data
->cmd_reg_addr
= default_reg
;
382 return omap_pmic_register_data(omap_tps_map
, &tps_pmic_desc
);
386 * omap_tps6236x_board_setup() - provide the board config for TPS connect
387 * @use_62361: Do we use TPS62361 variant?
388 * @gpio_vsel0: If using GPIO to control VSEL0, provide gpio number, else -1
389 * @gpio_vsel1: If using GPIO to control VSEL1, provide gpio number, else -1
390 * @pull0: If using GPIO, provide mux mode OMAP_PIN_OFF_OUTPUT_[HIGH|LOW]
391 * else provide any internal pull required, -1 if unused.
392 * @pull1: If using GPIO, provide mux mode OMAP_PIN_OFF_OUTPUT_[HIGH|LOW]
393 * else provide any internal pull required, -1 if unused.
395 * TPS6236x variants of PMIC can be hooked in numerous combinations on to the
396 * board. Some platforms can choose to hardwire and save on a GPIO for other
397 * uses, while others may hook a single line for GPIO control and may ground
398 * the other line. support these configurations.
400 * WARNING: for platforms using GPIO, be careful to provide MUX setting
401 * considering OFF mode configuration as well.
403 int __init
omap_tps6236x_board_setup(bool use_62361
, int gpio_vsel0
,
404 int gpio_vsel1
, int pull0
, int pull1
)
408 r
= _bd_setup("tps6236x_vsel0", gpio_vsel0
, &pull0
, &pd_vsel0
);
411 r
= _bd_setup("tps6236x_vsel1", gpio_vsel1
, &pull1
, &pd_vsel1
);
413 if (gpio_vsel0
!= -1)
414 gpio_free(gpio_vsel0
);
418 default_reg
= ((pull1
& 0x1) << 1) | (pull0
& 0x1);
421 voltage_min
= MIN_VOLTAGE_TPS62361_UV
;
422 voltage_max
= MAX_VOLTAGE_TPS62361_UV
;
424 voltage_min
= MIN_VOLTAGE_TPS62360_62_UV
;
425 voltage_max
= MAX_VOLTAGE_TPS62360_62_UV
;
431 int __init
omap_tps6236x_update(char *name
, u32 old_chip_id
, u32 new_chip_id
)
433 return omap_pmic_update(omap_tps_map
, name
, old_chip_id
, new_chip_id
);