diff options
Diffstat (limited to 'firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c index 201af5ee00..fbe5ef805e 100644 --- a/firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/adc-ipod6g.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | 23 | ||
24 | #include "inttypes.h" | 24 | #include "inttypes.h" |
@@ -28,12 +28,90 @@ | |||
28 | #include "pmu-target.h" | 28 | #include "pmu-target.h" |
29 | #include "kernel.h" | 29 | #include "kernel.h" |
30 | 30 | ||
31 | |||
32 | /* MS_TO_TICKS converts a milisecond time period into the | ||
33 | * corresponding amount of ticks. If the time period cannot | ||
34 | * be accurately measured in ticks it will round up. | ||
35 | */ | ||
36 | #define MS_PER_HZ (1000/HZ) | ||
37 | #define MS_TO_TICKS(x) (((x)+MS_PER_HZ-1)/MS_PER_HZ) | ||
38 | |||
39 | static const struct pmu_adc_channel adc_channels[] = | ||
40 | { | ||
41 | [ADC_BATTERY] = | ||
42 | { | ||
43 | .name = "Battery", | ||
44 | .adcc1 = PCF5063X_ADCC1_MUX_BATSNS_SUBTR | ||
45 | | PCF5063X_ADCC1_AVERAGE_4 | ||
46 | | PCF5063X_ADCC1_RES_10BIT, | ||
47 | }, | ||
48 | |||
49 | [ADC_USBDATA] = | ||
50 | { | ||
51 | .name = "USB D+/D-", | ||
52 | .adcc1 = PCF5063X_ADCC1_MUX_ADCIN2_RES | ||
53 | | PCF5063X_ADCC1_AVERAGE_16 | ||
54 | | PCF5063X_ADCC1_RES_10BIT, | ||
55 | .adcc3 = PCF5063X_ADCC3_RES_DIV_THREE, | ||
56 | }, | ||
57 | |||
58 | [ADC_ACCESSORY] = | ||
59 | { | ||
60 | .name = "Accessory", | ||
61 | .adcc1 = PCF5063X_ADCC1_MUX_ADCIN1 | ||
62 | | PCF5063X_ADCC1_AVERAGE_16 | ||
63 | | PCF5063X_ADCC1_RES_10BIT, | ||
64 | .adcc2 = PCF5063X_ADCC2_RATIO_ADCIN1 | ||
65 | | PCF5063X_ADCC2_RATIOSETTL_10US, | ||
66 | .adcc3 = PCF5063X_ADCC3_ACCSW_EN, | ||
67 | .bias_dly = MS_TO_TICKS(50), | ||
68 | }, | ||
69 | }; | ||
70 | |||
71 | const char *adc_name(int channel) | ||
72 | { | ||
73 | return adc_channels[channel].name; | ||
74 | } | ||
75 | |||
76 | unsigned short adc_read_millivolts(int channel) | ||
77 | { | ||
78 | const struct pmu_adc_channel *ch = &adc_channels[channel]; | ||
79 | return pmu_adc_raw2mv(ch, pmu_read_adc(ch)); | ||
80 | } | ||
81 | |||
82 | /* Returns battery voltage [millivolts] */ | ||
83 | unsigned int adc_read_battery_voltage(void) | ||
84 | { | ||
85 | return adc_read_millivolts(ADC_BATTERY); | ||
86 | } | ||
87 | |||
88 | /* Returns USB D+/D- voltage from ADC [millivolts] */ | ||
89 | unsigned int adc_read_usbdata_voltage(bool dp) | ||
90 | { | ||
91 | unsigned int mvolts; | ||
92 | int gpio = dp ? 0xb0300 : 0xb0200; /* select D+/D- */ | ||
93 | GPIOCMD = gpio | 0xf; /* route to ADCIN2 */ | ||
94 | mvolts = adc_read_millivolts(ADC_USBDATA); | ||
95 | GPIOCMD = gpio | 0xe; /* unroute */ | ||
96 | return mvolts; | ||
97 | } | ||
98 | |||
99 | /* Returns resistor connected to "Accessory identify" pin [ohms] */ | ||
100 | #define IAP_DEVICE_RESISTOR 100000 /* ohms */ | ||
101 | int adc_read_accessory_resistor(void) | ||
102 | { | ||
103 | int raw = pmu_read_adc(&adc_channels[ADC_ACCESSORY]); | ||
104 | return (1023-raw) ? raw * IAP_DEVICE_RESISTOR / (1023-raw) | ||
105 | : -1 /* open circuit */; | ||
106 | } | ||
107 | |||
108 | |||
109 | /* API functions */ | ||
31 | unsigned short adc_read(int channel) | 110 | unsigned short adc_read(int channel) |
32 | { | 111 | { |
33 | return pmu_read_adc(channel); | 112 | return pmu_read_adc(&adc_channels[channel]); |
34 | } | 113 | } |
35 | 114 | ||
36 | void adc_init(void) | 115 | void adc_init(void) |
37 | { | 116 | { |
38 | } | 117 | } |
39 | |||