2 * GPIO driver for RICOH583 power management chip.
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 * Author: Laxman dewangan <ldewangan@nvidia.com>
8 * Copyright (C) 2011 RICOH COMPANY,LTD
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/slab.h>
26 #include <linux/module.h>
27 #include <linux/platform_device.h>
28 #include <linux/device.h>
29 #include <linux/gpio.h>
30 #include <linux/mfd/rc5t583.h>
33 struct gpio_chip gpio_chip
;
34 struct rc5t583
*rc5t583
;
37 static inline struct rc5t583_gpio
*to_rc5t583_gpio(struct gpio_chip
*chip
)
39 return container_of(chip
, struct rc5t583_gpio
, gpio_chip
);
42 static int rc5t583_gpio_get(struct gpio_chip
*gc
, unsigned int offset
)
44 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
45 struct device
*parent
= rc5t583_gpio
->rc5t583
->dev
;
49 ret
= rc5t583_read(parent
, RC5T583_GPIO_MON_IOIN
, &val
);
53 return !!(val
& BIT(offset
));
56 static void rc5t583_gpio_set(struct gpio_chip
*gc
, unsigned int offset
, int val
)
58 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
59 struct device
*parent
= rc5t583_gpio
->rc5t583
->dev
;
61 rc5t583_set_bits(parent
, RC5T583_GPIO_IOOUT
, BIT(offset
));
63 rc5t583_clear_bits(parent
, RC5T583_GPIO_IOOUT
, BIT(offset
));
66 static int rc5t583_gpio_dir_input(struct gpio_chip
*gc
, unsigned int offset
)
68 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
69 struct device
*parent
= rc5t583_gpio
->rc5t583
->dev
;
72 ret
= rc5t583_clear_bits(parent
, RC5T583_GPIO_IOSEL
, BIT(offset
));
76 /* Set pin to gpio mode */
77 return rc5t583_clear_bits(parent
, RC5T583_GPIO_PGSEL
, BIT(offset
));
80 static int rc5t583_gpio_dir_output(struct gpio_chip
*gc
, unsigned offset
,
83 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
84 struct device
*parent
= rc5t583_gpio
->rc5t583
->dev
;
87 rc5t583_gpio_set(gc
, offset
, value
);
88 ret
= rc5t583_set_bits(parent
, RC5T583_GPIO_IOSEL
, BIT(offset
));
92 /* Set pin to gpio mode */
93 return rc5t583_clear_bits(parent
, RC5T583_GPIO_PGSEL
, BIT(offset
));
96 static int rc5t583_gpio_to_irq(struct gpio_chip
*gc
, unsigned offset
)
98 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
100 if (offset
< RC5T583_MAX_GPIO
)
101 return rc5t583_gpio
->rc5t583
->irq_base
+
102 RC5T583_IRQ_GPIO0
+ offset
;
106 static void rc5t583_gpio_free(struct gpio_chip
*gc
, unsigned offset
)
108 struct rc5t583_gpio
*rc5t583_gpio
= to_rc5t583_gpio(gc
);
109 struct device
*parent
= rc5t583_gpio
->rc5t583
->dev
;
111 rc5t583_set_bits(parent
, RC5T583_GPIO_PGSEL
, BIT(offset
));
114 static int rc5t583_gpio_probe(struct platform_device
*pdev
)
116 struct rc5t583
*rc5t583
= dev_get_drvdata(pdev
->dev
.parent
);
117 struct rc5t583_platform_data
*pdata
= dev_get_platdata(rc5t583
->dev
);
118 struct rc5t583_gpio
*rc5t583_gpio
;
120 rc5t583_gpio
= devm_kzalloc(&pdev
->dev
, sizeof(*rc5t583_gpio
),
123 dev_warn(&pdev
->dev
, "Mem allocation for rc5t583_gpio failed");
127 rc5t583_gpio
->gpio_chip
.label
= "gpio-rc5t583",
128 rc5t583_gpio
->gpio_chip
.owner
= THIS_MODULE
,
129 rc5t583_gpio
->gpio_chip
.free
= rc5t583_gpio_free
,
130 rc5t583_gpio
->gpio_chip
.direction_input
= rc5t583_gpio_dir_input
,
131 rc5t583_gpio
->gpio_chip
.direction_output
= rc5t583_gpio_dir_output
,
132 rc5t583_gpio
->gpio_chip
.set
= rc5t583_gpio_set
,
133 rc5t583_gpio
->gpio_chip
.get
= rc5t583_gpio_get
,
134 rc5t583_gpio
->gpio_chip
.to_irq
= rc5t583_gpio_to_irq
,
135 rc5t583_gpio
->gpio_chip
.ngpio
= RC5T583_MAX_GPIO
,
136 rc5t583_gpio
->gpio_chip
.can_sleep
= true,
137 rc5t583_gpio
->gpio_chip
.dev
= &pdev
->dev
;
138 rc5t583_gpio
->gpio_chip
.base
= -1;
139 rc5t583_gpio
->rc5t583
= rc5t583
;
141 if (pdata
&& pdata
->gpio_base
)
142 rc5t583_gpio
->gpio_chip
.base
= pdata
->gpio_base
;
144 platform_set_drvdata(pdev
, rc5t583_gpio
);
146 return gpiochip_add(&rc5t583_gpio
->gpio_chip
);
149 static int rc5t583_gpio_remove(struct platform_device
*pdev
)
151 struct rc5t583_gpio
*rc5t583_gpio
= platform_get_drvdata(pdev
);
153 return gpiochip_remove(&rc5t583_gpio
->gpio_chip
);
156 static struct platform_driver rc5t583_gpio_driver
= {
158 .name
= "rc5t583-gpio",
159 .owner
= THIS_MODULE
,
161 .probe
= rc5t583_gpio_probe
,
162 .remove
= rc5t583_gpio_remove
,
165 static int __init
rc5t583_gpio_init(void)
167 return platform_driver_register(&rc5t583_gpio_driver
);
169 subsys_initcall(rc5t583_gpio_init
);
171 static void __exit
rc5t583_gpio_exit(void)
173 platform_driver_unregister(&rc5t583_gpio_driver
);
175 module_exit(rc5t583_gpio_exit
);
177 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
178 MODULE_DESCRIPTION("GPIO interface for RC5T583");
179 MODULE_LICENSE("GPL v2");
180 MODULE_ALIAS("platform:rc5t583-gpio");