5
5
* Quentin Schulz <[email protected] >
6
6
*/
7
7
8
+ #include <asm/unaligned.h>
8
9
#include <linux/bitfield.h>
9
10
#include <linux/completion.h>
10
11
#include <linux/interrupt.h>
30
31
31
32
#define AXP22X_ADC_EN1_MASK (GENMASK(7, 5) | BIT(0))
32
33
34
+ #define AXP717_ADC_EN1_MASK GENMASK(7, 0)
35
+
33
36
#define AXP192_GPIO30_IN_RANGE_GPIO0 BIT(0)
34
37
#define AXP192_GPIO30_IN_RANGE_GPIO1 BIT(1)
35
38
#define AXP192_GPIO30_IN_RANGE_GPIO2 BIT(2)
43
46
44
47
#define AXP22X_ADC_RATE_HZ (x ) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)
45
48
49
+ #define AXP717_ADC_DATA_TS 0x00
50
+ #define AXP717_ADC_DATA_TEMP 0x01
51
+ #define AXP717_ADC_DATA_VMID 0x02
52
+ #define AXP717_ADC_DATA_BKUP_BATT 0x03
53
+
54
+ #define AXP717_ADC_DATA_MASK GENMASK(13, 0)
55
+
46
56
#define AXP813_V_I_ADC_RATE_MASK GENMASK(5, 4)
47
57
#define AXP813_ADC_RATE_MASK (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK)
48
58
#define AXP813_TS_GPIO0_ADC_RATE_HZ (x ) AXP20X_ADC_RATE_HZ(x)
@@ -125,6 +135,20 @@ enum axp22x_adc_channel_i {
125
135
AXP22X_BATT_DISCHRG_I ,
126
136
};
127
137
138
+ enum axp717_adc_channel_v {
139
+ AXP717_BATT_V = 0 ,
140
+ AXP717_TS_IN ,
141
+ AXP717_VBUS_V ,
142
+ AXP717_VSYS_V ,
143
+ AXP717_DIE_TEMP_V ,
144
+ AXP717_VMID_V = 6 ,
145
+ AXP717_BKUP_BATT_V ,
146
+ };
147
+
148
+ enum axp717_adc_channel_i {
149
+ AXP717_BATT_CHRG_I = 5 ,
150
+ };
151
+
128
152
enum axp813_adc_channel_v {
129
153
AXP813_TS_IN = 0 ,
130
154
AXP813_GPIO0_V ,
@@ -179,6 +203,22 @@ static struct iio_map axp22x_maps[] = {
179
203
}, { /* sentinel */ }
180
204
};
181
205
206
+ static struct iio_map axp717_maps [] = {
207
+ {
208
+ .consumer_dev_name = "axp20x-usb-power-supply" ,
209
+ .consumer_channel = "vbus_v" ,
210
+ .adc_channel_label = "vbus_v" ,
211
+ }, {
212
+ .consumer_dev_name = "axp20x-battery-power-supply" ,
213
+ .consumer_channel = "batt_v" ,
214
+ .adc_channel_label = "batt_v" ,
215
+ }, {
216
+ .consumer_dev_name = "axp20x-battery-power-supply" ,
217
+ .consumer_channel = "batt_chrg_i" ,
218
+ .adc_channel_label = "batt_chrg_i" ,
219
+ },
220
+ };
221
+
182
222
/*
183
223
* Channels are mapped by physical system. Their channels share the same index.
184
224
* i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.
@@ -274,6 +314,29 @@ static const struct iio_chan_spec axp22x_adc_channels[] = {
274
314
AXP22X_TS_ADC_H ),
275
315
};
276
316
317
+ /*
318
+ * Scale and offset is unknown for temp, ts, batt_chrg_i, vmid_v, and
319
+ * bkup_batt_v channels. Leaving scale and offset undefined for now.
320
+ */
321
+ static const struct iio_chan_spec axp717_adc_channels [] = {
322
+ AXP20X_ADC_CHANNEL (AXP717_BATT_V , "batt_v" , IIO_VOLTAGE ,
323
+ AXP717_BATT_V_H ),
324
+ AXP20X_ADC_CHANNEL (AXP717_TS_IN , "ts_v" , IIO_VOLTAGE ,
325
+ AXP717_ADC_DATA_H ),
326
+ AXP20X_ADC_CHANNEL (AXP717_VBUS_V , "vbus_v" , IIO_VOLTAGE ,
327
+ AXP717_VBUS_V_H ),
328
+ AXP20X_ADC_CHANNEL (AXP717_VSYS_V , "vsys_v" , IIO_VOLTAGE ,
329
+ AXP717_VSYS_V_H ),
330
+ AXP20X_ADC_CHANNEL (AXP717_DIE_TEMP_V , "pmic_temp" , IIO_TEMP ,
331
+ AXP717_ADC_DATA_H ),
332
+ AXP20X_ADC_CHANNEL (AXP717_BATT_CHRG_I , "batt_chrg_i" , IIO_CURRENT ,
333
+ AXP717_BATT_CHRG_I_H ),
334
+ AXP20X_ADC_CHANNEL (AXP717_VMID_V , "vmid_v" , IIO_VOLTAGE ,
335
+ AXP717_ADC_DATA_H ),
336
+ AXP20X_ADC_CHANNEL (AXP717_BKUP_BATT_V , "bkup_batt_v" , IIO_VOLTAGE ,
337
+ AXP717_ADC_DATA_H ),
338
+ };
339
+
277
340
static const struct iio_chan_spec axp813_adc_channels [] = {
278
341
{
279
342
.type = IIO_TEMP ,
@@ -354,6 +417,51 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev,
354
417
return IIO_VAL_INT ;
355
418
}
356
419
420
+ static int axp717_adc_raw (struct iio_dev * indio_dev ,
421
+ struct iio_chan_spec const * chan , int * val )
422
+ {
423
+ struct axp20x_adc_iio * info = iio_priv (indio_dev );
424
+ u8 bulk_reg [2 ];
425
+ int ret ;
426
+
427
+ /*
428
+ * A generic "ADC data" channel is used for TS, tdie, vmid,
429
+ * and vbackup. This channel must both first be enabled and
430
+ * also selected before it can be read.
431
+ */
432
+ switch (chan -> channel ) {
433
+ case AXP717_TS_IN :
434
+ regmap_write (info -> regmap , AXP717_ADC_DATA_SEL ,
435
+ AXP717_ADC_DATA_TS );
436
+ break ;
437
+ case AXP717_DIE_TEMP_V :
438
+ regmap_write (info -> regmap , AXP717_ADC_DATA_SEL ,
439
+ AXP717_ADC_DATA_TEMP );
440
+ break ;
441
+ case AXP717_VMID_V :
442
+ regmap_write (info -> regmap , AXP717_ADC_DATA_SEL ,
443
+ AXP717_ADC_DATA_VMID );
444
+ break ;
445
+ case AXP717_BKUP_BATT_V :
446
+ regmap_write (info -> regmap , AXP717_ADC_DATA_SEL ,
447
+ AXP717_ADC_DATA_BKUP_BATT );
448
+ break ;
449
+ default :
450
+ break ;
451
+ }
452
+
453
+ /*
454
+ * All channels are 14 bits, with the first 2 bits on the high
455
+ * register reserved and the remaining bits as the ADC value.
456
+ */
457
+ ret = regmap_bulk_read (info -> regmap , chan -> address , bulk_reg , 2 );
458
+ if (ret < 0 )
459
+ return ret ;
460
+
461
+ * val = FIELD_GET (AXP717_ADC_DATA_MASK , get_unaligned_be16 (bulk_reg ));
462
+ return IIO_VAL_INT ;
463
+ }
464
+
357
465
static int axp813_adc_raw (struct iio_dev * indio_dev ,
358
466
struct iio_chan_spec const * chan , int * val )
359
467
{
@@ -571,6 +679,27 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
571
679
}
572
680
}
573
681
682
+ static int axp717_adc_scale (struct iio_chan_spec const * chan , int * val ,
683
+ int * val2 )
684
+ {
685
+ switch (chan -> type ) {
686
+ case IIO_VOLTAGE :
687
+ * val = 1 ;
688
+ return IIO_VAL_INT ;
689
+
690
+ case IIO_CURRENT :
691
+ * val = 1 ;
692
+ return IIO_VAL_INT ;
693
+
694
+ case IIO_TEMP :
695
+ * val = 100 ;
696
+ return IIO_VAL_INT ;
697
+
698
+ default :
699
+ return - EINVAL ;
700
+ }
701
+ }
702
+
574
703
static int axp813_adc_scale (struct iio_chan_spec const * chan , int * val ,
575
704
int * val2 )
576
705
{
@@ -746,6 +875,22 @@ static int axp22x_read_raw(struct iio_dev *indio_dev,
746
875
}
747
876
}
748
877
878
+ static int axp717_read_raw (struct iio_dev * indio_dev ,
879
+ struct iio_chan_spec const * chan , int * val ,
880
+ int * val2 , long mask )
881
+ {
882
+ switch (mask ) {
883
+ case IIO_CHAN_INFO_SCALE :
884
+ return axp717_adc_scale (chan , val , val2 );
885
+
886
+ case IIO_CHAN_INFO_RAW :
887
+ return axp717_adc_raw (indio_dev , chan , val );
888
+
889
+ default :
890
+ return - EINVAL ;
891
+ }
892
+ }
893
+
749
894
static int axp813_read_raw (struct iio_dev * indio_dev ,
750
895
struct iio_chan_spec const * chan , int * val ,
751
896
int * val2 , long mask )
@@ -860,6 +1005,10 @@ static const struct iio_info axp22x_adc_iio_info = {
860
1005
.read_raw = axp22x_read_raw ,
861
1006
};
862
1007
1008
+ static const struct iio_info axp717_adc_iio_info = {
1009
+ .read_raw = axp717_read_raw ,
1010
+ };
1011
+
863
1012
static const struct iio_info axp813_adc_iio_info = {
864
1013
.read_raw = axp813_read_raw ,
865
1014
};
@@ -930,6 +1079,15 @@ static const struct axp_data axp22x_data = {
930
1079
.maps = axp22x_maps ,
931
1080
};
932
1081
1082
+ static const struct axp_data axp717_data = {
1083
+ .iio_info = & axp717_adc_iio_info ,
1084
+ .num_channels = ARRAY_SIZE (axp717_adc_channels ),
1085
+ .channels = axp717_adc_channels ,
1086
+ .adc_en1 = AXP717_ADC_CH_EN_CONTROL ,
1087
+ .adc_en1_mask = AXP717_ADC_EN1_MASK ,
1088
+ .maps = axp717_maps ,
1089
+ };
1090
+
933
1091
static const struct axp_data axp813_data = {
934
1092
.iio_info = & axp813_adc_iio_info ,
935
1093
.num_channels = ARRAY_SIZE (axp813_adc_channels ),
@@ -944,6 +1102,7 @@ static const struct of_device_id axp20x_adc_of_match[] = {
944
1102
{ .compatible = "x-powers,axp192-adc" , .data = (void * )& axp192_data , },
945
1103
{ .compatible = "x-powers,axp209-adc" , .data = (void * )& axp20x_data , },
946
1104
{ .compatible = "x-powers,axp221-adc" , .data = (void * )& axp22x_data , },
1105
+ { .compatible = "x-powers,axp717-adc" , .data = (void * )& axp717_data , },
947
1106
{ .compatible = "x-powers,axp813-adc" , .data = (void * )& axp813_data , },
948
1107
{ /* sentinel */ }
949
1108
};
@@ -953,6 +1112,7 @@ static const struct platform_device_id axp20x_adc_id_match[] = {
953
1112
{ .name = "axp192-adc" , .driver_data = (kernel_ulong_t )& axp192_data , },
954
1113
{ .name = "axp20x-adc" , .driver_data = (kernel_ulong_t )& axp20x_data , },
955
1114
{ .name = "axp22x-adc" , .driver_data = (kernel_ulong_t )& axp22x_data , },
1115
+ { .name = "axp717-adc" , .driver_data = (kernel_ulong_t )& axp717_data , },
956
1116
{ .name = "axp813-adc" , .driver_data = (kernel_ulong_t )& axp813_data , },
957
1117
{ /* sentinel */ },
958
1118
};
0 commit comments