forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
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,76 @@
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
+ chip->settings.prox_diode = prox_diode_mask;
610
+
611
+ return 0;
612
+}
613
+
614
+static void tsl2772_parse_dt(struct tsl2772_chip *chip)
615
+{
616
+ tsl2772_read_prox_led_current(chip);
617
+ tsl2772_read_prox_diodes(chip);
516618 }
517619
518620 /**
....@@ -541,6 +643,8 @@
541643 memcpy(chip->tsl2772_device_lux,
542644 tsl2772_default_lux_table_group[chip->id],
543645 TSL2772_DEFAULT_TABLE_BYTES);
646
+
647
+ tsl2772_parse_dt(chip);
544648 }
545649
546650 /**
....@@ -593,6 +697,13 @@
593697 chip->settings.als_gain_trim = ret;
594698
595699 return ret;
700
+}
701
+
702
+static void tsl2772_disable_regulators_action(void *_data)
703
+{
704
+ struct tsl2772_chip *chip = _data;
705
+
706
+ regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies);
596707 }
597708
598709 static int tsl2772_chip_on(struct iio_dev *indio_dev)
....@@ -822,7 +933,7 @@
822933 {
823934 struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
824935
825
- return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
936
+ return scnprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
826937 }
827938
828939 static ssize_t in_illuminance0_target_input_store(struct device *dev,
....@@ -876,7 +987,7 @@
876987 int offset = 0;
877988
878989 while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
879
- offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
990
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%u,%u,",
880991 chip->tsl2772_device_lux[i].ch0,
881992 chip->tsl2772_device_lux[i].ch1);
882993 if (chip->tsl2772_device_lux[i].ch0 == 0) {
....@@ -890,7 +1001,7 @@
8901001 i++;
8911002 }
8921003
893
- offset += snprintf(buf + offset, PAGE_SIZE, "\n");
1004
+ offset += scnprintf(buf + offset, PAGE_SIZE - offset, "\n");
8941005 return offset;
8951006 }
8961007
....@@ -1267,6 +1378,7 @@
12671378 case tmd2672:
12681379 case tsl2772:
12691380 case tmd2772:
1381
+ case apds9930:
12701382 return (id & 0xf0) == SWORDFISH_ID;
12711383 }
12721384
....@@ -1659,6 +1771,33 @@
16591771 chip->client = clientp;
16601772 i2c_set_clientdata(clientp, indio_dev);
16611773
1774
+ chip->supplies[TSL2772_SUPPLY_VDD].supply = "vdd";
1775
+ chip->supplies[TSL2772_SUPPLY_VDDIO].supply = "vddio";
1776
+
1777
+ ret = devm_regulator_bulk_get(&clientp->dev,
1778
+ ARRAY_SIZE(chip->supplies),
1779
+ chip->supplies);
1780
+ if (ret < 0)
1781
+ return dev_err_probe(&clientp->dev, ret, "Failed to get regulators\n");
1782
+
1783
+ ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies);
1784
+ if (ret < 0) {
1785
+ dev_err(&clientp->dev, "Failed to enable regulators: %d\n",
1786
+ ret);
1787
+ return ret;
1788
+ }
1789
+
1790
+ ret = devm_add_action_or_reset(&clientp->dev,
1791
+ tsl2772_disable_regulators_action,
1792
+ chip);
1793
+ if (ret < 0) {
1794
+ dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n",
1795
+ ret);
1796
+ return ret;
1797
+ }
1798
+
1799
+ usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
1800
+
16621801 ret = i2c_smbus_read_byte_data(chip->client,
16631802 TSL2772_CMD_REG | TSL2772_CHIPID);
16641803 if (ret < 0)
....@@ -1689,7 +1828,6 @@
16891828 &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]];
16901829
16911830 indio_dev->info = chip->chip_info->info;
1692
- indio_dev->dev.parent = &clientp->dev;
16931831 indio_dev->modes = INDIO_DIRECT_MODE;
16941832 indio_dev->name = chip->client->name;
16951833 indio_dev->num_channels = chip->chip_info->chan_table_elements;
....@@ -1724,37 +1862,34 @@
17241862 if (ret < 0)
17251863 return ret;
17261864
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;
1865
+ return devm_iio_device_register(&clientp->dev, indio_dev);
17351866 }
17361867
17371868 static int tsl2772_suspend(struct device *dev)
17381869 {
17391870 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1871
+ struct tsl2772_chip *chip = iio_priv(indio_dev);
1872
+ int ret;
17401873
1741
- return tsl2772_chip_off(indio_dev);
1874
+ ret = tsl2772_chip_off(indio_dev);
1875
+ regulator_bulk_disable(ARRAY_SIZE(chip->supplies), chip->supplies);
1876
+
1877
+ return ret;
17421878 }
17431879
17441880 static int tsl2772_resume(struct device *dev)
17451881 {
17461882 struct iio_dev *indio_dev = dev_get_drvdata(dev);
1883
+ struct tsl2772_chip *chip = iio_priv(indio_dev);
1884
+ int ret;
1885
+
1886
+ ret = regulator_bulk_enable(ARRAY_SIZE(chip->supplies), chip->supplies);
1887
+ if (ret < 0)
1888
+ return ret;
1889
+
1890
+ usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME);
17471891
17481892 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;
17581893 }
17591894
17601895 static const struct i2c_device_id tsl2772_idtable[] = {
....@@ -1768,6 +1903,7 @@
17681903 { "tmd2672", tmd2672 },
17691904 { "tsl2772", tsl2772 },
17701905 { "tmd2772", tmd2772 },
1906
+ { "apds9930", apds9930},
17711907 {}
17721908 };
17731909
....@@ -1784,6 +1920,7 @@
17841920 { .compatible = "amstaos,tmd2672" },
17851921 { .compatible = "amstaos,tsl2772" },
17861922 { .compatible = "amstaos,tmd2772" },
1923
+ { .compatible = "avago,apds9930" },
17871924 {}
17881925 };
17891926 MODULE_DEVICE_TABLE(of, tsl2772_of_match);
....@@ -1801,7 +1938,6 @@
18011938 },
18021939 .id_table = tsl2772_idtable,
18031940 .probe = tsl2772_probe,
1804
- .remove = tsl2772_remove,
18051941 };
18061942
18071943 module_i2c_driver(tsl2772_driver);