1/** 2 * drivers/gpio/max7301.c 3 * 4 * Copyright (C) 2006 Juergen Beisert, Pengutronix 5 * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix 6 * Copyright (C) 2009 Wolfram Sang, Pengutronix 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * The Maxim MAX7300/1 device is an I2C/SPI driven GPIO expander. There are 13 * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more 14 * details 15 * Note: 16 * - DIN must be stable at the rising edge of clock. 17 * - when writing: 18 * - always clock in 16 clocks at once 19 * - at DIN: D15 first, D0 last 20 * - D0..D7 = databyte, D8..D14 = commandbyte 21 * - D15 = low -> write command 22 * - when reading 23 * - always clock in 16 clocks at once 24 * - at DIN: D15 first, D0 last 25 * - D0..D7 = dummy, D8..D14 = register address 26 * - D15 = high -> read command 27 * - raise CS and assert it again 28 * - always clock in 16 clocks at once 29 * - at DOUT: D15 first, D0 last 30 * - D0..D7 contains the data from the first cycle 31 * 32 * The driver exports a standard gpiochip interface 33 */ 34 35#include <linux/module.h> 36#include <linux/init.h> 37#include <linux/platform_device.h> 38#include <linux/mutex.h> 39#include <linux/spi/max7301.h> 40#include <linux/gpio.h> 41#include <linux/slab.h> 42 43/* 44 * Pin configurations, see MAX7301 datasheet page 6 45 */ 46#define PIN_CONFIG_MASK 0x03 47#define PIN_CONFIG_IN_PULLUP 0x03 48#define PIN_CONFIG_IN_WO_PULLUP 0x02 49#define PIN_CONFIG_OUT 0x01 50 51#define PIN_NUMBER 28 52 53static int max7301_direction_input(struct gpio_chip *chip, unsigned offset) 54{ 55 struct max7301 *ts = container_of(chip, struct max7301, chip); 56 u8 *config; 57 u8 offset_bits, pin_config; 58 int ret; 59 60 /* First 4 pins are unused in the controller */ 61 offset += 4; 62 offset_bits = (offset & 3) << 1; 63 64 config = &ts->port_config[offset >> 2]; 65 66 if (ts->input_pullup_active & BIT(offset)) 67 pin_config = PIN_CONFIG_IN_PULLUP; 68 else 69 pin_config = PIN_CONFIG_IN_WO_PULLUP; 70 71 mutex_lock(&ts->lock); 72 73 *config = (*config & ~(PIN_CONFIG_MASK << offset_bits)) 74 | (pin_config << offset_bits); 75 76 ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config); 77 78 mutex_unlock(&ts->lock); 79 80 return ret; 81} 82 83static int __max7301_set(struct max7301 *ts, unsigned offset, int value) 84{ 85 if (value) { 86 ts->out_level |= 1 << offset; 87 return ts->write(ts->dev, 0x20 + offset, 0x01); 88 } else { 89 ts->out_level &= ~(1 << offset); 90 return ts->write(ts->dev, 0x20 + offset, 0x00); 91 } 92} 93 94static int max7301_direction_output(struct gpio_chip *chip, unsigned offset, 95 int value) 96{ 97 struct max7301 *ts = container_of(chip, struct max7301, chip); 98 u8 *config; 99 u8 offset_bits; 100 int ret; 101 102 /* First 4 pins are unused in the controller */ 103 offset += 4; 104 offset_bits = (offset & 3) << 1; 105 106 config = &ts->port_config[offset >> 2]; 107 108 mutex_lock(&ts->lock); 109 110 *config = (*config & ~(PIN_CONFIG_MASK << offset_bits)) 111 | (PIN_CONFIG_OUT << offset_bits); 112 113 ret = __max7301_set(ts, offset, value); 114 115 if (!ret) 116 ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config); 117 118 mutex_unlock(&ts->lock); 119 120 return ret; 121} 122 123static int max7301_get(struct gpio_chip *chip, unsigned offset) 124{ 125 struct max7301 *ts = container_of(chip, struct max7301, chip); 126 int config, level = -EINVAL; 127 128 /* First 4 pins are unused in the controller */ 129 offset += 4; 130 131 mutex_lock(&ts->lock); 132 133 config = (ts->port_config[offset >> 2] >> ((offset & 3) << 1)) 134 & PIN_CONFIG_MASK; 135 136 switch (config) { 137 case PIN_CONFIG_OUT: 138 /* Output: return cached level */ 139 level = !!(ts->out_level & (1 << offset)); 140 break; 141 case PIN_CONFIG_IN_WO_PULLUP: 142 case PIN_CONFIG_IN_PULLUP: 143 /* Input: read out */ 144 level = ts->read(ts->dev, 0x20 + offset) & 0x01; 145 } 146 mutex_unlock(&ts->lock); 147 148 return level; 149} 150 151static void max7301_set(struct gpio_chip *chip, unsigned offset, int value) 152{ 153 struct max7301 *ts = container_of(chip, struct max7301, chip); 154 155 /* First 4 pins are unused in the controller */ 156 offset += 4; 157 158 mutex_lock(&ts->lock); 159 160 __max7301_set(ts, offset, value); 161 162 mutex_unlock(&ts->lock); 163} 164 165int __devinit __max730x_probe(struct max7301 *ts) 166{ 167 struct device *dev = ts->dev; 168 struct max7301_platform_data *pdata; 169 int i, ret; 170 171 pdata = dev->platform_data; 172 if (!pdata || !pdata->base) { 173 dev_err(dev, "incorrect or missing platform data\n"); 174 return -EINVAL; 175 } 176 177 mutex_init(&ts->lock); 178 dev_set_drvdata(dev, ts); 179 180 /* Power up the chip and disable IRQ output */ 181 ts->write(dev, 0x04, 0x01); 182 183 ts->input_pullup_active = pdata->input_pullup_active; 184 ts->chip.label = dev->driver->name; 185 186 ts->chip.direction_input = max7301_direction_input; 187 ts->chip.get = max7301_get; 188 ts->chip.direction_output = max7301_direction_output; 189 ts->chip.set = max7301_set; 190 191 ts->chip.base = pdata->base; 192 ts->chip.ngpio = PIN_NUMBER; 193 ts->chip.can_sleep = 1; 194 ts->chip.dev = dev; 195 ts->chip.owner = THIS_MODULE; 196 197 /* 198 * initialize pullups according to platform data and cache the 199 * register values for later use. 200 */ 201 for (i = 1; i < 8; i++) { 202 int j; 203 /* 204 * initialize port_config with "0xAA", which means 205 * input with internal pullup disabled. This is needed 206 * to avoid writing zeros (in the inner for loop), 207 * which is not allowed according to the datasheet. 208 */ 209 ts->port_config[i] = 0xAA; 210 for (j = 0; j < 4; j++) { 211 int offset = (i - 1) * 4 + j; 212 ret = max7301_direction_input(&ts->chip, offset); 213 if (ret) 214 goto exit_destroy; 215 } 216 } 217 218 ret = gpiochip_add(&ts->chip); 219 if (ret) 220 goto exit_destroy; 221 222 return ret; 223 224exit_destroy: 225 dev_set_drvdata(dev, NULL); 226 mutex_destroy(&ts->lock); 227 return ret; 228} 229EXPORT_SYMBOL_GPL(__max730x_probe); 230 231int __devexit __max730x_remove(struct device *dev) 232{ 233 struct max7301 *ts = dev_get_drvdata(dev); 234 int ret; 235 236 if (ts == NULL) 237 return -ENODEV; 238 239 dev_set_drvdata(dev, NULL); 240 241 /* Power down the chip and disable IRQ output */ 242 ts->write(dev, 0x04, 0x00); 243 244 ret = gpiochip_remove(&ts->chip); 245 if (!ret) { 246 mutex_destroy(&ts->lock); 247 kfree(ts); 248 } else 249 dev_err(dev, "Failed to remove GPIO controller: %d\n", ret); 250 251 return ret; 252} 253EXPORT_SYMBOL_GPL(__max730x_remove); 254 255MODULE_AUTHOR("Juergen Beisert, Wolfram Sang"); 256MODULE_LICENSE("GPL v2"); 257MODULE_DESCRIPTION("MAX730x GPIO-Expanders, generic parts"); 258