3 #ifdef CONFIG_DRIVER_PCF50633
7 #include <asm/atomic.h>
8 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
11 #define ADC_NOMINAL_RES_1A 6
12 #define ADC_NOMINAL_RES_NC_R_USB 43
14 #define PCF50633_I2C_ADDR 0x73
16 void __pcf50633_reg_write(u_int8_t reg
, u_int8_t val
)
18 i2c_write(PCF50633_I2C_ADDR
, reg
, 1, &val
, 1);
21 u_int8_t
__pcf50633_reg_read(u_int8_t reg
)
24 i2c_read(PCF50633_I2C_ADDR
, reg
, 1, &tmp
, 1);
28 void pcf50633_reg_write(u_int8_t reg
, u_int8_t val
)
32 local_irq_save(flags
);
33 __pcf50633_reg_write(reg
, val
);
34 local_irq_restore(flags
);
37 u_int8_t
pcf50633_reg_read(u_int8_t reg
)
42 local_irq_save(flags
);
43 tmp
= __pcf50633_reg_read(reg
);
44 local_irq_restore(flags
);
49 void pcf50633_reg_set_bit_mask(u_int8_t reg
, u_int8_t mask
, u_int8_t val
)
54 local_irq_save(flags
);
55 tmp
= __pcf50633_reg_read(reg
);
56 __pcf50633_reg_write(reg
, (val
& mask
) | (tmp
& ~mask
));
57 local_irq_restore(flags
);
60 void pcf50633_reg_clear_bits(u_int8_t reg
, u_int8_t bits
)
65 local_irq_save(flags
);
66 tmp
= pcf50633_reg_read(reg
);
67 pcf50633_reg_write(reg
, (tmp
& ~bits
));
68 local_irq_restore(flags
);
71 static const u_int8_t regs_invalid
[] = {
74 PCF50633_REG_OOCSHDWN
,
82 PCF50633_REG_DCDCSTAT
,
89 /* 0x55 ... 0x6e: don't write */
90 /* 0x6f ... 0x83: reserved */
92 #define PCF50633_LAST_REG 0x55
94 static int reg_is_invalid(u_int8_t reg
)
98 /* all registers above 0x55 (ADCS1) except 0x84 */
99 if (reg
== PCF50633_REG_DCDCPFM
)
104 for (i
= 0; i
< ARRAY_SIZE(regs_invalid
); i
++) {
105 if (regs_invalid
[i
] > reg
)
107 if (regs_invalid
[i
] == reg
)
114 /* figure out our charger situation */
115 int pcf50633_read_charger_type(void)
119 /* kill ratiometric, but enable ACCSW biasing */
120 pcf50633_reg_write(PCF50633_REG_ADCC2
, 0x00);
121 pcf50633_reg_write(PCF50633_REG_ADCC3
, 0x01);
123 /* start ADC conversion of selected channel */
124 pcf50633_reg_write(PCF50633_REG_ADCC1
, PCF50633_ADCC1_MUX_ADCIN1
|
125 PCF50633_ADCC1_AVERAGE_16
|
126 PCF50633_ADCC1_ADCSTART
|
127 PCF50633_ADCC1_RES_10BIT
);
129 /* spin until completed */
130 while (!(pcf50633_reg_read(PCF50633_REG_ADCS3
) & 0x80))
133 /* grab the result */
134 ret
= (pcf50633_reg_read(PCF50633_REG_ADCS1
) << 2) |
135 (pcf50633_reg_read(PCF50633_REG_ADCS3
) &
136 PCF50633_ADCS3_ADCDAT1L_MASK
);
138 /* well it is nearest to the 1A resistor */
139 if (ret
< ((ADC_NOMINAL_RES_1A
+ ADC_NOMINAL_RES_NC_R_USB
) / 2))
142 /* ok all we know is there is no resistor, it can be USB pwr or none */
143 if ((pcf50633_reg_read(PCF50633_REG_MBCS1
) & 0x3) == 0x3)
144 return 100; /* USB power then */
146 return 0; /* nope, no power, just battery */
151 /* initialize PCF50633 register set */
152 void pcf50633_init(void)
158 local_irq_save(flags
);
159 for (i
= 0; i
< PCF50633_LAST_REG
; i
++) {
160 if (reg_is_invalid(i
))
162 __pcf50633_reg_write(i
, pcf50633_initial_regs
[i
]);
164 local_irq_restore(flags
);
167 limit
= pcf50633_read_charger_type();
169 * If we're on real USB, don't change the setting to avoid racing with
173 printf("%dmA\n", limit
);
174 pcf50633_usb_maxcurrent(limit
);
178 void pcf50633_usb_maxcurrent(unsigned int ma
)
183 val
= PCF50633_MBCC7_USB_SUSPEND
;
185 val
= PCF50633_MBCC7_USB_100mA
;
187 val
= PCF50633_MBCC7_USB_500mA
;
189 val
= PCF50633_MBCC7_USB_1000mA
;
191 return pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC7
, 0x03, val
);
195 static const char *charger_states
[] = {
197 [1] = "usb_precharge",
198 [2] = "usb_precharge_wait",
199 [3] = "usb_fast_charge",
200 [4] = "usb_fast_charge_wait",
202 [6] = "adapter_precharge",
203 [7] = "adapter_precharge_wait",
204 [8] = "adapter_fast_charge",
205 [9] = "adapter_fast_charge_wait",
206 [10] = "battery_full",
210 const char *pcf50633_charger_state(void)
212 u_int8_t val
= pcf50633_reg_read(PCF50633_REG_MBCS2
);
218 return charger_states
[val
];
221 #if defined(CONFIG_RTC_PCF50633) && defined(CONFIG_CMD_DATE)
225 static unsigned bcd2bin (uchar n
)
227 return ((((n
>> 4) & 0x0F) * 10) + (n
& 0x0F));
230 static unsigned char bin2bcd (unsigned int n
)
232 return (((n
/ 10) << 4) | (n
% 10));
236 void rtc_get(struct rtc_time
*tmp
)
238 tmp
->tm_sec
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCSC
));
239 tmp
->tm_min
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCMN
));
240 tmp
->tm_hour
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCHR
));
241 tmp
->tm_wday
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCWD
));
242 tmp
->tm_mday
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCDT
));
243 tmp
->tm_mon
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCMT
));
244 tmp
->tm_year
= bcd2bin(pcf50633_reg_read(PCF50633_REG_RTCYR
));
245 if (tmp
->tm_year
< 70)
246 tmp
->tm_year
+= 2000;
248 tmp
->tm_year
+= 1900;
253 void rtc_set(struct rtc_time
*tmp
)
255 pcf50633_reg_write(PCF50633_REG_RTCSC
, bin2bcd(tmp
->tm_sec
));
256 pcf50633_reg_write(PCF50633_REG_RTCMN
, bin2bcd(tmp
->tm_min
));
257 pcf50633_reg_write(PCF50633_REG_RTCHR
, bin2bcd(tmp
->tm_hour
));
258 pcf50633_reg_write(PCF50633_REG_RTCWD
, bin2bcd(tmp
->tm_wday
));
259 pcf50633_reg_write(PCF50633_REG_RTCDT
, bin2bcd(tmp
->tm_mday
));
260 pcf50633_reg_write(PCF50633_REG_RTCMN
, bin2bcd(tmp
->tm_mon
));
261 pcf50633_reg_write(PCF50633_REG_RTCYR
, bin2bcd(tmp
->tm_year
% 100));
268 #endif /* CONFIG_RTC_PCF50633 && CONFIG_CMD_DATE */
271 #endif /* CONFIG DRIVER_PCF50633 */