1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * linux/drivers/mfd/ucb1x00-assabet.c 4 * 5 * Copyright (C) 2001-2003 Russell King, All Rights Reserved. 6 * 7 * We handle the machine-specific bits of the UCB1x00 driver here. 8 */ 9 #include <linux/module.h> 10 #include <linux/init.h> 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/fs.h> 14 #include <linux/gpio_keys.h> 15 #include <linux/input.h> 16 #include <linux/platform_device.h> 17 #include <linux/proc_fs.h> 18 #include <linux/mfd/ucb1x00.h> 19 20 #define UCB1X00_ATTR(name,input)\ 21 static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ 22 char *buf) \ 23 { \ 24 struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ 25 int val; \ 26 ucb1x00_adc_enable(ucb); \ 27 val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \ 28 ucb1x00_adc_disable(ucb); \ 29 return sprintf(buf, "%d\n", val); \ 30 } \ 31 static DEVICE_ATTR(name,0444,name##_show,NULL) 32 33 UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); 34 UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); 35 UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); 36 37 static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) 38 { 39 struct ucb1x00 *ucb = dev->ucb; 40 struct platform_device *pdev; 41 struct gpio_keys_platform_data keys; 42 static struct gpio_keys_button buttons[6]; 43 unsigned i; 44 45 memset(buttons, 0, sizeof(buttons)); 46 memset(&keys, 0, sizeof(keys)); 47 48 for (i = 0; i < ARRAY_SIZE(buttons); i++) { 49 buttons[i].code = BTN_0 + i; 50 buttons[i].gpio = ucb->gpio.base + i; 51 buttons[i].type = EV_KEY; 52 buttons[i].can_disable = true; 53 } 54 55 keys.buttons = buttons; 56 keys.nbuttons = ARRAY_SIZE(buttons); 57 keys.poll_interval = 50; 58 keys.name = "ucb1x00"; 59 60 pdev = platform_device_register_data(&ucb->dev, "gpio-keys", -1, 61 &keys, sizeof(keys)); 62 63 device_create_file(&ucb->dev, &dev_attr_vbatt); 64 device_create_file(&ucb->dev, &dev_attr_vcharger); 65 device_create_file(&ucb->dev, &dev_attr_batt_temp); 66 67 dev->priv = pdev; 68 return 0; 69 } 70 71 static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) 72 { 73 struct platform_device *pdev = dev->priv; 74 75 if (!IS_ERR(pdev)) 76 platform_device_unregister(pdev); 77 78 device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); 79 device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); 80 device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); 81 } 82 83 static struct ucb1x00_driver ucb1x00_assabet_driver = { 84 .add = ucb1x00_assabet_add, 85 .remove = ucb1x00_assabet_remove, 86 }; 87 88 static int __init ucb1x00_assabet_init(void) 89 { 90 return ucb1x00_register_driver(&ucb1x00_assabet_driver); 91 } 92 93 static void __exit ucb1x00_assabet_exit(void) 94 { 95 ucb1x00_unregister_driver(&ucb1x00_assabet_driver); 96 } 97 98 module_init(ucb1x00_assabet_init); 99 module_exit(ucb1x00_assabet_exit); 100 101 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 102 MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); 103 MODULE_LICENSE("GPL"); 104