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