forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/iio/light/tsl2772.c
....@@ -20,6 +20,7 @@
2020 #include <linux/iio/iio.h>
2121 #include <linux/iio/sysfs.h>
2222 #include <linux/platform_data/tsl2772.h>
23
+#include <linux/regulator/consumer.h>
2324
2425 /* Cal defs */
2526 #define PROX_STAT_CAL 0
....@@ -107,6 +108,11 @@
107108 #define TSL2772_ALS_GAIN_TRIM_MIN 250
108109 #define TSL2772_ALS_GAIN_TRIM_MAX 4000
109110
111
+#define TSL2772_MAX_PROX_LEDS 2
112
+
113
+#define TSL2772_BOOT_MIN_SLEEP_TIME 10000
114
+#define TSL2772_BOOT_MAX_SLEEP_TIME 28000
115
+
110116 /* Device family members */
111117 enum {
112118 tsl2571,
....@@ -118,13 +124,20 @@
118124 tsl2672,
119125 tmd2672,
120126 tsl2772,
121
- tmd2772
127
+ tmd2772,
128
+ apds9930,
122129 };
123130
124131 enum {
125132 TSL2772_CHIP_UNKNOWN = 0,
126133 TSL2772_CHIP_WORKING = 1,
127134 TSL2772_CHIP_SUSPENDED = 2
135
+};
136
+
137
+enum {
138
+ TSL2772_SUPPLY_VDD = 0,
139
+ TSL2772_SUPPLY_VDDIO = 1,
140
+ TSL2772_NUM_SUPPLIES = 2
128141 };
129142
130143 /* Per-device data */
....@@ -141,11 +154,20 @@
141154 const struct iio_info *info;
142155 };
143156
157
+static const int tsl2772_led_currents[][2] = {
158
+ { 100000, TSL2772_100_mA },
159
+ { 50000, TSL2772_50_mA },
160
+ { 25000, TSL2772_25_mA },
161
+ { 13000, TSL2772_13_mA },
162
+ { 0, 0 }
163
+};
164
+
144165 struct tsl2772_chip {
145166 kernel_ulong_t id;
146167 struct mutex prox_mutex;
147168 struct mutex als_mutex;
148169 struct i2c_client *client;
170
+ struct regulator_bulk_data supplies[TSL2772_NUM_SUPPLIES];
149171 u16 prox_data;
150172 struct tsl2772_als_info als_cur_info;
151173 struct tsl2772_settings settings;
....@@ -197,6 +219,12 @@
197219 { 0, 0 },
198220 };
199221
222
+static const struct tsl2772_lux apds9930_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
223
+ { 52000, 96824 },
224
+ { 38792, 67132 },
225
+ { 0, 0 },
226
+};
227
+
200228 static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
201229 [tsl2571] = tsl2x71_lux_table,
202230 [tsl2671] = tsl2x71_lux_table,
....@@ -208,6 +236,7 @@
208236 [tmd2672] = tmd2x72_lux_table,
209237 [tsl2772] = tsl2x72_lux_table,
210238 [tmd2772] = tmd2x72_lux_table,
239
+ [apds9930] = apds9930_lux_table,
211240 };
212241
213242 static const struct tsl2772_settings tsl2772_default_settings = {
....@@ -258,6 +287,7 @@
258287 [tmd2672] = { 0, 2730, 0, 2730, 0, 699000 },
259288 [tsl2772] = { 0, 2730, 0, 2730, 0, 699000 },
260289 [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 },
290
+ [apds9930] = { 0, 2730, 0, 2730, 0, 699000 },
261291 };
262292
263293 static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 };
....@@ -283,7 +313,8 @@
283313 [tsl2672] = PRX2,
284314 [tmd2672] = PRX2,
285315 [tsl2772] = ALSPRX2,
286
- [tmd2772] = ALSPRX2
316
+ [tmd2772] = ALSPRX2,
317
+ [apds9930] = ALSPRX2,
287318 };
288319
289320 static int tsl2772_read_status(struct tsl2772_chip *chip)
....@@ -497,6 +528,7 @@
497528 case tmd2672:
498529 case tsl2772:
499530 case tmd2772:
531
+ case apds9930:
500532 if (!(ret & TSL2772_STA_PRX_VALID)) {
501533 ret = -EINVAL;
502534 goto prox_poll_err;
....@@ -513,6 +545,75 @@
513545 mutex_unlock(&chip->prox_mutex);
514546
515547 return ret;
548
+}
549
+
550
+static int tsl2772_read_prox_led_current(struct tsl2772_chip *chip)
551
+{
552
+ struct device_node *of_node = chip->client->dev.of_node;
553
+ int ret, tmp, i;
554
+
555
+ ret = of_property_read_u32(of_node, "led-max-microamp", &tmp);
556
+ if (ret < 0)
557
+ return ret;
558
+
559
+ for (i = 0; tsl2772_led_currents[i][0] != 0; i++) {
560
+ if (tmp == tsl2772_led_currents[i][0]) {
561
+ chip->settings.prox_power = tsl2772_led_currents[i][1];
562
+ return 0;
563
+ }
564
+ }
565
+
566
+ dev_err(&chip->client->dev, "Invalid value %d for led-max-microamp\n",
567
+ tmp);
568
+
569
+ return -EINVAL;
570
+
571
+}
572
+
573
+static int tsl2772_read_prox_diodes(struct tsl2772_chip *chip)
574
+{
575
+ struct device_node *of_node = chip->client->dev.of_node;
576
+ int i, ret, num_leds, prox_diode_mask;
577
+ u32 leds[TSL2772_MAX_PROX_LEDS];
578
+
579
+ ret = of_property_count_u32_elems(of_node, "amstaos,proximity-diodes");
580
+ if (ret < 0)
581
+ return ret;
582
+
583
+ num_leds = ret;
584
+ if (num_leds > TSL2772_MAX_PROX_LEDS)
585
+ num_leds = TSL2772_MAX_PROX_LEDS;
586
+
587
+ ret = of_property_read_u32_array(of_node, "amstaos,proximity-diodes",
588
+ leds, num_leds);
589
+ if (ret < 0) {
590
+ dev_err(&chip->client->dev,
591
+ "Invalid value for amstaos,proximity-diodes: %d.\n",
592
+ ret);
593
+ return ret;
594
+ }
595
+
596
+ prox_diode_mask = 0;
597
+ for (i = 0; i < num_leds; i++) {
598
+ if (leds[i] == 0)
599
+ prox_diode_mask |= TSL2772_DIODE0;
600
+ else if (leds[i] == 1)
601
+ prox_diode_mask |= TSL2772_DIODE1;
602
+ else {
603
+ dev_err(&chip->client->dev,
604
+ "Invalid value %d in amstaos,proximity-diodes.\n",
605
+ leds[i]);
606
+ return -EINVAL;
607
+ }
608
+ }
609
+
610
+ return 0;
611
+}
612
+
613
+static void tsl2772_parse_dt(struct tsl2772_chip *chip)
614
+{
615
+ tsl2772_read_prox_led_current(chip);
616
+ tsl2772_read_prox_diodes(chip);
516617 }
517618
518619 /**
....@@ -541,6 +642,8 @@
541642 memcpy(chip->tsl2772_device_lux,
542643 tsl2772_default_lux_table_group[chip->id],
543644 TSL2772_DEFAULT_TABLE_BYTES);
645
+
646
+ tsl2772_parse_dt(chip);
544647 }
545648
546649 /**
....@@ -593,6 +696,13 @@
593696 chip->settings.als_gain_trim = ret;
594697
595698 return ret;
699
+}
700
+
701
+static void tsl2772_disable_regulators_action(void *_data)
702
+{
703
+ struct tsl2772_chip *chip = _data;
704
+
705
+ regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies);
596706 }
597707
598708 static int tsl2772_chip_on(struct iio_dev *indio_dev)
....@@ -822,7 +932,7 @@
822932 {
823933 struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
824934
825
- return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
935
+ return scnprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
826936 }
827937
828938 static ssize_t in_illuminance0_target_input_store(struct device *dev,
....@@ -876,7 +986,7 @@
876986 int offset = 0;
877987
878988 while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
879
- offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
989
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%u,%u,",
880990 chip->tsl2772_device_lux[i].ch0,
881991 chip->tsl2772_device_lux[i].ch1);
882992 if (chip->tsl2772_device_lux[i].ch0 == 0) {
....@@ -890,7 +1000,7 @@
8901000 i++;
8911001 }
8921002
893
- offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1003
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\n");
8941004 return offset;
8951005 }
8961006
....@@ -1267,6 +1377,7 @@
12671377 case tmd2672:
12681378 case tsl2772:
12691379 case tmd2772:
1380
+ case apds9930:
12701381 return (id & 0xf0) == SWORDFISH_ID;
12711382 }
12721383
....@@ -1659,6 +1770,33 @@
16591770 chip->client = clientp;
16601771 i2c_set_clientdata(clientp, indio_dev);
16611772
1773
+ chip->supplies[TSL2772_SUPPLY_VDD].supply = "vdd";
1774
+ chip->supplies[TSL2772_SUPPLY_VDDIO].supply = "vddio";
1775
+
1776
+ ret = devm_regulator_bulk_get(&clientp->dev,
1777
+ ARRAY_SIZE(chip->supplies),
1778
+ chip->supplies);
1779
+ if (ret < 0)
1780
+ return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n");
1781
+
1782
+ ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies);
1783
+ if (ret < 0) {
1784
+ dev_err(&clientp->dev, "Failed to enable regulators: %d\n",
1785
+ ret);
1786
+ return ret;
1787
+ }
1788
+
1789
+ ret = devm_add_action_or_reset(&clientp->dev,
1790
+ tsl2772_disable_regulators_action,
1791
+ chip);
1792
+ if (ret < 0) {
1793
+ dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n",
1794
+ ret);
1795
+ return ret;
1796
+ }
1797
+
1798
+ usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
1799
+
16621800 ret = i2c_smbus_read_byte_data(chip->client,
16631801 TSL2772_CMD_REG | TSL2772_CHIPID);
16641802 if (ret < 0)
....@@ -1689,7 +1827,6 @@
16891827 &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]];
16901828
16911829 indio_dev->info = chip->chip_info->info;
1692
- indio_dev->dev.parent = &clientp->dev;
16931830 indio_dev->modes = INDIO_DIRECT_MODE;
16941831 indio_dev->name = chip->client->name;
16951832 indio_dev->num_channels = chip->chip_info->chan_table_elements;
....@@ -1724,37 +1861,34 @@
17241861 if (ret < 0)
17251862 return ret;
17261863
1727
- ret = iio_device_register(indio_dev);
1728
- if (ret) {
1729
- dev_err(&clientp->dev,
1730
- "%s: iio registration failed\n", __func__);
1731
- return ret;
1732
- }
1733
-
1734
- return 0;
1864
+ return devm_iio_device_register(&clientp->dev, indio_dev);
17351865 }
17361866
17371867 static int tsl2772_suspend(struct device *dev)
17381868 {
17391869 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1870
+ struct tsl2772_chip *chip = iio_priv(indio_dev);
1871
+ int ret;
17401872
1741
- return tsl2772_chip_off(indio_dev);
1873
+ ret = tsl2772_chip_off(indio_dev);
1874
+ regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies);
1875
+
1876
+ return ret;
17421877 }
17431878
17441879 static int tsl2772_resume(struct device *dev)
17451880 {
17461881 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1882
+ struct tsl2772_chip *chip = iio_priv(indio_dev);
1883
+ int ret;
1884
+
1885
+ ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies);
1886
+ if (ret < 0)
1887
+ return ret;
1888
+
1889
+ usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
17471890
17481891 return tsl2772_chip_on(indio_dev);
1749
-}
1750
-
1751
-static int tsl2772_remove(struct i2c_client *client)
1752
-{
1753
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
1754
-
1755
- iio_device_unregister(indio_dev);
1756
-
1757
- return 0;
17581892 }
17591893
17601894 static const struct i2c_device_id tsl2772_idtable[] = {
....@@ -1768,6 +1902,7 @@
17681902 { "tmd2672", tmd2672 },
17691903 { "tsl2772", tsl2772 },
17701904 { "tmd2772", tmd2772 },
1905
+ { "apds9930", apds9930},
17711906 {}
17721907 };
17731908
....@@ -1784,6 +1919,7 @@
17841919 { .compatible = "amstaos,tmd2672" },
17851920 { .compatible = "amstaos,tsl2772" },
17861921 { .compatible = "amstaos,tmd2772" },
1922
+ { .compatible = "avago,apds9930" },
17871923 {}
17881924 };
17891925 MODULE_DEVICE_TABLE(of, tsl2772_of_match);
....@@ -1801,7 +1937,6 @@
18011937 },
18021938 .id_table = tsl2772_idtable,
18031939 .probe = tsl2772_probe,
1804
- .remove = tsl2772_remove,
18051940 };
18061941
18071942 module_i2c_driver(tsl2772_driver);