diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/adc.c | 67 | ||||
-rw-r--r-- | firmware/drivers/i2c-pp5002.c | 10 | ||||
-rw-r--r-- | firmware/drivers/i2c-pp5020.c | 32 | ||||
-rw-r--r-- | firmware/drivers/pcf50605.c | 12 | ||||
-rw-r--r-- | firmware/drivers/rtc.c | 2 |
5 files changed, 70 insertions, 53 deletions
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c index a75f788417..4a99a49753 100644 --- a/firmware/drivers/adc.c +++ b/firmware/drivers/adc.c | |||
@@ -286,60 +286,57 @@ void adc_init(void) | |||
286 | #elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002) | 286 | #elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002) |
287 | 287 | ||
288 | struct adc_struct { | 288 | struct adc_struct { |
289 | long last_read; | 289 | long timeout; |
290 | unsigned short (*conversion)(unsigned short data); | 290 | void (*conversion)(unsigned short *data); |
291 | short channelnum; | 291 | short channelnum; |
292 | unsigned short data; | 292 | unsigned short data; |
293 | }; | 293 | }; |
294 | 294 | ||
295 | static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR; | 295 | static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR; |
296 | 296 | ||
297 | /* This takes 10 bit ADC data from the subtractor circuit and scales it to | 297 | static unsigned short _adc_read(struct adc_struct *adc) |
298 | * a 13 bit value corresponding to 0-5.4v, the resulting range is 13FB-17FA, | ||
299 | * representing 3.1-5.4v */ | ||
300 | static unsigned short ten_bit_subtractor(unsigned short data) { | ||
301 | return (data<<2)+0x4FB; | ||
302 | } | ||
303 | |||
304 | static unsigned short _adc_scan(struct adc_struct *adc) | ||
305 | { | 298 | { |
306 | unsigned short data; | 299 | if (adc->timeout < current_tick) { |
307 | 300 | unsigned char data[2]; | |
308 | /* ADCC1, 8 bit, start */ | 301 | unsigned short value; |
309 | pcf50605_write(0x2f, 0x80 | (adc->channelnum << 1) | 0x1); | 302 | /* 5x per 2 seconds */ |
310 | data = pcf50605_read(0x30); /* ADCS1 */ | 303 | adc->timeout = current_tick + (HZ * 2 / 5); |
311 | 304 | ||
312 | if (adc->conversion) { | 305 | /* ADCC1, 10 bit, start */ |
313 | data = adc->conversion(data); | 306 | pcf50605_write(0x2f, (adc->channelnum << 1) | 0x1); |
307 | pcf50605_read_multiple(0x30, data, 2); /* ADCS1, ADCS2 */ | ||
308 | value = data[0]; | ||
309 | value <<= 2; | ||
310 | value |= data[1] & 0x3; | ||
311 | |||
312 | if (adc->conversion) { | ||
313 | adc->conversion(&value); | ||
314 | } | ||
315 | adc->data = value; | ||
316 | return value; | ||
317 | } else { | ||
318 | return adc->data; | ||
314 | } | 319 | } |
315 | adc->data = data; | ||
316 | return data; | ||
317 | } | 320 | } |
318 | 321 | ||
319 | /* Force an ADC scan _now_ */ | 322 | /* Force an ADC scan _now_ */ |
320 | unsigned short adc_scan(int channel) { | 323 | unsigned short adc_scan(int channel) { |
321 | return _adc_scan(&adcdata[channel]); | 324 | struct adc_struct *adc = &adcdata[channel]; |
325 | adc->timeout = 0; | ||
326 | return _adc_read(adc); | ||
322 | } | 327 | } |
323 | 328 | ||
324 | /* Retrieve the ADC value, only does a scan once per second or less */ | 329 | /* Retrieve the ADC value, only does a scan periodically */ |
325 | unsigned short adc_read(int channel) | 330 | unsigned short adc_read(int channel) { |
326 | { | 331 | return _adc_read(&adcdata[channel]); |
327 | struct adc_struct *adc = &adcdata[channel]; | ||
328 | if (adc->last_read + HZ < current_tick) { | ||
329 | adc->last_read = current_tick; | ||
330 | return _adc_scan(adc); | ||
331 | } else { | ||
332 | return adc->data; | ||
333 | } | ||
334 | } | 332 | } |
335 | 333 | ||
336 | void adc_init(void) | 334 | void adc_init(void) |
337 | { | 335 | { |
338 | struct adc_struct *adc_battery = &adcdata[ADC_BATTERY]; | 336 | struct adc_struct *adc_battery = &adcdata[ADC_BATTERY]; |
339 | adc_battery->channelnum = 0x3; /* ADCVIN1, subtractor */ | 337 | adc_battery->channelnum = 0x2; /* ADCVIN1, resistive divider */ |
340 | adc_battery->conversion = ten_bit_subtractor; | 338 | adc_battery->timeout = 0; |
341 | adc_battery->last_read = current_tick; | 339 | _adc_read(adc_battery); |
342 | _adc_scan(adc_battery); | ||
343 | } | 340 | } |
344 | 341 | ||
345 | #elif CONFIG_CPU == PNX0101 | 342 | #elif CONFIG_CPU == PNX0101 |
diff --git a/firmware/drivers/i2c-pp5002.c b/firmware/drivers/i2c-pp5002.c index dc26d8a5d9..958ddeebe4 100644 --- a/firmware/drivers/i2c-pp5002.c +++ b/firmware/drivers/i2c-pp5002.c | |||
@@ -136,6 +136,16 @@ int ipod_i2c_send_byte(unsigned int addr, int data0) | |||
136 | return ipod_i2c_send_bytes(addr, 1, data); | 136 | return ipod_i2c_send_bytes(addr, 1, data); |
137 | } | 137 | } |
138 | 138 | ||
139 | int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) { | ||
140 | unsigned int temp; | ||
141 | int i; | ||
142 | ipod_i2c_send_byte(dev_addr, addr); | ||
143 | for (i = 0; i < len; i++) { | ||
144 | ipod_i2c_read_byte(dev_addr, &temp); | ||
145 | data[i] = temp; | ||
146 | } | ||
147 | return i; | ||
148 | } | ||
139 | 149 | ||
140 | int i2c_readbyte(unsigned int dev_addr, int addr) | 150 | int i2c_readbyte(unsigned int dev_addr, int addr) |
141 | { | 151 | { |
diff --git a/firmware/drivers/i2c-pp5020.c b/firmware/drivers/i2c-pp5020.c index 232de9cb5a..8b48375e3d 100644 --- a/firmware/drivers/i2c-pp5020.c +++ b/firmware/drivers/i2c-pp5020.c | |||
@@ -63,7 +63,6 @@ static int ipod_i2c_wait_not_busy(void) | |||
63 | return -1; | 63 | return -1; |
64 | } | 64 | } |
65 | 65 | ||
66 | |||
67 | static int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) | 66 | static int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) |
68 | { | 67 | { |
69 | if (ipod_i2c_wait_not_busy() < 0) | 68 | if (ipod_i2c_wait_not_busy() < 0) |
@@ -72,6 +71,7 @@ static int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) | |||
72 | } | 71 | } |
73 | 72 | ||
74 | { | 73 | { |
74 | unsigned int byte; | ||
75 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | 75 | int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); |
76 | 76 | ||
77 | /* clear top 15 bits, left shift 1, or in 0x1 for a read */ | 77 | /* clear top 15 bits, left shift 1, or in 0x1 for a read */ |
@@ -81,15 +81,18 @@ static int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) | |||
81 | 81 | ||
82 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); | 82 | outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); |
83 | 83 | ||
84 | if (data) | 84 | set_irq_level(old_irq_level); |
85 | if (ipod_i2c_wait_not_busy() < 0) | ||
85 | { | 86 | { |
86 | if (ipod_i2c_wait_not_busy() < 0) | 87 | return -1; |
87 | { | ||
88 | set_irq_level(old_irq_level); | ||
89 | return -1; | ||
90 | } | ||
91 | *data = inb(IPOD_I2C_DATA0); | ||
92 | } | 88 | } |
89 | old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); | ||
90 | |||
91 | byte = inb(IPOD_I2C_DATA0); | ||
92 | |||
93 | if (data) | ||
94 | *data = byte; | ||
95 | |||
93 | set_irq_level(old_irq_level); | 96 | set_irq_level(old_irq_level); |
94 | } | 97 | } |
95 | 98 | ||
@@ -148,6 +151,19 @@ static int ipod_i2c_send_byte(unsigned int addr, int data0) | |||
148 | /* Public functions */ | 151 | /* Public functions */ |
149 | static struct mutex i2c_mutex; | 152 | static struct mutex i2c_mutex; |
150 | 153 | ||
154 | int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data) { | ||
155 | unsigned int temp; | ||
156 | int i; | ||
157 | mutex_lock(&i2c_mutex); | ||
158 | ipod_i2c_send_byte(dev_addr, addr); | ||
159 | for (i = 0; i < len; i++) { | ||
160 | ipod_i2c_read_byte(dev_addr, &temp); | ||
161 | data[i] = temp; | ||
162 | } | ||
163 | mutex_unlock(&i2c_mutex); | ||
164 | return i; | ||
165 | } | ||
166 | |||
151 | int i2c_readbyte(unsigned int dev_addr, int addr) | 167 | int i2c_readbyte(unsigned int dev_addr, int addr) |
152 | { | 168 | { |
153 | int data; | 169 | int data; |
diff --git a/firmware/drivers/pcf50605.c b/firmware/drivers/pcf50605.c index c8ea4a499f..a8c61b1789 100644 --- a/firmware/drivers/pcf50605.c +++ b/firmware/drivers/pcf50605.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * KIND, either express or implied. | 23 | * KIND, either express or implied. |
24 | * | 24 | * |
25 | ****************************************************************************/ | 25 | ****************************************************************************/ |
26 | #include "system.h" | ||
26 | #include "config.h" | 27 | #include "config.h" |
27 | #if CONFIG_I2C == I2C_PP5020 | 28 | #if CONFIG_I2C == I2C_PP5020 |
28 | #include "i2c-pp5020.h" | 29 | #include "i2c-pp5020.h" |
@@ -72,15 +73,8 @@ int pcf50605_read(int address) | |||
72 | 73 | ||
73 | int pcf50605_read_multiple(int address, unsigned char* buf, int count) | 74 | int pcf50605_read_multiple(int address, unsigned char* buf, int count) |
74 | { | 75 | { |
75 | int i; | 76 | int read = i2c_readbytes(0x08, address, count, buf); |
76 | 77 | return read - count; | |
77 | for (i=0;i<count;i++) | ||
78 | { | ||
79 | buf[i]=pcf50605_read(address); | ||
80 | address++; | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | 78 | } |
85 | 79 | ||
86 | int pcf50605_write(int address, unsigned char val) | 80 | int pcf50605_write(int address, unsigned char val) |
diff --git a/firmware/drivers/rtc.c b/firmware/drivers/rtc.c index 4b4b45826f..6015f46026 100644 --- a/firmware/drivers/rtc.c +++ b/firmware/drivers/rtc.c | |||
@@ -34,12 +34,12 @@ | |||
34 | void rtc_init(void) | 34 | void rtc_init(void) |
35 | { | 35 | { |
36 | } | 36 | } |
37 | |||
37 | int rtc_read_datetime(unsigned char* buf) | 38 | int rtc_read_datetime(unsigned char* buf) |
38 | { | 39 | { |
39 | return pcf50605_read_multiple(0x0a, buf, 7); | 40 | return pcf50605_read_multiple(0x0a, buf, 7); |
40 | } | 41 | } |
41 | 42 | ||
42 | |||
43 | int rtc_write_datetime(unsigned char* buf) | 43 | int rtc_write_datetime(unsigned char* buf) |
44 | { | 44 | { |
45 | int i; | 45 | int i; |