pinctrl-mcp23s08.c (64ac43e6fa283f556f0a8f69ad52d6e7d550307d) | pinctrl-mcp23s08.c (82039d244f87b6c47e880b398414da55d4f48e06) |
---|---|
1/* 2 * MCP23S08 SPI/I2C GPIO gpio expander driver 3 * 4 * The inputs and outputs of the mcp23s08, mcp23s17, mcp23008 and mcp23017 are 5 * supported. 6 * For the I2C versions of the chips (mcp23008 and mcp23017) generation of 7 * interrupts is also supported. 8 * The hardware of the SPI versions of the chips (mcp23s08 and mcp23s17) is --- 10 unchanged lines hidden (view full) --- 19#include <linux/spi/spi.h> 20#include <linux/spi/mcp23s08.h> 21#include <linux/slab.h> 22#include <asm/byteorder.h> 23#include <linux/interrupt.h> 24#include <linux/of_irq.h> 25#include <linux/of_device.h> 26#include <linux/regmap.h> | 1/* 2 * MCP23S08 SPI/I2C GPIO gpio expander driver 3 * 4 * The inputs and outputs of the mcp23s08, mcp23s17, mcp23008 and mcp23017 are 5 * supported. 6 * For the I2C versions of the chips (mcp23008 and mcp23017) generation of 7 * interrupts is also supported. 8 * The hardware of the SPI versions of the chips (mcp23s08 and mcp23s17) is --- 10 unchanged lines hidden (view full) --- 19#include <linux/spi/spi.h> 20#include <linux/spi/mcp23s08.h> 21#include <linux/slab.h> 22#include <asm/byteorder.h> 23#include <linux/interrupt.h> 24#include <linux/of_irq.h> 25#include <linux/of_device.h> 26#include <linux/regmap.h> |
27#include <linux/pinctrl/pinctrl.h> 28#include <linux/pinctrl/pinconf.h> 29#include <linux/pinctrl/pinconf-generic.h> |
|
27 28/** 29 * MCP types supported by driver 30 */ 31#define MCP_TYPE_S08 0 32#define MCP_TYPE_S17 1 33#define MCP_TYPE_008 2 34#define MCP_TYPE_017 3 --- 37 unchanged lines hidden (view full) --- 72 /* lock protects the cached values */ 73 struct mutex lock; 74 struct mutex irq_lock; 75 76 struct gpio_chip chip; 77 78 struct regmap *regmap; 79 struct device *dev; | 30 31/** 32 * MCP types supported by driver 33 */ 34#define MCP_TYPE_S08 0 35#define MCP_TYPE_S17 1 36#define MCP_TYPE_008 2 37#define MCP_TYPE_017 3 --- 37 unchanged lines hidden (view full) --- 75 /* lock protects the cached values */ 76 struct mutex lock; 77 struct mutex irq_lock; 78 79 struct gpio_chip chip; 80 81 struct regmap *regmap; 82 struct device *dev; |
83 84 struct pinctrl_dev *pctldev; 85 struct pinctrl_desc pinctrl_desc; |
|
80}; 81 82static const struct regmap_config mcp23x08_regmap = { 83 .reg_bits = 8, 84 .val_bits = 8, 85 86 .reg_stride = 1, 87 .max_register = MCP_OLAT, 88}; 89 90static const struct regmap_config mcp23x17_regmap = { 91 .reg_bits = 8, 92 .val_bits = 16, 93 94 .reg_stride = 2, 95 .max_register = MCP_OLAT << 1, 96 .val_format_endian = REGMAP_ENDIAN_LITTLE, 97}; 98 | 86}; 87 88static const struct regmap_config mcp23x08_regmap = { 89 .reg_bits = 8, 90 .val_bits = 8, 91 92 .reg_stride = 1, 93 .max_register = MCP_OLAT, 94}; 95 96static const struct regmap_config mcp23x17_regmap = { 97 .reg_bits = 8, 98 .val_bits = 16, 99 100 .reg_stride = 2, 101 .max_register = MCP_OLAT << 1, 102 .val_format_endian = REGMAP_ENDIAN_LITTLE, 103}; 104 |
105static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val) 106{ 107 return regmap_read(mcp->regmap, reg << mcp->reg_shift, val); 108} 109 110static int mcp_write(struct mcp23s08 *mcp, unsigned int reg, unsigned int val) 111{ 112 return regmap_write(mcp->regmap, reg << mcp->reg_shift, val); 113} 114 115static int mcp_set_bit(struct mcp23s08 *mcp, unsigned int reg, 116 unsigned int pin, bool enabled) 117{ 118 u16 val = enabled ? 0xffff : 0x0000; 119 u16 mask = BIT(pin); 120 return regmap_update_bits(mcp->regmap, reg << mcp->reg_shift, 121 mask, val); 122} 123 124static int mcp_update_cache(struct mcp23s08 *mcp) 125{ 126 int ret, reg, i; 127 128 for (i = 0; i < ARRAY_SIZE(mcp->cache); i++) { 129 ret = mcp_read(mcp, i, ®); 130 if (ret < 0) 131 return ret; 132 mcp->cache[i] = reg; 133 } 134 135 return 0; 136} 137 138static const struct pinctrl_pin_desc mcp23x08_pins[] = { 139 PINCTRL_PIN(0, "gpio0"), 140 PINCTRL_PIN(1, "gpio1"), 141 PINCTRL_PIN(2, "gpio2"), 142 PINCTRL_PIN(3, "gpio3"), 143 PINCTRL_PIN(4, "gpio4"), 144 PINCTRL_PIN(5, "gpio5"), 145 PINCTRL_PIN(6, "gpio6"), 146 PINCTRL_PIN(7, "gpio7"), 147}; 148 149static const struct pinctrl_pin_desc mcp23x17_pins[] = { 150 PINCTRL_PIN(0, "gpio0"), 151 PINCTRL_PIN(1, "gpio1"), 152 PINCTRL_PIN(2, "gpio2"), 153 PINCTRL_PIN(3, "gpio3"), 154 PINCTRL_PIN(4, "gpio4"), 155 PINCTRL_PIN(5, "gpio5"), 156 PINCTRL_PIN(6, "gpio6"), 157 PINCTRL_PIN(7, "gpio7"), 158 PINCTRL_PIN(8, "gpio8"), 159 PINCTRL_PIN(9, "gpio9"), 160 PINCTRL_PIN(10, "gpio10"), 161 PINCTRL_PIN(11, "gpio11"), 162 PINCTRL_PIN(12, "gpio12"), 163 PINCTRL_PIN(13, "gpio13"), 164 PINCTRL_PIN(14, "gpio14"), 165 PINCTRL_PIN(15, "gpio15"), 166}; 167 168static int mcp_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 169{ 170 return 0; 171} 172 173static const char *mcp_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 174 unsigned int group) 175{ 176 return NULL; 177} 178 179static int mcp_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 180 unsigned int group, 181 const unsigned int **pins, 182 unsigned int *num_pins) 183{ 184 return -ENOTSUPP; 185} 186 187static const struct pinctrl_ops mcp_pinctrl_ops = { 188 .get_groups_count = mcp_pinctrl_get_groups_count, 189 .get_group_name = mcp_pinctrl_get_group_name, 190 .get_group_pins = mcp_pinctrl_get_group_pins, 191#ifdef CONFIG_OF 192 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 193 .dt_free_map = pinconf_generic_dt_free_map, 194#endif 195}; 196 197static int mcp_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 198 unsigned long *config) 199{ 200 struct mcp23s08 *mcp = pinctrl_dev_get_drvdata(pctldev); 201 enum pin_config_param param = pinconf_to_config_param(*config); 202 unsigned int data, status; 203 int ret; 204 205 switch (param) { 206 case PIN_CONFIG_BIAS_PULL_UP: 207 ret = mcp_read(mcp, MCP_GPPU, &data); 208 if (ret < 0) 209 return ret; 210 status = (data & BIT(pin)) ? 1 : 0; 211 break; 212 default: 213 dev_err(mcp->dev, "Invalid config param %04x\n", param); 214 return -ENOTSUPP; 215 } 216 217 *config = 0; 218 219 return status ? 0 : -EINVAL; 220} 221 222static int mcp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 223 unsigned long *configs, unsigned int num_configs) 224{ 225 struct mcp23s08 *mcp = pinctrl_dev_get_drvdata(pctldev); 226 enum pin_config_param param; 227 u32 arg, mask; 228 u16 val; 229 int ret = 0; 230 int i; 231 232 for (i = 0; i < num_configs; i++) { 233 param = pinconf_to_config_param(configs[i]); 234 arg = pinconf_to_config_argument(configs[i]); 235 236 switch (param) { 237 case PIN_CONFIG_BIAS_PULL_UP: 238 val = arg ? 0xFFFF : 0x0000; 239 mask = BIT(pin); 240 ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg); 241 break; 242 default: 243 dev_err(mcp->dev, "Invalid config param %04x\n", param); 244 return -ENOTSUPP; 245 } 246 } 247 248 return ret; 249} 250 251static const struct pinconf_ops mcp_pinconf_ops = { 252 .pin_config_get = mcp_pinconf_get, 253 .pin_config_set = mcp_pinconf_set, 254 .is_generic = true, 255}; 256 |
|
99/*----------------------------------------------------------------------*/ 100 101#ifdef CONFIG_SPI_MASTER 102 103static int mcp23sxx_spi_write(void *context, const void *data, size_t count) 104{ 105 struct mcp23s08 *mcp = context; 106 struct spi_device *spi = to_spi_device(mcp->dev); --- 46 unchanged lines hidden (view full) --- 153static const struct regmap_bus mcp23sxx_spi_regmap = { 154 .write = mcp23sxx_spi_write, 155 .gather_write = mcp23sxx_spi_gather_write, 156 .read = mcp23sxx_spi_read, 157}; 158 159#endif /* CONFIG_SPI_MASTER */ 160 | 257/*----------------------------------------------------------------------*/ 258 259#ifdef CONFIG_SPI_MASTER 260 261static int mcp23sxx_spi_write(void *context, const void *data, size_t count) 262{ 263 struct mcp23s08 *mcp = context; 264 struct spi_device *spi = to_spi_device(mcp->dev); --- 46 unchanged lines hidden (view full) --- 311static const struct regmap_bus mcp23sxx_spi_regmap = { 312 .write = mcp23sxx_spi_write, 313 .gather_write = mcp23sxx_spi_gather_write, 314 .read = mcp23sxx_spi_read, 315}; 316 317#endif /* CONFIG_SPI_MASTER */ 318 |
161static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val) 162{ 163 return regmap_read(mcp->regmap, reg << mcp->reg_shift, val); 164} 165 166static int mcp_write(struct mcp23s08 *mcp, unsigned int reg, unsigned int val) 167{ 168 return regmap_write(mcp->regmap, reg << mcp->reg_shift, val); 169} 170 171static int mcp_update_cache(struct mcp23s08 *mcp) 172{ 173 int ret, reg, i; 174 175 for (i = 0; i < ARRAY_SIZE(mcp->cache); i++) { 176 ret = mcp_read(mcp, i, ®); 177 if (ret < 0) 178 return ret; 179 mcp->cache[i] = reg; 180 } 181 182 return 0; 183} 184 | |
185/*----------------------------------------------------------------------*/ 186 187/* A given spi_device can represent up to eight mcp23sxx chips 188 * sharing the same chipselect but using different addresses 189 * (e.g. chips #0 and #3 might be populated, but not #1 or $2). 190 * Driver data holds all the per-chip data. 191 */ 192struct mcp23s08_driver_data { --- 484 unchanged lines hidden (view full) --- 677 if (ret < 0) 678 goto fail; 679 680 if (mcp->irq && mcp->irq_controller) { 681 ret = mcp23s08_irq_setup(mcp); 682 if (ret) 683 goto fail; 684 } | 319/*----------------------------------------------------------------------*/ 320 321/* A given spi_device can represent up to eight mcp23sxx chips 322 * sharing the same chipselect but using different addresses 323 * (e.g. chips #0 and #3 might be populated, but not #1 or $2). 324 * Driver data holds all the per-chip data. 325 */ 326struct mcp23s08_driver_data { --- 484 unchanged lines hidden (view full) --- 811 if (ret < 0) 812 goto fail; 813 814 if (mcp->irq && mcp->irq_controller) { 815 ret = mcp23s08_irq_setup(mcp); 816 if (ret) 817 goto fail; 818 } |
819 820 mcp->pinctrl_desc.name = "mcp23xxx-pinctrl"; 821 mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops; 822 mcp->pinctrl_desc.confops = &mcp_pinconf_ops; 823 mcp->pinctrl_desc.npins = mcp->chip.ngpio; 824 if (mcp->pinctrl_desc.npins == 8) 825 mcp->pinctrl_desc.pins = mcp23x08_pins; 826 else if (mcp->pinctrl_desc.npins == 16) 827 mcp->pinctrl_desc.pins = mcp23x17_pins; 828 mcp->pinctrl_desc.owner = THIS_MODULE; 829 830 mcp->pctldev = devm_pinctrl_register(dev, &mcp->pinctrl_desc, mcp); 831 if (IS_ERR(mcp->pctldev)) { 832 ret = PTR_ERR(mcp->pctldev); 833 goto fail; 834 } 835 |
|
685fail: 686 if (ret < 0) 687 dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret); 688 return ret; 689} 690 691/*----------------------------------------------------------------------*/ 692 --- 355 unchanged lines hidden --- | 836fail: 837 if (ret < 0) 838 dev_dbg(dev, "can't setup chip %d, --> %d\n", addr, ret); 839 return ret; 840} 841 842/*----------------------------------------------------------------------*/ 843 --- 355 unchanged lines hidden --- |