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