Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branch 'lee/ib-mfd-hwmon-4.14' into hwmon-next

+302 -26
+263 -22
drivers/hwmon/da9052-hwmon.c
··· 20 20 #include <linux/module.h> 21 21 #include <linux/slab.h> 22 22 #include <linux/platform_device.h> 23 + #include <linux/property.h> 23 24 24 25 #include <linux/mfd/da9052/da9052.h> 25 26 #include <linux/mfd/da9052/reg.h> 27 + #include <linux/regulator/consumer.h> 26 28 27 29 struct da9052_hwmon { 28 - struct da9052 *da9052; 29 - struct mutex hwmon_lock; 30 + struct da9052 *da9052; 31 + struct mutex hwmon_lock; 32 + bool tsi_as_adc; 33 + int tsiref_mv; 34 + struct regulator *tsiref; 35 + struct completion tsidone; 30 36 }; 31 37 32 38 static const char * const input_names[] = { ··· 43 37 [DA9052_ADC_IN4] = "ADC IN4", 44 38 [DA9052_ADC_IN5] = "ADC IN5", 45 39 [DA9052_ADC_IN6] = "ADC IN6", 40 + [DA9052_ADC_TSI_XP] = "ADC TS X+", 41 + [DA9052_ADC_TSI_YP] = "ADC TS Y+", 42 + [DA9052_ADC_TSI_XN] = "ADC TS X-", 43 + [DA9052_ADC_TSI_YN] = "ADC TS Y-", 46 44 [DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP", 47 45 [DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE", 48 46 }; ··· 67 57 static inline int vbbat_reg_to_mv(int value) 68 58 { 69 59 return DIV_ROUND_CLOSEST(value * 5000, 1023); 60 + } 61 + 62 + static inline int input_tsireg_to_mv(struct da9052_hwmon *hwmon, int value) 63 + { 64 + return DIV_ROUND_CLOSEST(value * hwmon->tsiref_mv, 1023); 70 65 } 71 66 72 67 static inline int da9052_enable_vddout_channel(struct da9052 *da9052) ··· 169 154 return sprintf(buf, "%d\n", input_reg_to_mv(ret)); 170 155 } 171 156 157 + static int da9052_request_tsi_read(struct da9052_hwmon *hwmon, int channel) 158 + { 159 + u8 val = DA9052_TSICONTB_TSIMAN; 160 + 161 + switch (channel) { 162 + case DA9052_ADC_TSI_XP: 163 + val |= DA9052_TSICONTB_TSIMUX_XP; 164 + break; 165 + case DA9052_ADC_TSI_YP: 166 + val |= DA9052_TSICONTB_TSIMUX_YP; 167 + break; 168 + case DA9052_ADC_TSI_XN: 169 + val |= DA9052_TSICONTB_TSIMUX_XN; 170 + break; 171 + case DA9052_ADC_TSI_YN: 172 + val |= DA9052_TSICONTB_TSIMUX_YN; 173 + break; 174 + } 175 + 176 + return da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_B_REG, val); 177 + } 178 + 179 + static int da9052_get_tsi_result(struct da9052_hwmon *hwmon, int channel) 180 + { 181 + u8 regs[3]; 182 + int msb, lsb, err; 183 + 184 + /* block read to avoid separation of MSB and LSB */ 185 + err = da9052_group_read(hwmon->da9052, DA9052_TSI_X_MSB_REG, 186 + ARRAY_SIZE(regs), regs); 187 + if (err) 188 + return err; 189 + 190 + switch (channel) { 191 + case DA9052_ADC_TSI_XP: 192 + case DA9052_ADC_TSI_XN: 193 + msb = regs[0] << DA9052_TSILSB_TSIXL_BITS; 194 + lsb = regs[2] & DA9052_TSILSB_TSIXL; 195 + lsb >>= DA9052_TSILSB_TSIXL_SHIFT; 196 + break; 197 + case DA9052_ADC_TSI_YP: 198 + case DA9052_ADC_TSI_YN: 199 + msb = regs[1] << DA9052_TSILSB_TSIYL_BITS; 200 + lsb = regs[2] & DA9052_TSILSB_TSIYL; 201 + lsb >>= DA9052_TSILSB_TSIYL_SHIFT; 202 + break; 203 + default: 204 + return -EINVAL; 205 + } 206 + 207 + return msb | lsb; 208 + } 209 + 210 + 211 + static ssize_t __da9052_read_tsi(struct device *dev, int channel) 212 + { 213 + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); 214 + int ret; 215 + 216 + reinit_completion(&hwmon->tsidone); 217 + 218 + ret = da9052_request_tsi_read(hwmon, channel); 219 + if (ret < 0) 220 + return ret; 221 + 222 + /* Wait for an conversion done interrupt */ 223 + if (!wait_for_completion_timeout(&hwmon->tsidone, 224 + msecs_to_jiffies(500))) 225 + return -ETIMEDOUT; 226 + 227 + return da9052_get_tsi_result(hwmon, channel); 228 + } 229 + 230 + static ssize_t da9052_read_tsi(struct device *dev, 231 + struct device_attribute *devattr, 232 + char *buf) 233 + { 234 + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); 235 + int channel = to_sensor_dev_attr(devattr)->index; 236 + int ret; 237 + 238 + mutex_lock(&hwmon->hwmon_lock); 239 + ret = __da9052_read_tsi(dev, channel); 240 + mutex_unlock(&hwmon->hwmon_lock); 241 + 242 + if (ret < 0) 243 + return ret; 244 + else 245 + return sprintf(buf, "%d\n", input_tsireg_to_mv(hwmon, ret)); 246 + } 247 + 172 248 static ssize_t da9052_read_tjunc(struct device *dev, 173 249 struct device_attribute *devattr, char *buf) 174 250 { ··· 302 196 input_names[to_sensor_dev_attr(devattr)->index]); 303 197 } 304 198 305 - static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL, 199 + static umode_t da9052_channel_is_visible(struct kobject *kobj, 200 + struct attribute *attr, int index) 201 + { 202 + struct device *dev = container_of(kobj, struct device, kobj); 203 + struct da9052_hwmon *hwmon = dev_get_drvdata(dev); 204 + struct device_attribute *dattr = container_of(attr, 205 + struct device_attribute, attr); 206 + struct sensor_device_attribute *sattr = to_sensor_dev_attr(dattr); 207 + 208 + if (!hwmon->tsi_as_adc) { 209 + switch (sattr->index) { 210 + case DA9052_ADC_TSI_XP: 211 + case DA9052_ADC_TSI_YP: 212 + case DA9052_ADC_TSI_XN: 213 + case DA9052_ADC_TSI_YN: 214 + return 0; 215 + } 216 + } 217 + 218 + return attr->mode; 219 + } 220 + 221 + static SENSOR_DEVICE_ATTR(in0_input, 0444, da9052_read_vddout, NULL, 306 222 DA9052_ADC_VDDOUT); 307 - static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, 223 + static SENSOR_DEVICE_ATTR(in0_label, 0444, show_label, NULL, 308 224 DA9052_ADC_VDDOUT); 309 - static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL, 225 + static SENSOR_DEVICE_ATTR(in3_input, 0444, da9052_read_vbat, NULL, 310 226 DA9052_ADC_VBAT); 311 - static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 227 + static SENSOR_DEVICE_ATTR(in3_label, 0444, show_label, NULL, 312 228 DA9052_ADC_VBAT); 313 - static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL, 229 + static SENSOR_DEVICE_ATTR(in4_input, 0444, da9052_read_misc_channel, NULL, 314 230 DA9052_ADC_IN4); 315 - static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, 231 + static SENSOR_DEVICE_ATTR(in4_label, 0444, show_label, NULL, 316 232 DA9052_ADC_IN4); 317 - static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL, 233 + static SENSOR_DEVICE_ATTR(in5_input, 0444, da9052_read_misc_channel, NULL, 318 234 DA9052_ADC_IN5); 319 - static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, 235 + static SENSOR_DEVICE_ATTR(in5_label, 0444, show_label, NULL, 320 236 DA9052_ADC_IN5); 321 - static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL, 237 + static SENSOR_DEVICE_ATTR(in6_input, 0444, da9052_read_misc_channel, NULL, 322 238 DA9052_ADC_IN6); 323 - static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, 239 + static SENSOR_DEVICE_ATTR(in6_label, 0444, show_label, NULL, 324 240 DA9052_ADC_IN6); 325 - static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL, 241 + static SENSOR_DEVICE_ATTR(in9_input, 0444, da9052_read_vbbat, NULL, 326 242 DA9052_ADC_VBBAT); 327 - static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 243 + static SENSOR_DEVICE_ATTR(in9_label, 0444, show_label, NULL, 328 244 DA9052_ADC_VBBAT); 329 245 330 - static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL, 246 + static SENSOR_DEVICE_ATTR(in70_input, 0444, da9052_read_tsi, NULL, 247 + DA9052_ADC_TSI_XP); 248 + static SENSOR_DEVICE_ATTR(in70_label, 0444, show_label, NULL, 249 + DA9052_ADC_TSI_XP); 250 + static SENSOR_DEVICE_ATTR(in71_input, 0444, da9052_read_tsi, NULL, 251 + DA9052_ADC_TSI_XN); 252 + static SENSOR_DEVICE_ATTR(in71_label, 0444, show_label, NULL, 253 + DA9052_ADC_TSI_XN); 254 + static SENSOR_DEVICE_ATTR(in72_input, 0444, da9052_read_tsi, NULL, 255 + DA9052_ADC_TSI_YP); 256 + static SENSOR_DEVICE_ATTR(in72_label, 0444, show_label, NULL, 257 + DA9052_ADC_TSI_YP); 258 + static SENSOR_DEVICE_ATTR(in73_input, 0444, da9052_read_tsi, NULL, 259 + DA9052_ADC_TSI_YN); 260 + static SENSOR_DEVICE_ATTR(in73_label, 0444, show_label, NULL, 261 + DA9052_ADC_TSI_YN); 262 + 263 + static SENSOR_DEVICE_ATTR(curr1_input, 0444, da9052_read_ich, NULL, 331 264 DA9052_ADC_ICH); 332 - static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL, 265 + static SENSOR_DEVICE_ATTR(curr1_label, 0444, show_label, NULL, 333 266 DA9052_ADC_ICH); 334 267 335 - static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL, 268 + static SENSOR_DEVICE_ATTR(temp2_input, 0444, da9052_read_tbat, NULL, 336 269 DA9052_ADC_TBAT); 337 - static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, 270 + static SENSOR_DEVICE_ATTR(temp2_label, 0444, show_label, NULL, 338 271 DA9052_ADC_TBAT); 339 - static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL, 272 + static SENSOR_DEVICE_ATTR(temp8_input, 0444, da9052_read_tjunc, NULL, 340 273 DA9052_ADC_TJUNC); 341 - static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL, 274 + static SENSOR_DEVICE_ATTR(temp8_label, 0444, show_label, NULL, 342 275 DA9052_ADC_TJUNC); 343 276 344 277 static struct attribute *da9052_attrs[] = { ··· 391 246 &sensor_dev_attr_in5_label.dev_attr.attr, 392 247 &sensor_dev_attr_in6_input.dev_attr.attr, 393 248 &sensor_dev_attr_in6_label.dev_attr.attr, 249 + &sensor_dev_attr_in70_input.dev_attr.attr, 250 + &sensor_dev_attr_in70_label.dev_attr.attr, 251 + &sensor_dev_attr_in71_input.dev_attr.attr, 252 + &sensor_dev_attr_in71_label.dev_attr.attr, 253 + &sensor_dev_attr_in72_input.dev_attr.attr, 254 + &sensor_dev_attr_in72_label.dev_attr.attr, 255 + &sensor_dev_attr_in73_input.dev_attr.attr, 256 + &sensor_dev_attr_in73_label.dev_attr.attr, 394 257 &sensor_dev_attr_in9_input.dev_attr.attr, 395 258 &sensor_dev_attr_in9_label.dev_attr.attr, 396 259 &sensor_dev_attr_curr1_input.dev_attr.attr, ··· 410 257 NULL 411 258 }; 412 259 413 - ATTRIBUTE_GROUPS(da9052); 260 + static const struct attribute_group da9052_group = { 261 + .attrs = da9052_attrs, 262 + .is_visible = da9052_channel_is_visible, 263 + }; 264 + __ATTRIBUTE_GROUPS(da9052); 265 + 266 + static irqreturn_t da9052_tsi_datardy_irq(int irq, void *data) 267 + { 268 + struct da9052_hwmon *hwmon = data; 269 + 270 + complete(&hwmon->tsidone); 271 + return IRQ_HANDLED; 272 + } 414 273 415 274 static int da9052_hwmon_probe(struct platform_device *pdev) 416 275 { 417 276 struct device *dev = &pdev->dev; 418 277 struct da9052_hwmon *hwmon; 419 278 struct device *hwmon_dev; 279 + int err; 420 280 421 281 hwmon = devm_kzalloc(dev, sizeof(struct da9052_hwmon), GFP_KERNEL); 422 282 if (!hwmon) 423 283 return -ENOMEM; 424 284 285 + platform_set_drvdata(pdev, hwmon); 286 + 425 287 mutex_init(&hwmon->hwmon_lock); 426 288 hwmon->da9052 = dev_get_drvdata(pdev->dev.parent); 289 + 290 + init_completion(&hwmon->tsidone); 291 + 292 + hwmon->tsi_as_adc = 293 + device_property_read_bool(pdev->dev.parent, "dlg,tsi-as-adc"); 294 + 295 + if (hwmon->tsi_as_adc) { 296 + hwmon->tsiref = devm_regulator_get(pdev->dev.parent, "tsiref"); 297 + if (IS_ERR(hwmon->tsiref)) { 298 + err = PTR_ERR(hwmon->tsiref); 299 + dev_err(&pdev->dev, "failed to get tsiref: %d", err); 300 + return err; 301 + } 302 + 303 + err = regulator_enable(hwmon->tsiref); 304 + if (err) 305 + return err; 306 + 307 + hwmon->tsiref_mv = regulator_get_voltage(hwmon->tsiref); 308 + if (hwmon->tsiref_mv < 0) { 309 + err = hwmon->tsiref_mv; 310 + goto exit_regulator; 311 + } 312 + 313 + /* convert from microvolt (DT) to millivolt (hwmon) */ 314 + hwmon->tsiref_mv /= 1000; 315 + 316 + /* TSIREF limits from datasheet */ 317 + if (hwmon->tsiref_mv < 1800 || hwmon->tsiref_mv > 2600) { 318 + dev_err(hwmon->da9052->dev, "invalid TSIREF voltage: %d", 319 + hwmon->tsiref_mv); 320 + err = -ENXIO; 321 + goto exit_regulator; 322 + } 323 + 324 + /* disable touchscreen features */ 325 + da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00); 326 + 327 + err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, 328 + "tsiready-irq", da9052_tsi_datardy_irq, 329 + hwmon); 330 + if (err) { 331 + dev_err(&pdev->dev, "Failed to register TSIRDY IRQ: %d", 332 + err); 333 + goto exit_regulator; 334 + } 335 + } 427 336 428 337 hwmon_dev = devm_hwmon_device_register_with_groups(dev, "da9052", 429 338 hwmon, 430 339 da9052_groups); 431 - return PTR_ERR_OR_ZERO(hwmon_dev); 340 + err = PTR_ERR_OR_ZERO(hwmon_dev); 341 + if (err) 342 + goto exit_irq; 343 + 344 + return 0; 345 + 346 + exit_irq: 347 + if (hwmon->tsi_as_adc) 348 + da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon); 349 + exit_regulator: 350 + if (hwmon->tsiref) 351 + regulator_disable(hwmon->tsiref); 352 + 353 + return err; 354 + } 355 + 356 + static int da9052_hwmon_remove(struct platform_device *pdev) 357 + { 358 + struct da9052_hwmon *hwmon = platform_get_drvdata(pdev); 359 + 360 + if (hwmon->tsi_as_adc) { 361 + da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon); 362 + regulator_disable(hwmon->tsiref); 363 + } 364 + 365 + return 0; 432 366 } 433 367 434 368 static struct platform_driver da9052_hwmon_driver = { 435 369 .probe = da9052_hwmon_probe, 370 + .remove = da9052_hwmon_remove, 436 371 .driver = { 437 372 .name = "da9052-hwmon", 438 373 },
+23 -3
drivers/mfd/da9052-core.c
··· 18 18 #include <linux/mfd/core.h> 19 19 #include <linux/slab.h> 20 20 #include <linux/module.h> 21 + #include <linux/property.h> 21 22 22 23 #include <linux/mfd/da9052/da9052.h> 23 24 #include <linux/mfd/da9052/pdata.h> ··· 520 519 .name = "da9052-wled3", 521 520 }, 522 521 { 523 - .name = "da9052-tsi", 524 - }, 525 - { 526 522 .name = "da9052-bat", 527 523 }, 528 524 { 529 525 .name = "da9052-watchdog", 530 526 }, 527 + }; 528 + 529 + static const struct mfd_cell da9052_tsi_subdev_info[] = { 530 + { .name = "da9052-tsi" }, 531 531 }; 532 532 533 533 const struct regmap_config da9052_regmap_config = { ··· 621 619 goto err; 622 620 } 623 621 622 + /* 623 + * Check if touchscreen pins are used are analogue input instead 624 + * of having a touchscreen connected to them. The analogue input 625 + * functionality will be provided by hwmon driver (if enabled). 626 + */ 627 + if (!device_property_read_bool(da9052->dev, "dlg,tsi-as-adc")) { 628 + ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO, 629 + da9052_tsi_subdev_info, 630 + ARRAY_SIZE(da9052_tsi_subdev_info), 631 + NULL, 0, NULL); 632 + if (ret) { 633 + dev_err(da9052->dev, "failed to add TSI subdev: %d\n", 634 + ret); 635 + goto err; 636 + } 637 + } 638 + 624 639 return 0; 625 640 626 641 err: 642 + mfd_remove_devices(da9052->dev); 627 643 da9052_irq_exit(da9052); 628 644 629 645 return ret;
+6
include/linux/mfd/da9052/da9052.h
··· 45 45 #define DA9052_ADC_TJUNC 8 46 46 #define DA9052_ADC_VBBAT 9 47 47 48 + /* TSI channel has its own 4 channel mux */ 49 + #define DA9052_ADC_TSI_XP 70 50 + #define DA9052_ADC_TSI_XN 71 51 + #define DA9052_ADC_TSI_YP 72 52 + #define DA9052_ADC_TSI_YN 73 53 + 48 54 #define DA9052_IRQ_DCIN 0 49 55 #define DA9052_IRQ_VBUS 1 50 56 #define DA9052_IRQ_DCINREM 2
+10 -1
include/linux/mfd/da9052/reg.h
··· 690 690 /* TSI CONTROL REGISTER B BITS */ 691 691 #define DA9052_TSICONTB_ADCREF 0X80 692 692 #define DA9052_TSICONTB_TSIMAN 0X40 693 - #define DA9052_TSICONTB_TSIMUX 0X30 693 + #define DA9052_TSICONTB_TSIMUX_XP 0X00 694 + #define DA9052_TSICONTB_TSIMUX_YP 0X10 695 + #define DA9052_TSICONTB_TSIMUX_XN 0X20 696 + #define DA9052_TSICONTB_TSIMUX_YN 0X30 694 697 #define DA9052_TSICONTB_TSISEL3 0X08 695 698 #define DA9052_TSICONTB_TSISEL2 0X04 696 699 #define DA9052_TSICONTB_TSISEL1 0X02 ··· 708 705 /* TSI CO-ORDINATE LSB RESULT REGISTER BITS */ 709 706 #define DA9052_TSILSB_PENDOWN 0X40 710 707 #define DA9052_TSILSB_TSIZL 0X30 708 + #define DA9052_TSILSB_TSIZL_SHIFT 4 709 + #define DA9052_TSILSB_TSIZL_BITS 2 711 710 #define DA9052_TSILSB_TSIYL 0X0C 711 + #define DA9052_TSILSB_TSIYL_SHIFT 2 712 + #define DA9052_TSILSB_TSIYL_BITS 2 712 713 #define DA9052_TSILSB_TSIXL 0X03 714 + #define DA9052_TSILSB_TSIXL_SHIFT 0 715 + #define DA9052_TSILSB_TSIXL_BITS 2 713 716 714 717 /* TSI Z MEASUREMENT MSB RESULT REGISTER BIT */ 715 718 #define DA9052_TSIZMSB_TSIZM 0XFF