1*9e80f906SNeil Armstrong /* 2*9e80f906SNeil Armstrong * Copyright (c) 2016, BayLibre, SAS. All rights reserved. 3*9e80f906SNeil Armstrong * Author: Neil Armstrong <narmstrong@baylibre.com> 4*9e80f906SNeil Armstrong * 5*9e80f906SNeil Armstrong * Copyright (c) 2010, Code Aurora Forum. All rights reserved. 6*9e80f906SNeil Armstrong * 7*9e80f906SNeil Armstrong * Driver for Semtech SX150X I2C GPIO Expanders 8*9e80f906SNeil Armstrong * 9*9e80f906SNeil Armstrong * Author: Gregory Bean <gbean@codeaurora.org> 10*9e80f906SNeil Armstrong * 11*9e80f906SNeil Armstrong * This program is free software; you can redistribute it and/or modify 12*9e80f906SNeil Armstrong * it under the terms of the GNU General Public License version 2 and 13*9e80f906SNeil Armstrong * only version 2 as published by the Free Software Foundation. 14*9e80f906SNeil Armstrong * 15*9e80f906SNeil Armstrong * This program is distributed in the hope that it will be useful, 16*9e80f906SNeil Armstrong * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*9e80f906SNeil Armstrong * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*9e80f906SNeil Armstrong * GNU General Public License for more details. 19*9e80f906SNeil Armstrong */ 20*9e80f906SNeil Armstrong 21*9e80f906SNeil Armstrong #include <linux/i2c.h> 22*9e80f906SNeil Armstrong #include <linux/init.h> 23*9e80f906SNeil Armstrong #include <linux/interrupt.h> 24*9e80f906SNeil Armstrong #include <linux/irq.h> 25*9e80f906SNeil Armstrong #include <linux/mutex.h> 26*9e80f906SNeil Armstrong #include <linux/slab.h> 27*9e80f906SNeil Armstrong #include <linux/of.h> 28*9e80f906SNeil Armstrong #include <linux/gpio.h> 29*9e80f906SNeil Armstrong #include <linux/pinctrl/machine.h> 30*9e80f906SNeil Armstrong #include <linux/pinctrl/pinconf.h> 31*9e80f906SNeil Armstrong #include <linux/pinctrl/pinctrl.h> 32*9e80f906SNeil Armstrong #include <linux/pinctrl/pinmux.h> 33*9e80f906SNeil Armstrong #include <linux/pinctrl/pinconf-generic.h> 34*9e80f906SNeil Armstrong 35*9e80f906SNeil Armstrong #include "core.h" 36*9e80f906SNeil Armstrong #include "pinconf.h" 37*9e80f906SNeil Armstrong #include "pinctrl-utils.h" 38*9e80f906SNeil Armstrong 39*9e80f906SNeil Armstrong /* The chip models of sx150x */ 40*9e80f906SNeil Armstrong enum { 41*9e80f906SNeil Armstrong SX150X_123 = 0, 42*9e80f906SNeil Armstrong SX150X_456, 43*9e80f906SNeil Armstrong SX150X_789, 44*9e80f906SNeil Armstrong }; 45*9e80f906SNeil Armstrong 46*9e80f906SNeil Armstrong struct sx150x_123_pri { 47*9e80f906SNeil Armstrong u8 reg_pld_mode; 48*9e80f906SNeil Armstrong u8 reg_pld_table0; 49*9e80f906SNeil Armstrong u8 reg_pld_table1; 50*9e80f906SNeil Armstrong u8 reg_pld_table2; 51*9e80f906SNeil Armstrong u8 reg_pld_table3; 52*9e80f906SNeil Armstrong u8 reg_pld_table4; 53*9e80f906SNeil Armstrong u8 reg_advance; 54*9e80f906SNeil Armstrong }; 55*9e80f906SNeil Armstrong 56*9e80f906SNeil Armstrong struct sx150x_456_pri { 57*9e80f906SNeil Armstrong u8 reg_pld_mode; 58*9e80f906SNeil Armstrong u8 reg_pld_table0; 59*9e80f906SNeil Armstrong u8 reg_pld_table1; 60*9e80f906SNeil Armstrong u8 reg_pld_table2; 61*9e80f906SNeil Armstrong u8 reg_pld_table3; 62*9e80f906SNeil Armstrong u8 reg_pld_table4; 63*9e80f906SNeil Armstrong u8 reg_advance; 64*9e80f906SNeil Armstrong }; 65*9e80f906SNeil Armstrong 66*9e80f906SNeil Armstrong struct sx150x_789_pri { 67*9e80f906SNeil Armstrong u8 reg_drain; 68*9e80f906SNeil Armstrong u8 reg_polarity; 69*9e80f906SNeil Armstrong u8 reg_clock; 70*9e80f906SNeil Armstrong u8 reg_misc; 71*9e80f906SNeil Armstrong u8 reg_reset; 72*9e80f906SNeil Armstrong u8 ngpios; 73*9e80f906SNeil Armstrong }; 74*9e80f906SNeil Armstrong 75*9e80f906SNeil Armstrong struct sx150x_device_data { 76*9e80f906SNeil Armstrong u8 model; 77*9e80f906SNeil Armstrong u8 reg_pullup; 78*9e80f906SNeil Armstrong u8 reg_pulldn; 79*9e80f906SNeil Armstrong u8 reg_dir; 80*9e80f906SNeil Armstrong u8 reg_data; 81*9e80f906SNeil Armstrong u8 reg_irq_mask; 82*9e80f906SNeil Armstrong u8 reg_irq_src; 83*9e80f906SNeil Armstrong u8 reg_sense; 84*9e80f906SNeil Armstrong u8 ngpios; 85*9e80f906SNeil Armstrong union { 86*9e80f906SNeil Armstrong struct sx150x_123_pri x123; 87*9e80f906SNeil Armstrong struct sx150x_456_pri x456; 88*9e80f906SNeil Armstrong struct sx150x_789_pri x789; 89*9e80f906SNeil Armstrong } pri; 90*9e80f906SNeil Armstrong const struct pinctrl_pin_desc *pins; 91*9e80f906SNeil Armstrong unsigned int npins; 92*9e80f906SNeil Armstrong }; 93*9e80f906SNeil Armstrong 94*9e80f906SNeil Armstrong struct sx150x_pinctrl { 95*9e80f906SNeil Armstrong struct device *dev; 96*9e80f906SNeil Armstrong struct i2c_client *client; 97*9e80f906SNeil Armstrong struct pinctrl_dev *pctldev; 98*9e80f906SNeil Armstrong struct pinctrl_desc pinctrl_desc; 99*9e80f906SNeil Armstrong struct gpio_chip gpio; 100*9e80f906SNeil Armstrong struct irq_chip irq_chip; 101*9e80f906SNeil Armstrong struct { 102*9e80f906SNeil Armstrong int update; 103*9e80f906SNeil Armstrong u32 sense; 104*9e80f906SNeil Armstrong u32 masked; 105*9e80f906SNeil Armstrong u32 dev_sense; 106*9e80f906SNeil Armstrong u32 dev_masked; 107*9e80f906SNeil Armstrong } irq; 108*9e80f906SNeil Armstrong struct mutex lock; 109*9e80f906SNeil Armstrong const struct sx150x_device_data *data; 110*9e80f906SNeil Armstrong }; 111*9e80f906SNeil Armstrong 112*9e80f906SNeil Armstrong static const struct pinctrl_pin_desc sx150x_8_pins[] = { 113*9e80f906SNeil Armstrong PINCTRL_PIN(0, "gpio0"), 114*9e80f906SNeil Armstrong PINCTRL_PIN(1, "gpio1"), 115*9e80f906SNeil Armstrong PINCTRL_PIN(2, "gpio2"), 116*9e80f906SNeil Armstrong PINCTRL_PIN(3, "gpio3"), 117*9e80f906SNeil Armstrong PINCTRL_PIN(4, "gpio4"), 118*9e80f906SNeil Armstrong PINCTRL_PIN(5, "gpio5"), 119*9e80f906SNeil Armstrong PINCTRL_PIN(6, "gpio6"), 120*9e80f906SNeil Armstrong PINCTRL_PIN(7, "gpio7"), 121*9e80f906SNeil Armstrong PINCTRL_PIN(8, "oscio"), 122*9e80f906SNeil Armstrong }; 123*9e80f906SNeil Armstrong 124*9e80f906SNeil Armstrong static const struct pinctrl_pin_desc sx150x_16_pins[] = { 125*9e80f906SNeil Armstrong PINCTRL_PIN(0, "gpio0"), 126*9e80f906SNeil Armstrong PINCTRL_PIN(1, "gpio1"), 127*9e80f906SNeil Armstrong PINCTRL_PIN(2, "gpio2"), 128*9e80f906SNeil Armstrong PINCTRL_PIN(3, "gpio3"), 129*9e80f906SNeil Armstrong PINCTRL_PIN(4, "gpio4"), 130*9e80f906SNeil Armstrong PINCTRL_PIN(5, "gpio5"), 131*9e80f906SNeil Armstrong PINCTRL_PIN(6, "gpio6"), 132*9e80f906SNeil Armstrong PINCTRL_PIN(7, "gpio7"), 133*9e80f906SNeil Armstrong PINCTRL_PIN(8, "gpio8"), 134*9e80f906SNeil Armstrong PINCTRL_PIN(9, "gpio9"), 135*9e80f906SNeil Armstrong PINCTRL_PIN(10, "gpio10"), 136*9e80f906SNeil Armstrong PINCTRL_PIN(11, "gpio11"), 137*9e80f906SNeil Armstrong PINCTRL_PIN(12, "gpio12"), 138*9e80f906SNeil Armstrong PINCTRL_PIN(13, "gpio13"), 139*9e80f906SNeil Armstrong PINCTRL_PIN(14, "gpio14"), 140*9e80f906SNeil Armstrong PINCTRL_PIN(15, "gpio15"), 141*9e80f906SNeil Armstrong PINCTRL_PIN(16, "oscio"), 142*9e80f906SNeil Armstrong }; 143*9e80f906SNeil Armstrong 144*9e80f906SNeil Armstrong static const struct sx150x_device_data sx1508q_device_data = { 145*9e80f906SNeil Armstrong .model = SX150X_789, 146*9e80f906SNeil Armstrong .reg_pullup = 0x03, 147*9e80f906SNeil Armstrong .reg_pulldn = 0x04, 148*9e80f906SNeil Armstrong .reg_dir = 0x07, 149*9e80f906SNeil Armstrong .reg_data = 0x08, 150*9e80f906SNeil Armstrong .reg_irq_mask = 0x09, 151*9e80f906SNeil Armstrong .reg_irq_src = 0x0c, 152*9e80f906SNeil Armstrong .reg_sense = 0x0b, 153*9e80f906SNeil Armstrong .pri.x789 = { 154*9e80f906SNeil Armstrong .reg_drain = 0x05, 155*9e80f906SNeil Armstrong .reg_polarity = 0x06, 156*9e80f906SNeil Armstrong .reg_clock = 0x0f, 157*9e80f906SNeil Armstrong .reg_misc = 0x10, 158*9e80f906SNeil Armstrong .reg_reset = 0x7d, 159*9e80f906SNeil Armstrong }, 160*9e80f906SNeil Armstrong .ngpios = 8, 161*9e80f906SNeil Armstrong .pins = sx150x_8_pins, 162*9e80f906SNeil Armstrong .npins = ARRAY_SIZE(sx150x_8_pins), 163*9e80f906SNeil Armstrong }; 164*9e80f906SNeil Armstrong 165*9e80f906SNeil Armstrong static const struct sx150x_device_data sx1509q_device_data = { 166*9e80f906SNeil Armstrong .model = SX150X_789, 167*9e80f906SNeil Armstrong .reg_pullup = 0x07, 168*9e80f906SNeil Armstrong .reg_pulldn = 0x09, 169*9e80f906SNeil Armstrong .reg_dir = 0x0f, 170*9e80f906SNeil Armstrong .reg_data = 0x11, 171*9e80f906SNeil Armstrong .reg_irq_mask = 0x13, 172*9e80f906SNeil Armstrong .reg_irq_src = 0x19, 173*9e80f906SNeil Armstrong .reg_sense = 0x17, 174*9e80f906SNeil Armstrong .pri.x789 = { 175*9e80f906SNeil Armstrong .reg_drain = 0x0b, 176*9e80f906SNeil Armstrong .reg_polarity = 0x0d, 177*9e80f906SNeil Armstrong .reg_clock = 0x1e, 178*9e80f906SNeil Armstrong .reg_misc = 0x1f, 179*9e80f906SNeil Armstrong .reg_reset = 0x7d, 180*9e80f906SNeil Armstrong }, 181*9e80f906SNeil Armstrong .ngpios = 16, 182*9e80f906SNeil Armstrong .pins = sx150x_16_pins, 183*9e80f906SNeil Armstrong .npins = ARRAY_SIZE(sx150x_16_pins), 184*9e80f906SNeil Armstrong }; 185*9e80f906SNeil Armstrong 186*9e80f906SNeil Armstrong static const struct sx150x_device_data sx1506q_device_data = { 187*9e80f906SNeil Armstrong .model = SX150X_456, 188*9e80f906SNeil Armstrong .reg_pullup = 0x05, 189*9e80f906SNeil Armstrong .reg_pulldn = 0x07, 190*9e80f906SNeil Armstrong .reg_dir = 0x03, 191*9e80f906SNeil Armstrong .reg_data = 0x01, 192*9e80f906SNeil Armstrong .reg_irq_mask = 0x09, 193*9e80f906SNeil Armstrong .reg_irq_src = 0x0f, 194*9e80f906SNeil Armstrong .reg_sense = 0x0d, 195*9e80f906SNeil Armstrong .pri.x456 = { 196*9e80f906SNeil Armstrong .reg_pld_mode = 0x21, 197*9e80f906SNeil Armstrong .reg_pld_table0 = 0x23, 198*9e80f906SNeil Armstrong .reg_pld_table1 = 0x25, 199*9e80f906SNeil Armstrong .reg_pld_table2 = 0x27, 200*9e80f906SNeil Armstrong .reg_pld_table3 = 0x29, 201*9e80f906SNeil Armstrong .reg_pld_table4 = 0x2b, 202*9e80f906SNeil Armstrong .reg_advance = 0xad, 203*9e80f906SNeil Armstrong }, 204*9e80f906SNeil Armstrong .ngpios = 16, 205*9e80f906SNeil Armstrong .pins = sx150x_16_pins, 206*9e80f906SNeil Armstrong .npins = 16, /* oscio not available */ 207*9e80f906SNeil Armstrong }; 208*9e80f906SNeil Armstrong 209*9e80f906SNeil Armstrong static const struct sx150x_device_data sx1502q_device_data = { 210*9e80f906SNeil Armstrong .model = SX150X_123, 211*9e80f906SNeil Armstrong .reg_pullup = 0x02, 212*9e80f906SNeil Armstrong .reg_pulldn = 0x03, 213*9e80f906SNeil Armstrong .reg_dir = 0x01, 214*9e80f906SNeil Armstrong .reg_data = 0x00, 215*9e80f906SNeil Armstrong .reg_irq_mask = 0x05, 216*9e80f906SNeil Armstrong .reg_irq_src = 0x08, 217*9e80f906SNeil Armstrong .reg_sense = 0x07, 218*9e80f906SNeil Armstrong .pri.x123 = { 219*9e80f906SNeil Armstrong .reg_pld_mode = 0x10, 220*9e80f906SNeil Armstrong .reg_pld_table0 = 0x11, 221*9e80f906SNeil Armstrong .reg_pld_table1 = 0x12, 222*9e80f906SNeil Armstrong .reg_pld_table2 = 0x13, 223*9e80f906SNeil Armstrong .reg_pld_table3 = 0x14, 224*9e80f906SNeil Armstrong .reg_pld_table4 = 0x15, 225*9e80f906SNeil Armstrong .reg_advance = 0xad, 226*9e80f906SNeil Armstrong }, 227*9e80f906SNeil Armstrong .ngpios = 8, 228*9e80f906SNeil Armstrong .pins = sx150x_8_pins, 229*9e80f906SNeil Armstrong .npins = 8, /* oscio not available */ 230*9e80f906SNeil Armstrong }; 231*9e80f906SNeil Armstrong 232*9e80f906SNeil Armstrong static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val) 233*9e80f906SNeil Armstrong { 234*9e80f906SNeil Armstrong s32 err = i2c_smbus_write_byte_data(client, reg, val); 235*9e80f906SNeil Armstrong 236*9e80f906SNeil Armstrong if (err < 0) 237*9e80f906SNeil Armstrong dev_warn(&client->dev, 238*9e80f906SNeil Armstrong "i2c write fail: can't write %02x to %02x: %d\n", 239*9e80f906SNeil Armstrong val, reg, err); 240*9e80f906SNeil Armstrong return err; 241*9e80f906SNeil Armstrong } 242*9e80f906SNeil Armstrong 243*9e80f906SNeil Armstrong static s32 sx150x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) 244*9e80f906SNeil Armstrong { 245*9e80f906SNeil Armstrong s32 err = i2c_smbus_read_byte_data(client, reg); 246*9e80f906SNeil Armstrong 247*9e80f906SNeil Armstrong if (err >= 0) 248*9e80f906SNeil Armstrong *val = err; 249*9e80f906SNeil Armstrong else 250*9e80f906SNeil Armstrong dev_warn(&client->dev, 251*9e80f906SNeil Armstrong "i2c read fail: can't read from %02x: %d\n", 252*9e80f906SNeil Armstrong reg, err); 253*9e80f906SNeil Armstrong return err; 254*9e80f906SNeil Armstrong } 255*9e80f906SNeil Armstrong 256*9e80f906SNeil Armstrong /* 257*9e80f906SNeil Armstrong * These utility functions solve the common problem of locating and setting 258*9e80f906SNeil Armstrong * configuration bits. Configuration bits are grouped into registers 259*9e80f906SNeil Armstrong * whose indexes increase downwards. For example, with eight-bit registers, 260*9e80f906SNeil Armstrong * sixteen gpios would have their config bits grouped in the following order: 261*9e80f906SNeil Armstrong * REGISTER N-1 [ f e d c b a 9 8 ] 262*9e80f906SNeil Armstrong * N [ 7 6 5 4 3 2 1 0 ] 263*9e80f906SNeil Armstrong * 264*9e80f906SNeil Armstrong * For multi-bit configurations, the pattern gets wider: 265*9e80f906SNeil Armstrong * REGISTER N-3 [ f f e e d d c c ] 266*9e80f906SNeil Armstrong * N-2 [ b b a a 9 9 8 8 ] 267*9e80f906SNeil Armstrong * N-1 [ 7 7 6 6 5 5 4 4 ] 268*9e80f906SNeil Armstrong * N [ 3 3 2 2 1 1 0 0 ] 269*9e80f906SNeil Armstrong * 270*9e80f906SNeil Armstrong * Given the address of the starting register 'N', the index of the gpio 271*9e80f906SNeil Armstrong * whose configuration we seek to change, and the width in bits of that 272*9e80f906SNeil Armstrong * configuration, these functions allow us to locate the correct 273*9e80f906SNeil Armstrong * register and mask the correct bits. 274*9e80f906SNeil Armstrong */ 275*9e80f906SNeil Armstrong static inline void sx150x_find_cfg(u8 offset, u8 width, 276*9e80f906SNeil Armstrong u8 *reg, u8 *mask, u8 *shift) 277*9e80f906SNeil Armstrong { 278*9e80f906SNeil Armstrong *reg -= offset * width / 8; 279*9e80f906SNeil Armstrong *mask = (1 << width) - 1; 280*9e80f906SNeil Armstrong *shift = (offset * width) % 8; 281*9e80f906SNeil Armstrong *mask <<= *shift; 282*9e80f906SNeil Armstrong } 283*9e80f906SNeil Armstrong 284*9e80f906SNeil Armstrong static int sx150x_write_cfg(struct i2c_client *client, 285*9e80f906SNeil Armstrong u8 offset, u8 width, u8 reg, u8 val) 286*9e80f906SNeil Armstrong { 287*9e80f906SNeil Armstrong u8 mask; 288*9e80f906SNeil Armstrong u8 data; 289*9e80f906SNeil Armstrong u8 shift; 290*9e80f906SNeil Armstrong int err; 291*9e80f906SNeil Armstrong 292*9e80f906SNeil Armstrong sx150x_find_cfg(offset, width, ®, &mask, &shift); 293*9e80f906SNeil Armstrong err = sx150x_i2c_read(client, reg, &data); 294*9e80f906SNeil Armstrong if (err < 0) 295*9e80f906SNeil Armstrong return err; 296*9e80f906SNeil Armstrong 297*9e80f906SNeil Armstrong data &= ~mask; 298*9e80f906SNeil Armstrong data |= (val << shift) & mask; 299*9e80f906SNeil Armstrong return sx150x_i2c_write(client, reg, data); 300*9e80f906SNeil Armstrong } 301*9e80f906SNeil Armstrong 302*9e80f906SNeil Armstrong static int sx150x_read_cfg(struct i2c_client *client, 303*9e80f906SNeil Armstrong u8 offset, u8 width, u8 reg) 304*9e80f906SNeil Armstrong { 305*9e80f906SNeil Armstrong u8 mask; 306*9e80f906SNeil Armstrong u8 data; 307*9e80f906SNeil Armstrong u8 shift; 308*9e80f906SNeil Armstrong int err; 309*9e80f906SNeil Armstrong 310*9e80f906SNeil Armstrong sx150x_find_cfg(offset, width, ®, &mask, &shift); 311*9e80f906SNeil Armstrong err = sx150x_i2c_read(client, reg, &data); 312*9e80f906SNeil Armstrong if (err < 0) 313*9e80f906SNeil Armstrong return err; 314*9e80f906SNeil Armstrong 315*9e80f906SNeil Armstrong return (data & mask); 316*9e80f906SNeil Armstrong } 317*9e80f906SNeil Armstrong 318*9e80f906SNeil Armstrong static int sx150x_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) 319*9e80f906SNeil Armstrong { 320*9e80f906SNeil Armstrong return 0; 321*9e80f906SNeil Armstrong } 322*9e80f906SNeil Armstrong 323*9e80f906SNeil Armstrong static const char *sx150x_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 324*9e80f906SNeil Armstrong unsigned int group) 325*9e80f906SNeil Armstrong { 326*9e80f906SNeil Armstrong return NULL; 327*9e80f906SNeil Armstrong } 328*9e80f906SNeil Armstrong 329*9e80f906SNeil Armstrong static int sx150x_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 330*9e80f906SNeil Armstrong unsigned int group, 331*9e80f906SNeil Armstrong const unsigned int **pins, 332*9e80f906SNeil Armstrong unsigned int *num_pins) 333*9e80f906SNeil Armstrong { 334*9e80f906SNeil Armstrong return -ENOTSUPP; 335*9e80f906SNeil Armstrong } 336*9e80f906SNeil Armstrong 337*9e80f906SNeil Armstrong static const struct pinctrl_ops sx150x_pinctrl_ops = { 338*9e80f906SNeil Armstrong .get_groups_count = sx150x_pinctrl_get_groups_count, 339*9e80f906SNeil Armstrong .get_group_name = sx150x_pinctrl_get_group_name, 340*9e80f906SNeil Armstrong .get_group_pins = sx150x_pinctrl_get_group_pins, 341*9e80f906SNeil Armstrong #ifdef CONFIG_OF 342*9e80f906SNeil Armstrong .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 343*9e80f906SNeil Armstrong .dt_free_map = pinctrl_utils_free_map, 344*9e80f906SNeil Armstrong #endif 345*9e80f906SNeil Armstrong }; 346*9e80f906SNeil Armstrong 347*9e80f906SNeil Armstrong static bool sx150x_pin_is_oscio(struct sx150x_pinctrl *pctl, unsigned int pin) 348*9e80f906SNeil Armstrong { 349*9e80f906SNeil Armstrong if (pin >= pctl->data->npins) 350*9e80f906SNeil Armstrong return false; 351*9e80f906SNeil Armstrong 352*9e80f906SNeil Armstrong /* OSCIO pin is only present in 789 devices */ 353*9e80f906SNeil Armstrong if (pctl->data->model != SX150X_789) 354*9e80f906SNeil Armstrong return false; 355*9e80f906SNeil Armstrong 356*9e80f906SNeil Armstrong return !strcmp(pctl->data->pins[pin].name, "oscio"); 357*9e80f906SNeil Armstrong } 358*9e80f906SNeil Armstrong 359*9e80f906SNeil Armstrong static int sx150x_gpio_get_direction(struct gpio_chip *chip, 360*9e80f906SNeil Armstrong unsigned int offset) 361*9e80f906SNeil Armstrong { 362*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 363*9e80f906SNeil Armstrong int status; 364*9e80f906SNeil Armstrong 365*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, offset)) 366*9e80f906SNeil Armstrong return false; 367*9e80f906SNeil Armstrong 368*9e80f906SNeil Armstrong status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_dir); 369*9e80f906SNeil Armstrong if (status >= 0) 370*9e80f906SNeil Armstrong status = !!status; 371*9e80f906SNeil Armstrong 372*9e80f906SNeil Armstrong return status; 373*9e80f906SNeil Armstrong } 374*9e80f906SNeil Armstrong 375*9e80f906SNeil Armstrong static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset) 376*9e80f906SNeil Armstrong { 377*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 378*9e80f906SNeil Armstrong int status; 379*9e80f906SNeil Armstrong 380*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, offset)) 381*9e80f906SNeil Armstrong return -EINVAL; 382*9e80f906SNeil Armstrong 383*9e80f906SNeil Armstrong status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_data); 384*9e80f906SNeil Armstrong if (status >= 0) 385*9e80f906SNeil Armstrong status = !!status; 386*9e80f906SNeil Armstrong 387*9e80f906SNeil Armstrong return status; 388*9e80f906SNeil Armstrong } 389*9e80f906SNeil Armstrong 390*9e80f906SNeil Armstrong static int sx150x_gpio_set_single_ended(struct gpio_chip *chip, 391*9e80f906SNeil Armstrong unsigned int offset, 392*9e80f906SNeil Armstrong enum single_ended_mode mode) 393*9e80f906SNeil Armstrong { 394*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 395*9e80f906SNeil Armstrong int ret; 396*9e80f906SNeil Armstrong 397*9e80f906SNeil Armstrong switch (mode) { 398*9e80f906SNeil Armstrong case LINE_MODE_PUSH_PULL: 399*9e80f906SNeil Armstrong if (pctl->data->model != SX150X_789 || 400*9e80f906SNeil Armstrong sx150x_pin_is_oscio(pctl, offset)) 401*9e80f906SNeil Armstrong return 0; 402*9e80f906SNeil Armstrong 403*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 404*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, offset, 1, 405*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_drain, 406*9e80f906SNeil Armstrong 0); 407*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 408*9e80f906SNeil Armstrong if (ret < 0) 409*9e80f906SNeil Armstrong return ret; 410*9e80f906SNeil Armstrong break; 411*9e80f906SNeil Armstrong 412*9e80f906SNeil Armstrong case LINE_MODE_OPEN_DRAIN: 413*9e80f906SNeil Armstrong if (pctl->data->model != SX150X_789 || 414*9e80f906SNeil Armstrong sx150x_pin_is_oscio(pctl, offset)) 415*9e80f906SNeil Armstrong return -ENOTSUPP; 416*9e80f906SNeil Armstrong 417*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 418*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, offset, 1, 419*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_drain, 420*9e80f906SNeil Armstrong 1); 421*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 422*9e80f906SNeil Armstrong if (ret < 0) 423*9e80f906SNeil Armstrong return ret; 424*9e80f906SNeil Armstrong break; 425*9e80f906SNeil Armstrong 426*9e80f906SNeil Armstrong default: 427*9e80f906SNeil Armstrong return -ENOTSUPP; 428*9e80f906SNeil Armstrong } 429*9e80f906SNeil Armstrong 430*9e80f906SNeil Armstrong return 0; 431*9e80f906SNeil Armstrong } 432*9e80f906SNeil Armstrong 433*9e80f906SNeil Armstrong static void sx150x_gpio_set(struct gpio_chip *chip, unsigned int offset, 434*9e80f906SNeil Armstrong int value) 435*9e80f906SNeil Armstrong { 436*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 437*9e80f906SNeil Armstrong 438*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, offset)) { 439*9e80f906SNeil Armstrong 440*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 441*9e80f906SNeil Armstrong sx150x_i2c_write(pctl->client, 442*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_clock, 443*9e80f906SNeil Armstrong (value ? 0x1f : 0x10)); 444*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 445*9e80f906SNeil Armstrong } else { 446*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 447*9e80f906SNeil Armstrong sx150x_write_cfg(pctl->client, offset, 1, 448*9e80f906SNeil Armstrong pctl->data->reg_data, 449*9e80f906SNeil Armstrong (value ? 1 : 0)); 450*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 451*9e80f906SNeil Armstrong } 452*9e80f906SNeil Armstrong } 453*9e80f906SNeil Armstrong 454*9e80f906SNeil Armstrong static int sx150x_gpio_direction_input(struct gpio_chip *chip, 455*9e80f906SNeil Armstrong unsigned int offset) 456*9e80f906SNeil Armstrong { 457*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 458*9e80f906SNeil Armstrong int ret; 459*9e80f906SNeil Armstrong 460*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, offset)) 461*9e80f906SNeil Armstrong return -EINVAL; 462*9e80f906SNeil Armstrong 463*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 464*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, offset, 1, 465*9e80f906SNeil Armstrong pctl->data->reg_dir, 1); 466*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 467*9e80f906SNeil Armstrong 468*9e80f906SNeil Armstrong return ret; 469*9e80f906SNeil Armstrong } 470*9e80f906SNeil Armstrong 471*9e80f906SNeil Armstrong static int sx150x_gpio_direction_output(struct gpio_chip *chip, 472*9e80f906SNeil Armstrong unsigned int offset, int value) 473*9e80f906SNeil Armstrong { 474*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); 475*9e80f906SNeil Armstrong int status; 476*9e80f906SNeil Armstrong 477*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, offset)) { 478*9e80f906SNeil Armstrong sx150x_gpio_set(chip, offset, value); 479*9e80f906SNeil Armstrong return 0; 480*9e80f906SNeil Armstrong } 481*9e80f906SNeil Armstrong 482*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 483*9e80f906SNeil Armstrong status = sx150x_write_cfg(pctl->client, offset, 1, 484*9e80f906SNeil Armstrong pctl->data->reg_data, 485*9e80f906SNeil Armstrong (value ? 1 : 0)); 486*9e80f906SNeil Armstrong if (status >= 0) 487*9e80f906SNeil Armstrong status = sx150x_write_cfg(pctl->client, offset, 1, 488*9e80f906SNeil Armstrong pctl->data->reg_dir, 0); 489*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 490*9e80f906SNeil Armstrong 491*9e80f906SNeil Armstrong return status; 492*9e80f906SNeil Armstrong } 493*9e80f906SNeil Armstrong 494*9e80f906SNeil Armstrong static void sx150x_irq_mask(struct irq_data *d) 495*9e80f906SNeil Armstrong { 496*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = 497*9e80f906SNeil Armstrong gpiochip_get_data(irq_data_get_irq_chip_data(d)); 498*9e80f906SNeil Armstrong unsigned int n = d->hwirq; 499*9e80f906SNeil Armstrong 500*9e80f906SNeil Armstrong pctl->irq.masked |= (1 << n); 501*9e80f906SNeil Armstrong pctl->irq.update = n; 502*9e80f906SNeil Armstrong } 503*9e80f906SNeil Armstrong 504*9e80f906SNeil Armstrong static void sx150x_irq_unmask(struct irq_data *d) 505*9e80f906SNeil Armstrong { 506*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = 507*9e80f906SNeil Armstrong gpiochip_get_data(irq_data_get_irq_chip_data(d)); 508*9e80f906SNeil Armstrong unsigned int n = d->hwirq; 509*9e80f906SNeil Armstrong 510*9e80f906SNeil Armstrong pctl->irq.masked &= ~(1 << n); 511*9e80f906SNeil Armstrong pctl->irq.update = n; 512*9e80f906SNeil Armstrong } 513*9e80f906SNeil Armstrong 514*9e80f906SNeil Armstrong static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type) 515*9e80f906SNeil Armstrong { 516*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = 517*9e80f906SNeil Armstrong gpiochip_get_data(irq_data_get_irq_chip_data(d)); 518*9e80f906SNeil Armstrong unsigned int n, val = 0; 519*9e80f906SNeil Armstrong 520*9e80f906SNeil Armstrong if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) 521*9e80f906SNeil Armstrong return -EINVAL; 522*9e80f906SNeil Armstrong 523*9e80f906SNeil Armstrong n = d->hwirq; 524*9e80f906SNeil Armstrong 525*9e80f906SNeil Armstrong if (flow_type & IRQ_TYPE_EDGE_RISING) 526*9e80f906SNeil Armstrong val |= 0x1; 527*9e80f906SNeil Armstrong if (flow_type & IRQ_TYPE_EDGE_FALLING) 528*9e80f906SNeil Armstrong val |= 0x2; 529*9e80f906SNeil Armstrong 530*9e80f906SNeil Armstrong pctl->irq.sense &= ~(3UL << (n * 2)); 531*9e80f906SNeil Armstrong pctl->irq.sense |= val << (n * 2); 532*9e80f906SNeil Armstrong pctl->irq.update = n; 533*9e80f906SNeil Armstrong return 0; 534*9e80f906SNeil Armstrong } 535*9e80f906SNeil Armstrong 536*9e80f906SNeil Armstrong static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id) 537*9e80f906SNeil Armstrong { 538*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = (struct sx150x_pinctrl *)dev_id; 539*9e80f906SNeil Armstrong unsigned int nhandled = 0; 540*9e80f906SNeil Armstrong unsigned int sub_irq; 541*9e80f906SNeil Armstrong unsigned int n; 542*9e80f906SNeil Armstrong s32 err; 543*9e80f906SNeil Armstrong u8 val; 544*9e80f906SNeil Armstrong int i; 545*9e80f906SNeil Armstrong 546*9e80f906SNeil Armstrong for (i = (pctl->data->ngpios / 8) - 1; i >= 0; --i) { 547*9e80f906SNeil Armstrong err = sx150x_i2c_read(pctl->client, 548*9e80f906SNeil Armstrong pctl->data->reg_irq_src - i, 549*9e80f906SNeil Armstrong &val); 550*9e80f906SNeil Armstrong if (err < 0) 551*9e80f906SNeil Armstrong continue; 552*9e80f906SNeil Armstrong 553*9e80f906SNeil Armstrong err = sx150x_i2c_write(pctl->client, 554*9e80f906SNeil Armstrong pctl->data->reg_irq_src - i, 555*9e80f906SNeil Armstrong val); 556*9e80f906SNeil Armstrong if (err < 0) 557*9e80f906SNeil Armstrong continue; 558*9e80f906SNeil Armstrong 559*9e80f906SNeil Armstrong for (n = 0; n < 8; ++n) { 560*9e80f906SNeil Armstrong if (val & (1 << n)) { 561*9e80f906SNeil Armstrong sub_irq = irq_find_mapping( 562*9e80f906SNeil Armstrong pctl->gpio.irqdomain, 563*9e80f906SNeil Armstrong (i * 8) + n); 564*9e80f906SNeil Armstrong handle_nested_irq(sub_irq); 565*9e80f906SNeil Armstrong ++nhandled; 566*9e80f906SNeil Armstrong } 567*9e80f906SNeil Armstrong } 568*9e80f906SNeil Armstrong } 569*9e80f906SNeil Armstrong 570*9e80f906SNeil Armstrong return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); 571*9e80f906SNeil Armstrong } 572*9e80f906SNeil Armstrong 573*9e80f906SNeil Armstrong static void sx150x_irq_bus_lock(struct irq_data *d) 574*9e80f906SNeil Armstrong { 575*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = 576*9e80f906SNeil Armstrong gpiochip_get_data(irq_data_get_irq_chip_data(d)); 577*9e80f906SNeil Armstrong 578*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 579*9e80f906SNeil Armstrong } 580*9e80f906SNeil Armstrong 581*9e80f906SNeil Armstrong static void sx150x_irq_bus_sync_unlock(struct irq_data *d) 582*9e80f906SNeil Armstrong { 583*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = 584*9e80f906SNeil Armstrong gpiochip_get_data(irq_data_get_irq_chip_data(d)); 585*9e80f906SNeil Armstrong unsigned int n; 586*9e80f906SNeil Armstrong 587*9e80f906SNeil Armstrong if (pctl->irq.update < 0) 588*9e80f906SNeil Armstrong goto out; 589*9e80f906SNeil Armstrong 590*9e80f906SNeil Armstrong n = pctl->irq.update; 591*9e80f906SNeil Armstrong pctl->irq.update = -1; 592*9e80f906SNeil Armstrong 593*9e80f906SNeil Armstrong /* Avoid updates if nothing changed */ 594*9e80f906SNeil Armstrong if (pctl->irq.dev_sense == pctl->irq.sense && 595*9e80f906SNeil Armstrong pctl->irq.dev_masked == pctl->irq.masked) 596*9e80f906SNeil Armstrong goto out; 597*9e80f906SNeil Armstrong 598*9e80f906SNeil Armstrong pctl->irq.dev_sense = pctl->irq.sense; 599*9e80f906SNeil Armstrong pctl->irq.dev_masked = pctl->irq.masked; 600*9e80f906SNeil Armstrong 601*9e80f906SNeil Armstrong if (pctl->irq.masked & (1 << n)) { 602*9e80f906SNeil Armstrong sx150x_write_cfg(pctl->client, n, 1, 603*9e80f906SNeil Armstrong pctl->data->reg_irq_mask, 1); 604*9e80f906SNeil Armstrong sx150x_write_cfg(pctl->client, n, 2, 605*9e80f906SNeil Armstrong pctl->data->reg_sense, 0); 606*9e80f906SNeil Armstrong } else { 607*9e80f906SNeil Armstrong sx150x_write_cfg(pctl->client, n, 1, 608*9e80f906SNeil Armstrong pctl->data->reg_irq_mask, 0); 609*9e80f906SNeil Armstrong sx150x_write_cfg(pctl->client, n, 2, 610*9e80f906SNeil Armstrong pctl->data->reg_sense, 611*9e80f906SNeil Armstrong pctl->irq.sense >> (n * 2)); 612*9e80f906SNeil Armstrong } 613*9e80f906SNeil Armstrong out: 614*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 615*9e80f906SNeil Armstrong } 616*9e80f906SNeil Armstrong 617*9e80f906SNeil Armstrong static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 618*9e80f906SNeil Armstrong unsigned long *config) 619*9e80f906SNeil Armstrong { 620*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 621*9e80f906SNeil Armstrong unsigned int param = pinconf_to_config_param(*config); 622*9e80f906SNeil Armstrong int ret; 623*9e80f906SNeil Armstrong u32 arg; 624*9e80f906SNeil Armstrong 625*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, pin)) { 626*9e80f906SNeil Armstrong u8 data; 627*9e80f906SNeil Armstrong 628*9e80f906SNeil Armstrong switch (param) { 629*9e80f906SNeil Armstrong case PIN_CONFIG_DRIVE_PUSH_PULL: 630*9e80f906SNeil Armstrong case PIN_CONFIG_OUTPUT: 631*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 632*9e80f906SNeil Armstrong ret = sx150x_i2c_read(pctl->client, 633*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_clock, 634*9e80f906SNeil Armstrong &data); 635*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 636*9e80f906SNeil Armstrong 637*9e80f906SNeil Armstrong if (ret < 0) 638*9e80f906SNeil Armstrong return ret; 639*9e80f906SNeil Armstrong 640*9e80f906SNeil Armstrong if (param == PIN_CONFIG_DRIVE_PUSH_PULL) 641*9e80f906SNeil Armstrong arg = (data & 0x1f) ? 1 : 0; 642*9e80f906SNeil Armstrong else { 643*9e80f906SNeil Armstrong if ((data & 0x1f) == 0x1f) 644*9e80f906SNeil Armstrong arg = 1; 645*9e80f906SNeil Armstrong else if ((data & 0x1f) == 0x10) 646*9e80f906SNeil Armstrong arg = 0; 647*9e80f906SNeil Armstrong else 648*9e80f906SNeil Armstrong return -EINVAL; 649*9e80f906SNeil Armstrong } 650*9e80f906SNeil Armstrong 651*9e80f906SNeil Armstrong break; 652*9e80f906SNeil Armstrong default: 653*9e80f906SNeil Armstrong return -ENOTSUPP; 654*9e80f906SNeil Armstrong } 655*9e80f906SNeil Armstrong 656*9e80f906SNeil Armstrong goto out; 657*9e80f906SNeil Armstrong } 658*9e80f906SNeil Armstrong 659*9e80f906SNeil Armstrong switch (param) { 660*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_PULL_DOWN: 661*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 662*9e80f906SNeil Armstrong ret = sx150x_read_cfg(pctl->client, pin, 1, 663*9e80f906SNeil Armstrong pctl->data->reg_pulldn); 664*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 665*9e80f906SNeil Armstrong 666*9e80f906SNeil Armstrong if (ret < 0) 667*9e80f906SNeil Armstrong return ret; 668*9e80f906SNeil Armstrong 669*9e80f906SNeil Armstrong if (!ret) 670*9e80f906SNeil Armstrong return -EINVAL; 671*9e80f906SNeil Armstrong 672*9e80f906SNeil Armstrong arg = 1; 673*9e80f906SNeil Armstrong break; 674*9e80f906SNeil Armstrong 675*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_PULL_UP: 676*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 677*9e80f906SNeil Armstrong ret = sx150x_read_cfg(pctl->client, pin, 1, 678*9e80f906SNeil Armstrong pctl->data->reg_pullup); 679*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 680*9e80f906SNeil Armstrong 681*9e80f906SNeil Armstrong if (ret < 0) 682*9e80f906SNeil Armstrong return ret; 683*9e80f906SNeil Armstrong 684*9e80f906SNeil Armstrong if (!ret) 685*9e80f906SNeil Armstrong return -EINVAL; 686*9e80f906SNeil Armstrong 687*9e80f906SNeil Armstrong arg = 1; 688*9e80f906SNeil Armstrong break; 689*9e80f906SNeil Armstrong 690*9e80f906SNeil Armstrong case PIN_CONFIG_DRIVE_OPEN_DRAIN: 691*9e80f906SNeil Armstrong if (pctl->data->model != SX150X_789) 692*9e80f906SNeil Armstrong return -ENOTSUPP; 693*9e80f906SNeil Armstrong 694*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 695*9e80f906SNeil Armstrong ret = sx150x_read_cfg(pctl->client, pin, 1, 696*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_drain); 697*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 698*9e80f906SNeil Armstrong 699*9e80f906SNeil Armstrong if (ret < 0) 700*9e80f906SNeil Armstrong return ret; 701*9e80f906SNeil Armstrong 702*9e80f906SNeil Armstrong if (!ret) 703*9e80f906SNeil Armstrong return -EINVAL; 704*9e80f906SNeil Armstrong 705*9e80f906SNeil Armstrong arg = 1; 706*9e80f906SNeil Armstrong break; 707*9e80f906SNeil Armstrong 708*9e80f906SNeil Armstrong case PIN_CONFIG_DRIVE_PUSH_PULL: 709*9e80f906SNeil Armstrong if (pctl->data->model != SX150X_789) 710*9e80f906SNeil Armstrong arg = true; 711*9e80f906SNeil Armstrong else { 712*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 713*9e80f906SNeil Armstrong ret = sx150x_read_cfg(pctl->client, pin, 1, 714*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_drain); 715*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 716*9e80f906SNeil Armstrong 717*9e80f906SNeil Armstrong if (ret < 0) 718*9e80f906SNeil Armstrong return ret; 719*9e80f906SNeil Armstrong 720*9e80f906SNeil Armstrong if (ret) 721*9e80f906SNeil Armstrong return -EINVAL; 722*9e80f906SNeil Armstrong 723*9e80f906SNeil Armstrong arg = 1; 724*9e80f906SNeil Armstrong } 725*9e80f906SNeil Armstrong break; 726*9e80f906SNeil Armstrong 727*9e80f906SNeil Armstrong case PIN_CONFIG_OUTPUT: 728*9e80f906SNeil Armstrong ret = sx150x_gpio_get_direction(&pctl->gpio, pin); 729*9e80f906SNeil Armstrong if (ret < 0) 730*9e80f906SNeil Armstrong return ret; 731*9e80f906SNeil Armstrong 732*9e80f906SNeil Armstrong if (ret) 733*9e80f906SNeil Armstrong return -EINVAL; 734*9e80f906SNeil Armstrong 735*9e80f906SNeil Armstrong ret = sx150x_gpio_get(&pctl->gpio, pin); 736*9e80f906SNeil Armstrong if (ret < 0) 737*9e80f906SNeil Armstrong return ret; 738*9e80f906SNeil Armstrong 739*9e80f906SNeil Armstrong arg = ret; 740*9e80f906SNeil Armstrong break; 741*9e80f906SNeil Armstrong 742*9e80f906SNeil Armstrong default: 743*9e80f906SNeil Armstrong return -ENOTSUPP; 744*9e80f906SNeil Armstrong } 745*9e80f906SNeil Armstrong 746*9e80f906SNeil Armstrong out: 747*9e80f906SNeil Armstrong *config = pinconf_to_config_packed(param, arg); 748*9e80f906SNeil Armstrong 749*9e80f906SNeil Armstrong return 0; 750*9e80f906SNeil Armstrong } 751*9e80f906SNeil Armstrong 752*9e80f906SNeil Armstrong static int sx150x_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 753*9e80f906SNeil Armstrong unsigned long *configs, unsigned int num_configs) 754*9e80f906SNeil Armstrong { 755*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); 756*9e80f906SNeil Armstrong enum pin_config_param param; 757*9e80f906SNeil Armstrong u32 arg; 758*9e80f906SNeil Armstrong int i; 759*9e80f906SNeil Armstrong int ret; 760*9e80f906SNeil Armstrong 761*9e80f906SNeil Armstrong for (i = 0; i < num_configs; i++) { 762*9e80f906SNeil Armstrong param = pinconf_to_config_param(configs[i]); 763*9e80f906SNeil Armstrong arg = pinconf_to_config_argument(configs[i]); 764*9e80f906SNeil Armstrong 765*9e80f906SNeil Armstrong if (sx150x_pin_is_oscio(pctl, pin)) { 766*9e80f906SNeil Armstrong if (param == PIN_CONFIG_OUTPUT) { 767*9e80f906SNeil Armstrong ret = sx150x_gpio_direction_output(&pctl->gpio, 768*9e80f906SNeil Armstrong pin, arg); 769*9e80f906SNeil Armstrong if (ret < 0) 770*9e80f906SNeil Armstrong return ret; 771*9e80f906SNeil Armstrong 772*9e80f906SNeil Armstrong continue; 773*9e80f906SNeil Armstrong } else 774*9e80f906SNeil Armstrong return -ENOTSUPP; 775*9e80f906SNeil Armstrong } 776*9e80f906SNeil Armstrong 777*9e80f906SNeil Armstrong switch (param) { 778*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 779*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_DISABLE: 780*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 781*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, pin, 1, 782*9e80f906SNeil Armstrong pctl->data->reg_pulldn, 0); 783*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 784*9e80f906SNeil Armstrong if (ret < 0) 785*9e80f906SNeil Armstrong return ret; 786*9e80f906SNeil Armstrong 787*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 788*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, pin, 1, 789*9e80f906SNeil Armstrong pctl->data->reg_pullup, 0); 790*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 791*9e80f906SNeil Armstrong if (ret < 0) 792*9e80f906SNeil Armstrong return ret; 793*9e80f906SNeil Armstrong 794*9e80f906SNeil Armstrong break; 795*9e80f906SNeil Armstrong 796*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_PULL_UP: 797*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 798*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, pin, 1, 799*9e80f906SNeil Armstrong pctl->data->reg_pullup, 800*9e80f906SNeil Armstrong 1); 801*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 802*9e80f906SNeil Armstrong if (ret < 0) 803*9e80f906SNeil Armstrong return ret; 804*9e80f906SNeil Armstrong 805*9e80f906SNeil Armstrong break; 806*9e80f906SNeil Armstrong 807*9e80f906SNeil Armstrong case PIN_CONFIG_BIAS_PULL_DOWN: 808*9e80f906SNeil Armstrong mutex_lock(&pctl->lock); 809*9e80f906SNeil Armstrong ret = sx150x_write_cfg(pctl->client, pin, 1, 810*9e80f906SNeil Armstrong pctl->data->reg_pulldn, 811*9e80f906SNeil Armstrong 1); 812*9e80f906SNeil Armstrong mutex_unlock(&pctl->lock); 813*9e80f906SNeil Armstrong if (ret < 0) 814*9e80f906SNeil Armstrong return ret; 815*9e80f906SNeil Armstrong 816*9e80f906SNeil Armstrong break; 817*9e80f906SNeil Armstrong 818*9e80f906SNeil Armstrong case PIN_CONFIG_DRIVE_OPEN_DRAIN: 819*9e80f906SNeil Armstrong ret = sx150x_gpio_set_single_ended(&pctl->gpio, 820*9e80f906SNeil Armstrong pin, LINE_MODE_OPEN_DRAIN); 821*9e80f906SNeil Armstrong if (ret < 0) 822*9e80f906SNeil Armstrong return ret; 823*9e80f906SNeil Armstrong 824*9e80f906SNeil Armstrong break; 825*9e80f906SNeil Armstrong 826*9e80f906SNeil Armstrong case PIN_CONFIG_DRIVE_PUSH_PULL: 827*9e80f906SNeil Armstrong ret = sx150x_gpio_set_single_ended(&pctl->gpio, 828*9e80f906SNeil Armstrong pin, LINE_MODE_PUSH_PULL); 829*9e80f906SNeil Armstrong if (ret < 0) 830*9e80f906SNeil Armstrong return ret; 831*9e80f906SNeil Armstrong 832*9e80f906SNeil Armstrong break; 833*9e80f906SNeil Armstrong 834*9e80f906SNeil Armstrong case PIN_CONFIG_OUTPUT: 835*9e80f906SNeil Armstrong ret = sx150x_gpio_direction_output(&pctl->gpio, 836*9e80f906SNeil Armstrong pin, arg); 837*9e80f906SNeil Armstrong if (ret < 0) 838*9e80f906SNeil Armstrong return ret; 839*9e80f906SNeil Armstrong 840*9e80f906SNeil Armstrong break; 841*9e80f906SNeil Armstrong 842*9e80f906SNeil Armstrong default: 843*9e80f906SNeil Armstrong return -ENOTSUPP; 844*9e80f906SNeil Armstrong } 845*9e80f906SNeil Armstrong } /* for each config */ 846*9e80f906SNeil Armstrong 847*9e80f906SNeil Armstrong return 0; 848*9e80f906SNeil Armstrong } 849*9e80f906SNeil Armstrong 850*9e80f906SNeil Armstrong static const struct pinconf_ops sx150x_pinconf_ops = { 851*9e80f906SNeil Armstrong .pin_config_get = sx150x_pinconf_get, 852*9e80f906SNeil Armstrong .pin_config_set = sx150x_pinconf_set, 853*9e80f906SNeil Armstrong .is_generic = true, 854*9e80f906SNeil Armstrong }; 855*9e80f906SNeil Armstrong 856*9e80f906SNeil Armstrong static const struct i2c_device_id sx150x_id[] = { 857*9e80f906SNeil Armstrong {"sx1508q", (kernel_ulong_t) &sx1508q_device_data }, 858*9e80f906SNeil Armstrong {"sx1509q", (kernel_ulong_t) &sx1509q_device_data }, 859*9e80f906SNeil Armstrong {"sx1506q", (kernel_ulong_t) &sx1506q_device_data }, 860*9e80f906SNeil Armstrong {"sx1502q", (kernel_ulong_t) &sx1502q_device_data }, 861*9e80f906SNeil Armstrong {} 862*9e80f906SNeil Armstrong }; 863*9e80f906SNeil Armstrong 864*9e80f906SNeil Armstrong static const struct of_device_id sx150x_of_match[] = { 865*9e80f906SNeil Armstrong { .compatible = "semtech,sx1508q" }, 866*9e80f906SNeil Armstrong { .compatible = "semtech,sx1509q" }, 867*9e80f906SNeil Armstrong { .compatible = "semtech,sx1506q" }, 868*9e80f906SNeil Armstrong { .compatible = "semtech,sx1502q" }, 869*9e80f906SNeil Armstrong {}, 870*9e80f906SNeil Armstrong }; 871*9e80f906SNeil Armstrong 872*9e80f906SNeil Armstrong static int sx150x_init_io(struct sx150x_pinctrl *pctl, u8 base, u16 cfg) 873*9e80f906SNeil Armstrong { 874*9e80f906SNeil Armstrong int err = 0; 875*9e80f906SNeil Armstrong unsigned int n; 876*9e80f906SNeil Armstrong 877*9e80f906SNeil Armstrong for (n = 0; err >= 0 && n < (pctl->data->ngpios / 8); ++n) 878*9e80f906SNeil Armstrong err = sx150x_i2c_write(pctl->client, base - n, cfg >> (n * 8)); 879*9e80f906SNeil Armstrong return err; 880*9e80f906SNeil Armstrong } 881*9e80f906SNeil Armstrong 882*9e80f906SNeil Armstrong static int sx150x_reset(struct sx150x_pinctrl *pctl) 883*9e80f906SNeil Armstrong { 884*9e80f906SNeil Armstrong int err; 885*9e80f906SNeil Armstrong 886*9e80f906SNeil Armstrong err = i2c_smbus_write_byte_data(pctl->client, 887*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_reset, 888*9e80f906SNeil Armstrong 0x12); 889*9e80f906SNeil Armstrong if (err < 0) 890*9e80f906SNeil Armstrong return err; 891*9e80f906SNeil Armstrong 892*9e80f906SNeil Armstrong err = i2c_smbus_write_byte_data(pctl->client, 893*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_reset, 894*9e80f906SNeil Armstrong 0x34); 895*9e80f906SNeil Armstrong return err; 896*9e80f906SNeil Armstrong } 897*9e80f906SNeil Armstrong 898*9e80f906SNeil Armstrong static int sx150x_init_hw(struct sx150x_pinctrl *pctl) 899*9e80f906SNeil Armstrong { 900*9e80f906SNeil Armstrong int err; 901*9e80f906SNeil Armstrong 902*9e80f906SNeil Armstrong if (pctl->data->model == SX150X_789 && 903*9e80f906SNeil Armstrong of_property_read_bool(pctl->dev->of_node, "semtech,probe-reset")) { 904*9e80f906SNeil Armstrong err = sx150x_reset(pctl); 905*9e80f906SNeil Armstrong if (err < 0) 906*9e80f906SNeil Armstrong return err; 907*9e80f906SNeil Armstrong } 908*9e80f906SNeil Armstrong 909*9e80f906SNeil Armstrong if (pctl->data->model == SX150X_789) 910*9e80f906SNeil Armstrong err = sx150x_i2c_write(pctl->client, 911*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_misc, 912*9e80f906SNeil Armstrong 0x01); 913*9e80f906SNeil Armstrong else if (pctl->data->model == SX150X_456) 914*9e80f906SNeil Armstrong err = sx150x_i2c_write(pctl->client, 915*9e80f906SNeil Armstrong pctl->data->pri.x456.reg_advance, 916*9e80f906SNeil Armstrong 0x04); 917*9e80f906SNeil Armstrong else 918*9e80f906SNeil Armstrong err = sx150x_i2c_write(pctl->client, 919*9e80f906SNeil Armstrong pctl->data->pri.x123.reg_advance, 920*9e80f906SNeil Armstrong 0x00); 921*9e80f906SNeil Armstrong if (err < 0) 922*9e80f906SNeil Armstrong return err; 923*9e80f906SNeil Armstrong 924*9e80f906SNeil Armstrong /* Set all pins to work in normal mode */ 925*9e80f906SNeil Armstrong if (pctl->data->model == SX150X_789) { 926*9e80f906SNeil Armstrong err = sx150x_init_io(pctl, 927*9e80f906SNeil Armstrong pctl->data->pri.x789.reg_polarity, 928*9e80f906SNeil Armstrong 0); 929*9e80f906SNeil Armstrong if (err < 0) 930*9e80f906SNeil Armstrong return err; 931*9e80f906SNeil Armstrong } else if (pctl->data->model == SX150X_456) { 932*9e80f906SNeil Armstrong /* Set all pins to work in normal mode */ 933*9e80f906SNeil Armstrong err = sx150x_init_io(pctl, 934*9e80f906SNeil Armstrong pctl->data->pri.x456.reg_pld_mode, 935*9e80f906SNeil Armstrong 0); 936*9e80f906SNeil Armstrong if (err < 0) 937*9e80f906SNeil Armstrong return err; 938*9e80f906SNeil Armstrong } else { 939*9e80f906SNeil Armstrong /* Set all pins to work in normal mode */ 940*9e80f906SNeil Armstrong err = sx150x_init_io(pctl, 941*9e80f906SNeil Armstrong pctl->data->pri.x123.reg_pld_mode, 942*9e80f906SNeil Armstrong 0); 943*9e80f906SNeil Armstrong if (err < 0) 944*9e80f906SNeil Armstrong return err; 945*9e80f906SNeil Armstrong } 946*9e80f906SNeil Armstrong 947*9e80f906SNeil Armstrong return 0; 948*9e80f906SNeil Armstrong } 949*9e80f906SNeil Armstrong 950*9e80f906SNeil Armstrong static int sx150x_probe(struct i2c_client *client, 951*9e80f906SNeil Armstrong const struct i2c_device_id *id) 952*9e80f906SNeil Armstrong { 953*9e80f906SNeil Armstrong static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA | 954*9e80f906SNeil Armstrong I2C_FUNC_SMBUS_WRITE_WORD_DATA; 955*9e80f906SNeil Armstrong struct device *dev = &client->dev; 956*9e80f906SNeil Armstrong struct sx150x_pinctrl *pctl; 957*9e80f906SNeil Armstrong int ret; 958*9e80f906SNeil Armstrong 959*9e80f906SNeil Armstrong if (!id->driver_data) 960*9e80f906SNeil Armstrong return -EINVAL; 961*9e80f906SNeil Armstrong 962*9e80f906SNeil Armstrong if (!i2c_check_functionality(client->adapter, i2c_funcs)) 963*9e80f906SNeil Armstrong return -ENOSYS; 964*9e80f906SNeil Armstrong 965*9e80f906SNeil Armstrong pctl = devm_kzalloc(dev, sizeof(*pctl), GFP_KERNEL); 966*9e80f906SNeil Armstrong if (!pctl) 967*9e80f906SNeil Armstrong return -ENOMEM; 968*9e80f906SNeil Armstrong 969*9e80f906SNeil Armstrong pctl->dev = dev; 970*9e80f906SNeil Armstrong pctl->client = client; 971*9e80f906SNeil Armstrong pctl->data = (void *)id->driver_data; 972*9e80f906SNeil Armstrong 973*9e80f906SNeil Armstrong mutex_init(&pctl->lock); 974*9e80f906SNeil Armstrong 975*9e80f906SNeil Armstrong ret = sx150x_init_hw(pctl); 976*9e80f906SNeil Armstrong if (ret) 977*9e80f906SNeil Armstrong return ret; 978*9e80f906SNeil Armstrong 979*9e80f906SNeil Armstrong /* Register GPIO controller */ 980*9e80f906SNeil Armstrong pctl->gpio.label = devm_kstrdup(dev, client->name, GFP_KERNEL); 981*9e80f906SNeil Armstrong pctl->gpio.base = -1; 982*9e80f906SNeil Armstrong pctl->gpio.ngpio = pctl->data->npins; 983*9e80f906SNeil Armstrong pctl->gpio.get_direction = sx150x_gpio_get_direction; 984*9e80f906SNeil Armstrong pctl->gpio.direction_input = sx150x_gpio_direction_input; 985*9e80f906SNeil Armstrong pctl->gpio.direction_output = sx150x_gpio_direction_output; 986*9e80f906SNeil Armstrong pctl->gpio.get = sx150x_gpio_get; 987*9e80f906SNeil Armstrong pctl->gpio.set = sx150x_gpio_set; 988*9e80f906SNeil Armstrong pctl->gpio.set_single_ended = sx150x_gpio_set_single_ended; 989*9e80f906SNeil Armstrong pctl->gpio.parent = dev; 990*9e80f906SNeil Armstrong #ifdef CONFIG_OF_GPIO 991*9e80f906SNeil Armstrong pctl->gpio.of_node = dev->of_node; 992*9e80f906SNeil Armstrong #endif 993*9e80f906SNeil Armstrong pctl->gpio.can_sleep = true; 994*9e80f906SNeil Armstrong 995*9e80f906SNeil Armstrong ret = devm_gpiochip_add_data(dev, &pctl->gpio, pctl); 996*9e80f906SNeil Armstrong if (ret) 997*9e80f906SNeil Armstrong return ret; 998*9e80f906SNeil Armstrong 999*9e80f906SNeil Armstrong /* Add Interrupt support if an irq is specified */ 1000*9e80f906SNeil Armstrong if (client->irq > 0) { 1001*9e80f906SNeil Armstrong pctl->irq_chip.name = devm_kstrdup(dev, client->name, 1002*9e80f906SNeil Armstrong GFP_KERNEL); 1003*9e80f906SNeil Armstrong pctl->irq_chip.irq_mask = sx150x_irq_mask; 1004*9e80f906SNeil Armstrong pctl->irq_chip.irq_unmask = sx150x_irq_unmask; 1005*9e80f906SNeil Armstrong pctl->irq_chip.irq_set_type = sx150x_irq_set_type; 1006*9e80f906SNeil Armstrong pctl->irq_chip.irq_bus_lock = sx150x_irq_bus_lock; 1007*9e80f906SNeil Armstrong pctl->irq_chip.irq_bus_sync_unlock = sx150x_irq_bus_sync_unlock; 1008*9e80f906SNeil Armstrong 1009*9e80f906SNeil Armstrong pctl->irq.masked = ~0; 1010*9e80f906SNeil Armstrong pctl->irq.sense = 0; 1011*9e80f906SNeil Armstrong pctl->irq.dev_masked = ~0; 1012*9e80f906SNeil Armstrong pctl->irq.dev_sense = 0; 1013*9e80f906SNeil Armstrong pctl->irq.update = -1; 1014*9e80f906SNeil Armstrong 1015*9e80f906SNeil Armstrong ret = gpiochip_irqchip_add(&pctl->gpio, 1016*9e80f906SNeil Armstrong &pctl->irq_chip, 0, 1017*9e80f906SNeil Armstrong handle_edge_irq, IRQ_TYPE_NONE); 1018*9e80f906SNeil Armstrong if (ret) { 1019*9e80f906SNeil Armstrong dev_err(dev, "could not connect irqchip to gpiochip\n"); 1020*9e80f906SNeil Armstrong return ret; 1021*9e80f906SNeil Armstrong } 1022*9e80f906SNeil Armstrong 1023*9e80f906SNeil Armstrong ret = devm_request_threaded_irq(dev, client->irq, NULL, 1024*9e80f906SNeil Armstrong sx150x_irq_thread_fn, 1025*9e80f906SNeil Armstrong IRQF_ONESHOT | IRQF_SHARED | 1026*9e80f906SNeil Armstrong IRQF_TRIGGER_FALLING, 1027*9e80f906SNeil Armstrong pctl->irq_chip.name, pctl); 1028*9e80f906SNeil Armstrong if (ret < 0) 1029*9e80f906SNeil Armstrong return ret; 1030*9e80f906SNeil Armstrong } 1031*9e80f906SNeil Armstrong 1032*9e80f906SNeil Armstrong /* Pinctrl_desc */ 1033*9e80f906SNeil Armstrong pctl->pinctrl_desc.name = "sx150x-pinctrl"; 1034*9e80f906SNeil Armstrong pctl->pinctrl_desc.pctlops = &sx150x_pinctrl_ops; 1035*9e80f906SNeil Armstrong pctl->pinctrl_desc.confops = &sx150x_pinconf_ops; 1036*9e80f906SNeil Armstrong pctl->pinctrl_desc.pins = pctl->data->pins; 1037*9e80f906SNeil Armstrong pctl->pinctrl_desc.npins = pctl->data->npins; 1038*9e80f906SNeil Armstrong pctl->pinctrl_desc.owner = THIS_MODULE; 1039*9e80f906SNeil Armstrong 1040*9e80f906SNeil Armstrong pctl->pctldev = pinctrl_register(&pctl->pinctrl_desc, dev, pctl); 1041*9e80f906SNeil Armstrong if (IS_ERR(pctl->pctldev)) { 1042*9e80f906SNeil Armstrong dev_err(dev, "Failed to register pinctrl device\n"); 1043*9e80f906SNeil Armstrong return PTR_ERR(pctl->pctldev); 1044*9e80f906SNeil Armstrong } 1045*9e80f906SNeil Armstrong 1046*9e80f906SNeil Armstrong return 0; 1047*9e80f906SNeil Armstrong } 1048*9e80f906SNeil Armstrong 1049*9e80f906SNeil Armstrong static struct i2c_driver sx150x_driver = { 1050*9e80f906SNeil Armstrong .driver = { 1051*9e80f906SNeil Armstrong .name = "sx150x-pinctrl", 1052*9e80f906SNeil Armstrong .of_match_table = of_match_ptr(sx150x_of_match), 1053*9e80f906SNeil Armstrong }, 1054*9e80f906SNeil Armstrong .probe = sx150x_probe, 1055*9e80f906SNeil Armstrong .id_table = sx150x_id, 1056*9e80f906SNeil Armstrong }; 1057*9e80f906SNeil Armstrong 1058*9e80f906SNeil Armstrong static int __init sx150x_init(void) 1059*9e80f906SNeil Armstrong { 1060*9e80f906SNeil Armstrong return i2c_add_driver(&sx150x_driver); 1061*9e80f906SNeil Armstrong } 1062*9e80f906SNeil Armstrong subsys_initcall(sx150x_init); 1063