0008-misc-apds990x-Add-device-tree-support.patch (5515B)
1 From aca9cbfc6f2bf8a3dc6b30d6b7e78e9790a9875f Mon Sep 17 00:00:00 2001 2 From: filippz <filip.matijevic.pz@gmail.com> 3 Date: Thu, 28 Dec 2017 06:57:45 +0100 4 Subject: [PATCH 08/11] misc: apds990x: Add device tree support 5 6 Signed-off-by: filippz <filip.matijevic.pz@gmail.com> 7 --- 8 .../devicetree/bindings/misc/avago-apds990x.txt | 41 +++++++++++ 9 drivers/misc/apds990x.c | 85 +++++++++++++++++++++- 10 2 files changed, 123 insertions(+), 3 deletions(-) 11 create mode 100644 Documentation/devicetree/bindings/misc/avago-apds990x.txt 12 13 diff --git a/Documentation/devicetree/bindings/misc/avago-apds990x.txt b/Documentation/devicetree/bindings/misc/avago-apds990x.txt 14 new file mode 100644 15 index 000000000000..480c0b1c570d 16 --- /dev/null 17 +++ b/Documentation/devicetree/bindings/misc/avago-apds990x.txt 18 @@ -0,0 +1,41 @@ 19 +Avago APDS990X driver 20 + 21 +https://docs.broadcom.com/docs/AV02-2867EN 22 + 23 +Required properties: 24 +- compatible: "avago,apds990x" 25 +- reg: address on the I2C bus 26 +- interrupts: external interrupt line number 27 +- vdd-supply: power supply for VDD 28 +- vled-supply: power supply for LEDA 29 +- avago,ga: Glass attenuation 30 +- avago,cf1: Clear channel factor 1 31 +- avago,irf1: IR channel factor 1 32 +- avago,cf2: Clear channel factor 2 33 +- avago,irf2: IR channel factor 2 34 +- avago,df: Device factor 35 +- avago,pdrive: IR current, one of APDS_IRLED_CURR_XXXmA values 36 +- avago,ppcount: Proximity pulse count 37 + 38 +Example (Nokia N9): 39 + 40 + als_ps@39 { 41 + compatible = "avago,apds990x"; 42 + reg = <0x39>; 43 + 44 + interrupt-parent = <&gpio3>; 45 + interrupts = <19 (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)>; /* gpio_83 */ 46 + 47 + vdd-supply = <&vaux1>; 48 + vled-supply = <&vbat>; 49 + 50 + avago,ga = <168834>; 51 + avago,cf1 = <4096>; 52 + avago,irf1 = <7824>; 53 + avago,cf2 = <877>; 54 + avago,irf2 = <1575>; 55 + avago,df = <52>; 56 + 57 + avago,pdrive = <0x2>; /* APDS_IRLED_CURR_25mA */ 58 + avago,ppcount = <5>; 59 + }; 60 diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c 61 index ed9412d750b7..7bb9cd76110a 100644 62 --- a/drivers/misc/apds990x.c 63 +++ b/drivers/misc/apds990x.c 64 @@ -33,6 +33,8 @@ 65 #include <linux/wait.h> 66 #include <linux/slab.h> 67 #include <linux/platform_data/apds990x.h> 68 +#include <linux/gpio.h> 69 +#include <linux/of_gpio.h> 70 71 /* Register map */ 72 #define APDS990X_ENABLE 0x00 /* Enable of states and interrupts */ 73 @@ -195,8 +197,8 @@ static const u16 arates_hz[] = {10, 5, 2, 1}; 74 static const u8 apersis[] = {1, 2, 4, 5}; 75 76 /* Regulators */ 77 -static const char reg_vcc[] = "Vdd"; 78 -static const char reg_vled[] = "Vled"; 79 +static const char reg_vcc[] = "vdd"; 80 +static const char reg_vled[] = "vled"; 81 82 static int apds990x_read_byte(struct apds990x_chip *chip, u8 reg, u8 *data) 83 { 84 @@ -1066,11 +1068,71 @@ static const struct attribute_group apds990x_attribute_group[] = { 85 {.attrs = sysfs_attrs_ctrl }, 86 }; 87 88 +static const int apds990x_parse_dt(struct device *dev, 89 + struct apds990x_platform_data *pdata) 90 +{ 91 + struct device_node *np = dev->of_node; 92 + int res; 93 + 94 + if (!np) 95 + return -EINVAL; 96 + 97 + res = of_property_read_s32(np, "avago,ga", &pdata->cf.ga); 98 + if (res < 0) { 99 + dev_err(dev, "Failed to retrieve ga from device tree\n"); 100 + return -EINVAL; 101 + } 102 + 103 + res = of_property_read_s32(np, "avago,cf1", &pdata->cf.cf1); 104 + if (res < 0) { 105 + dev_err(dev, "Failed to retrieve cf1 from device tree\n"); 106 + return -EINVAL; 107 + } 108 + 109 + res = of_property_read_s32(np, "avago,irf1", &pdata->cf.irf1); 110 + if (res < 0) { 111 + dev_err(dev, "Failed to retrieve irf1 from device tree\n"); 112 + return -EINVAL; 113 + } 114 + 115 + res = of_property_read_s32(np, "cf2", &pdata->cf.cf2); 116 + if (res < 0) { 117 + dev_err(dev, "Failed to retrieve cf2 from device tree\n"); 118 + return -EINVAL; 119 + } 120 + 121 + res = of_property_read_s32(np, "avago,irf2", &pdata->cf.irf2); 122 + if (res < 0) { 123 + dev_err(dev, "Failed to retrieve irf2 from device tree\n"); 124 + return -EINVAL; 125 + } 126 + 127 + res = of_property_read_s32(np, "avago,df", &pdata->cf.df); 128 + if (res < 0) { 129 + dev_err(dev, "Failed to retrieve irf1 from device tree\n"); 130 + return -EINVAL; 131 + } 132 + 133 + res = of_property_read_u8(np, "avago,pdrive", &pdata->pdrive); 134 + if (res < 0) { 135 + dev_err(dev, "Failed to retrieve pdrive from device tree\n"); 136 + return -EINVAL; 137 + } 138 + 139 + res = of_property_read_u8(np, "avago,ppcount", &pdata->ppcount); 140 + if (res < 0) { 141 + dev_err(dev, "Failed to retrieve ppcount from device tree\n"); 142 + return -EINVAL; 143 + } 144 + 145 + return 0; 146 +} 147 + 148 static int apds990x_probe(struct i2c_client *client, 149 const struct i2c_device_id *id) 150 { 151 struct apds990x_chip *chip; 152 - int err; 153 + int err = 0; 154 155 chip = kzalloc(sizeof *chip, GFP_KERNEL); 156 if (!chip) 157 @@ -1083,6 +1145,16 @@ static int apds990x_probe(struct i2c_client *client, 158 mutex_init(&chip->mutex); 159 chip->pdata = client->dev.platform_data; 160 161 + if (chip->pdata == NULL) { 162 + chip->pdata = devm_kzalloc(&client->dev, sizeof(*chip->pdata), 163 + GFP_KERNEL); 164 + if (!chip->pdata) 165 + return -ENOMEM; 166 + err = apds990x_parse_dt(&client->dev, chip->pdata); 167 + } 168 + if (err < 0) 169 + return err; 170 + 171 if (chip->pdata == NULL) { 172 dev_err(&client->dev, "platform data is mandatory\n"); 173 err = -EINVAL; 174 @@ -1283,9 +1355,16 @@ static const struct dev_pm_ops apds990x_pm_ops = { 175 NULL) 176 }; 177 178 +static const struct of_device_id apds990x_of_match[] = { 179 + {.compatible = "avago,apds990x" }, 180 + {} 181 +}; 182 +MODULE_DEVICE_TABLE(of, apds990x_of_match); 183 + 184 static struct i2c_driver apds990x_driver = { 185 .driver = { 186 .name = "apds990x", 187 + .of_match_table = apds990x_of_match, 188 .pm = &apds990x_pm_ops, 189 }, 190 .probe = apds990x_probe, 191 -- 192 2.14.1 193