1 /* 2 * GPIO driver for RICOH583 power management chip. 3 * 4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5 * Author: Laxman dewangan <ldewangan@nvidia.com> 6 * 7 * Based on code 8 * Copyright (C) 2011 RICOH COMPANY,LTD 9 * 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. 13 * 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 17 * more details. 18 * 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/>. 21 * 22 */ 23 #include <linux/init.h> 24 #include <linux/kernel.h> 25 #include <linux/slab.h> 26 #include <linux/platform_device.h> 27 #include <linux/device.h> 28 #include <linux/gpio.h> 29 #include <linux/mfd/rc5t583.h> 30 31 struct rc5t583_gpio { 32 struct gpio_chip gpio_chip; 33 struct rc5t583 *rc5t583; 34 }; 35 36 static int rc5t583_gpio_get(struct gpio_chip *gc, unsigned int offset) 37 { 38 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 39 struct device *parent = rc5t583_gpio->rc5t583->dev; 40 uint8_t val = 0; 41 int ret; 42 43 ret = rc5t583_read(parent, RC5T583_GPIO_MON_IOIN, &val); 44 if (ret < 0) 45 return ret; 46 47 return !!(val & BIT(offset)); 48 } 49 50 static void rc5t583_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) 51 { 52 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 53 struct device *parent = rc5t583_gpio->rc5t583->dev; 54 if (val) 55 rc5t583_set_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset)); 56 else 57 rc5t583_clear_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset)); 58 } 59 60 static int rc5t583_gpio_dir_input(struct gpio_chip *gc, unsigned int offset) 61 { 62 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 63 struct device *parent = rc5t583_gpio->rc5t583->dev; 64 int ret; 65 66 ret = rc5t583_clear_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset)); 67 if (ret < 0) 68 return ret; 69 70 /* Set pin to gpio mode */ 71 return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); 72 } 73 74 static int rc5t583_gpio_dir_output(struct gpio_chip *gc, unsigned offset, 75 int value) 76 { 77 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 78 struct device *parent = rc5t583_gpio->rc5t583->dev; 79 int ret; 80 81 rc5t583_gpio_set(gc, offset, value); 82 ret = rc5t583_set_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset)); 83 if (ret < 0) 84 return ret; 85 86 /* Set pin to gpio mode */ 87 return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); 88 } 89 90 static int rc5t583_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 91 { 92 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 93 94 if (offset < RC5T583_MAX_GPIO) 95 return rc5t583_gpio->rc5t583->irq_base + 96 RC5T583_IRQ_GPIO0 + offset; 97 return -EINVAL; 98 } 99 100 static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset) 101 { 102 struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc); 103 struct device *parent = rc5t583_gpio->rc5t583->dev; 104 105 rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset)); 106 } 107 108 static int rc5t583_gpio_probe(struct platform_device *pdev) 109 { 110 struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); 111 struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); 112 struct rc5t583_gpio *rc5t583_gpio; 113 114 rc5t583_gpio = devm_kzalloc(&pdev->dev, sizeof(*rc5t583_gpio), 115 GFP_KERNEL); 116 if (!rc5t583_gpio) 117 return -ENOMEM; 118 119 rc5t583_gpio->gpio_chip.label = "gpio-rc5t583", 120 rc5t583_gpio->gpio_chip.owner = THIS_MODULE, 121 rc5t583_gpio->gpio_chip.free = rc5t583_gpio_free, 122 rc5t583_gpio->gpio_chip.direction_input = rc5t583_gpio_dir_input, 123 rc5t583_gpio->gpio_chip.direction_output = rc5t583_gpio_dir_output, 124 rc5t583_gpio->gpio_chip.set = rc5t583_gpio_set, 125 rc5t583_gpio->gpio_chip.get = rc5t583_gpio_get, 126 rc5t583_gpio->gpio_chip.to_irq = rc5t583_gpio_to_irq, 127 rc5t583_gpio->gpio_chip.ngpio = RC5T583_MAX_GPIO, 128 rc5t583_gpio->gpio_chip.can_sleep = true, 129 rc5t583_gpio->gpio_chip.parent = &pdev->dev; 130 rc5t583_gpio->gpio_chip.base = -1; 131 rc5t583_gpio->rc5t583 = rc5t583; 132 133 if (pdata && pdata->gpio_base) 134 rc5t583_gpio->gpio_chip.base = pdata->gpio_base; 135 136 platform_set_drvdata(pdev, rc5t583_gpio); 137 138 return devm_gpiochip_add_data(&pdev->dev, &rc5t583_gpio->gpio_chip, 139 rc5t583_gpio); 140 } 141 142 static struct platform_driver rc5t583_gpio_driver = { 143 .driver = { 144 .name = "rc5t583-gpio", 145 }, 146 .probe = rc5t583_gpio_probe, 147 }; 148 149 static int __init rc5t583_gpio_init(void) 150 { 151 return platform_driver_register(&rc5t583_gpio_driver); 152 } 153 subsys_initcall(rc5t583_gpio_init); 154