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)\ 24static 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} \ 34static DEVICE_ATTR(name,0444,name##_show,NULL) 35 36UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); 37UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); 38UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); 39 40static 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 74static 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 86static struct ucb1x00_driver ucb1x00_assabet_driver = { 87 .add = ucb1x00_assabet_add, 88 .remove = ucb1x00_assabet_remove, 89}; 90 91static int __init ucb1x00_assabet_init(void) 92{ 93 return ucb1x00_register_driver(&ucb1x00_assabet_driver); 94} 95 96static void __exit ucb1x00_assabet_exit(void) 97{ 98 ucb1x00_unregister_driver(&ucb1x00_assabet_driver); 99} 100 101module_init(ucb1x00_assabet_init); 102module_exit(ucb1x00_assabet_exit); 103 104MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 105MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); 106MODULE_LICENSE("GPL"); 107