605 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// CS42L43 Pinctrl and GPIO driver4//5// Copyright (c) 2023 Cirrus Logic, Inc. and6// Cirrus Logic International Semiconductor Ltd.7 8#include <linux/array_size.h>9#include <linux/bits.h>10#include <linux/build_bug.h>11#include <linux/err.h>12#include <linux/gpio/driver.h>13#include <linux/mfd/cs42l43.h>14#include <linux/mfd/cs42l43-regs.h>15#include <linux/module.h>16#include <linux/of.h>17#include <linux/platform_device.h>18#include <linux/pm_runtime.h>19#include <linux/regmap.h>20#include <linux/string_choices.h>21 22#include <linux/pinctrl/consumer.h>23#include <linux/pinctrl/pinctrl.h>24#include <linux/pinctrl/pinconf.h>25#include <linux/pinctrl/pinconf-generic.h>26#include <linux/pinctrl/pinmux.h>27 28#include "../pinctrl-utils.h"29 30#define CS42L43_NUM_GPIOS 331 32struct cs42l43_pin {33 struct gpio_chip gpio_chip;34 35 struct device *dev;36 struct regmap *regmap;37 bool shutters_locked;38};39 40struct cs42l43_pin_data {41 unsigned int reg;42 unsigned int shift;43 unsigned int mask;44};45 46#define CS42L43_PIN(_number, _name, _reg, _field) { \47 .number = _number, .name = _name, \48 .drv_data = &((struct cs42l43_pin_data){ \49 .reg = CS42L43_##_reg, \50 .shift = CS42L43_##_field##_DRV_SHIFT, \51 .mask = CS42L43_##_field##_DRV_MASK, \52 }), \53}54 55static const struct pinctrl_pin_desc cs42l43_pin_pins[] = {56 CS42L43_PIN(0, "gpio1", DRV_CTRL4, GPIO1),57 CS42L43_PIN(1, "gpio2", DRV_CTRL4, GPIO2),58 CS42L43_PIN(2, "gpio3", DRV_CTRL4, GPIO3),59 CS42L43_PIN(3, "asp_dout", DRV_CTRL1, ASP_DOUT),60 CS42L43_PIN(4, "asp_fsync", DRV_CTRL1, ASP_FSYNC),61 CS42L43_PIN(5, "asp_bclk", DRV_CTRL1, ASP_BCLK),62 CS42L43_PIN(6, "pdmout2_clk", DRV_CTRL3, PDMOUT2_CLK),63 CS42L43_PIN(7, "pdmout2_data", DRV_CTRL3, PDMOUT2_DATA),64 CS42L43_PIN(8, "pdmout1_clk", DRV_CTRL3, PDMOUT1_CLK),65 CS42L43_PIN(9, "pdmout1_data", DRV_CTRL3, PDMOUT1_DATA),66 CS42L43_PIN(10, "i2c_sda", DRV_CTRL3, I2C_SDA),67 CS42L43_PIN(11, "i2c_scl", DRV_CTRL_5, I2C_SCL),68 CS42L43_PIN(12, "spi_miso", DRV_CTRL3, SPI_MISO),69 CS42L43_PIN(13, "spi_sck", DRV_CTRL_5, SPI_SCK),70 CS42L43_PIN(14, "spi_ssb", DRV_CTRL_5, SPI_SSB),71};72 73static const unsigned int cs42l43_pin_gpio1_pins[] = { 0 };74static const unsigned int cs42l43_pin_gpio2_pins[] = { 1 };75static const unsigned int cs42l43_pin_gpio3_pins[] = { 2 };76static const unsigned int cs42l43_pin_asp_pins[] = { 3, 4, 5 };77static const unsigned int cs42l43_pin_pdmout2_pins[] = { 6, 7 };78static const unsigned int cs42l43_pin_pdmout1_pins[] = { 8, 9 };79static const unsigned int cs42l43_pin_i2c_pins[] = { 10, 11 };80static const unsigned int cs42l43_pin_spi_pins[] = { 12, 13, 14 };81 82#define CS42L43_PINGROUP(_name) \83 PINCTRL_PINGROUP(#_name, cs42l43_pin_##_name##_pins, \84 ARRAY_SIZE(cs42l43_pin_##_name##_pins))85 86static const struct pingroup cs42l43_pin_groups[] = {87 CS42L43_PINGROUP(gpio1),88 CS42L43_PINGROUP(gpio2),89 CS42L43_PINGROUP(gpio3),90 CS42L43_PINGROUP(asp),91 CS42L43_PINGROUP(pdmout2),92 CS42L43_PINGROUP(pdmout1),93 CS42L43_PINGROUP(i2c),94 CS42L43_PINGROUP(spi),95};96 97static int cs42l43_pin_get_groups_count(struct pinctrl_dev *pctldev)98{99 return ARRAY_SIZE(cs42l43_pin_groups);100}101 102static const char *cs42l43_pin_get_group_name(struct pinctrl_dev *pctldev,103 unsigned int group_idx)104{105 return cs42l43_pin_groups[group_idx].name;106}107 108static int cs42l43_pin_get_group_pins(struct pinctrl_dev *pctldev,109 unsigned int group_idx,110 const unsigned int **pins,111 unsigned int *num_pins)112{113 *pins = cs42l43_pin_groups[group_idx].pins;114 *num_pins = cs42l43_pin_groups[group_idx].npins;115 116 return 0;117}118 119static const struct pinctrl_ops cs42l43_pin_group_ops = {120 .get_groups_count = cs42l43_pin_get_groups_count,121 .get_group_name = cs42l43_pin_get_group_name,122 .get_group_pins = cs42l43_pin_get_group_pins,123#if IS_ENABLED(CONFIG_OF)124 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,125 .dt_free_map = pinconf_generic_dt_free_map,126#endif127};128 129enum cs42l43_pin_funcs {130 CS42L43_FUNC_GPIO,131 CS42L43_FUNC_SPDIF,132 CS42L43_FUNC_IRQ,133 CS42L43_FUNC_MIC_SHT,134 CS42L43_FUNC_SPK_SHT,135 CS42L43_FUNC_MAX136};137 138static const char * const cs42l43_pin_funcs[] = {139 "gpio", "spdif", "irq", "mic-shutter", "spk-shutter",140};141 142static const char * const cs42l43_pin_gpio_groups[] = { "gpio1", "gpio3" };143static const char * const cs42l43_pin_spdif_groups[] = { "gpio3" };144static const char * const cs42l43_pin_irq_groups[] = { "gpio1" };145static const char * const cs42l43_pin_shutter_groups[] = { "gpio1", "gpio2", "gpio3" };146 147static const struct pinfunction cs42l43_pin_func_groups[] = {148 PINCTRL_PINFUNCTION("gpio", cs42l43_pin_gpio_groups,149 ARRAY_SIZE(cs42l43_pin_gpio_groups)),150 PINCTRL_PINFUNCTION("spdif", cs42l43_pin_spdif_groups,151 ARRAY_SIZE(cs42l43_pin_spdif_groups)),152 PINCTRL_PINFUNCTION("irq", cs42l43_pin_irq_groups,153 ARRAY_SIZE(cs42l43_pin_irq_groups)),154 PINCTRL_PINFUNCTION("mic-shutter", cs42l43_pin_shutter_groups,155 ARRAY_SIZE(cs42l43_pin_shutter_groups)),156 PINCTRL_PINFUNCTION("spk-shutter", cs42l43_pin_shutter_groups,157 ARRAY_SIZE(cs42l43_pin_shutter_groups)),158};159 160static_assert(ARRAY_SIZE(cs42l43_pin_funcs) == CS42L43_FUNC_MAX);161static_assert(ARRAY_SIZE(cs42l43_pin_func_groups) == CS42L43_FUNC_MAX);162 163static int cs42l43_pin_get_func_count(struct pinctrl_dev *pctldev)164{165 return ARRAY_SIZE(cs42l43_pin_funcs);166}167 168static const char *cs42l43_pin_get_func_name(struct pinctrl_dev *pctldev,169 unsigned int func_idx)170{171 return cs42l43_pin_funcs[func_idx];172}173 174static int cs42l43_pin_get_func_groups(struct pinctrl_dev *pctldev,175 unsigned int func_idx,176 const char * const **groups,177 unsigned int * const num_groups)178{179 *groups = cs42l43_pin_func_groups[func_idx].groups;180 *num_groups = cs42l43_pin_func_groups[func_idx].ngroups;181 182 return 0;183}184 185static int cs42l43_pin_set_mux(struct pinctrl_dev *pctldev,186 unsigned int func_idx, unsigned int group_idx)187{188 struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);189 unsigned int reg, mask, val;190 191 dev_dbg(priv->dev, "Setting %s to %s\n",192 cs42l43_pin_groups[group_idx].name, cs42l43_pin_funcs[func_idx]);193 194 switch (func_idx) {195 case CS42L43_FUNC_MIC_SHT:196 reg = CS42L43_SHUTTER_CONTROL;197 mask = CS42L43_MIC_SHUTTER_CFG_MASK;198 val = 0x2 << (group_idx + CS42L43_MIC_SHUTTER_CFG_SHIFT);199 break;200 case CS42L43_FUNC_SPK_SHT:201 reg = CS42L43_SHUTTER_CONTROL;202 mask = CS42L43_SPK_SHUTTER_CFG_MASK;203 val = 0x2 << (group_idx + CS42L43_SPK_SHUTTER_CFG_SHIFT);204 break;205 default:206 reg = CS42L43_GPIO_FN_SEL;207 mask = BIT(group_idx + CS42L43_GPIO1_FN_SEL_SHIFT);208 val = (func_idx == CS42L43_FUNC_GPIO) ?209 (0x1 << (group_idx + CS42L43_GPIO1_FN_SEL_SHIFT)) : 0;210 break;211 }212 213 if (priv->shutters_locked && reg == CS42L43_SHUTTER_CONTROL) {214 dev_err(priv->dev, "Shutter configuration not available\n");215 return -EPERM;216 }217 218 return regmap_update_bits(priv->regmap, reg, mask, val);219}220 221static int cs42l43_gpio_set_direction(struct pinctrl_dev *pctldev,222 struct pinctrl_gpio_range *range,223 unsigned int offset, bool input)224{225 struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);226 unsigned int shift = offset + CS42L43_GPIO1_DIR_SHIFT;227 int ret;228 229 dev_dbg(priv->dev, "Setting gpio%d to %s\n",230 offset + 1, input ? "input" : "output");231 232 ret = pm_runtime_resume_and_get(priv->dev);233 if (ret) {234 dev_err(priv->dev, "Failed to resume for direction: %d\n", ret);235 return ret;236 }237 238 ret = regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL1,239 BIT(shift), !!input << shift);240 if (ret)241 dev_err(priv->dev, "Failed to set gpio%d direction: %d\n",242 offset + 1, ret);243 244 pm_runtime_put(priv->dev);245 246 return ret;247}248 249static int cs42l43_gpio_request_enable(struct pinctrl_dev *pctldev,250 struct pinctrl_gpio_range *range,251 unsigned int offset)252{253 return cs42l43_pin_set_mux(pctldev, 0, offset);254}255 256static void cs42l43_gpio_disable_free(struct pinctrl_dev *pctldev,257 struct pinctrl_gpio_range *range,258 unsigned int offset)259{260 cs42l43_gpio_set_direction(pctldev, range, offset, true);261}262 263static const struct pinmux_ops cs42l43_pin_mux_ops = {264 .get_functions_count = cs42l43_pin_get_func_count,265 .get_function_name = cs42l43_pin_get_func_name,266 .get_function_groups = cs42l43_pin_get_func_groups,267 268 .set_mux = cs42l43_pin_set_mux,269 270 .gpio_request_enable = cs42l43_gpio_request_enable,271 .gpio_disable_free = cs42l43_gpio_disable_free,272 .gpio_set_direction = cs42l43_gpio_set_direction,273 274 .strict = true,275};276 277static const unsigned int cs42l43_pin_drv_str_ma[] = { 1, 2, 4, 8, 9, 10, 12, 16 };278 279static int cs42l43_pin_get_drv_str(struct cs42l43_pin *priv, unsigned int pin)280{281 const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;282 unsigned int val;283 int ret;284 285 ret = regmap_read(priv->regmap, pdat->reg, &val);286 if (ret)287 return ret;288 289 return cs42l43_pin_drv_str_ma[(val & pdat->mask) >> pdat->shift];290}291 292static int cs42l43_pin_set_drv_str(struct cs42l43_pin *priv, unsigned int pin,293 unsigned int ma)294{295 const struct cs42l43_pin_data *pdat = cs42l43_pin_pins[pin].drv_data;296 int i;297 298 for (i = 0; i < ARRAY_SIZE(cs42l43_pin_drv_str_ma); i++) {299 if (ma == cs42l43_pin_drv_str_ma[i]) {300 if ((i << pdat->shift) > pdat->mask)301 goto err;302 303 dev_dbg(priv->dev, "Set drive strength for %s to %d mA\n",304 cs42l43_pin_pins[pin].name, ma);305 306 return regmap_update_bits(priv->regmap, pdat->reg,307 pdat->mask, i << pdat->shift);308 }309 }310 311err:312 dev_err(priv->dev, "Invalid drive strength for %s: %d mA\n",313 cs42l43_pin_pins[pin].name, ma);314 return -EINVAL;315}316 317static int cs42l43_pin_get_db(struct cs42l43_pin *priv, unsigned int pin)318{319 unsigned int val;320 int ret;321 322 if (pin >= CS42L43_NUM_GPIOS)323 return -ENOTSUPP;324 325 ret = regmap_read(priv->regmap, CS42L43_GPIO_CTRL2, &val);326 if (ret)327 return ret;328 329 if (val & (CS42L43_GPIO1_DEGLITCH_BYP_MASK << pin))330 return 0;331 332 return 85; // Debounce is roughly 85uS333}334 335static int cs42l43_pin_set_db(struct cs42l43_pin *priv, unsigned int pin,336 unsigned int us)337{338 if (pin >= CS42L43_NUM_GPIOS)339 return -ENOTSUPP;340 341 dev_dbg(priv->dev, "Set debounce %s for %s\n",342 str_on_off(us), cs42l43_pin_pins[pin].name);343 344 return regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL2,345 CS42L43_GPIO1_DEGLITCH_BYP_MASK << pin,346 !!us << pin);347}348 349static int cs42l43_pin_config_get(struct pinctrl_dev *pctldev,350 unsigned int pin, unsigned long *config)351{352 struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);353 unsigned int param = pinconf_to_config_param(*config);354 int ret;355 356 switch (param) {357 case PIN_CONFIG_DRIVE_STRENGTH:358 ret = cs42l43_pin_get_drv_str(priv, pin);359 if (ret < 0)360 return ret;361 break;362 case PIN_CONFIG_INPUT_DEBOUNCE:363 ret = cs42l43_pin_get_db(priv, pin);364 if (ret < 0)365 return ret;366 break;367 default:368 return -ENOTSUPP;369 }370 371 *config = pinconf_to_config_packed(param, ret);372 373 return 0;374}375 376static int cs42l43_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,377 unsigned long *configs, unsigned int num_configs)378{379 struct cs42l43_pin *priv = pinctrl_dev_get_drvdata(pctldev);380 unsigned int val;381 int ret;382 383 while (num_configs) {384 val = pinconf_to_config_argument(*configs);385 386 switch (pinconf_to_config_param(*configs)) {387 case PIN_CONFIG_DRIVE_STRENGTH:388 ret = cs42l43_pin_set_drv_str(priv, pin, val);389 if (ret)390 return ret;391 break;392 case PIN_CONFIG_INPUT_DEBOUNCE:393 ret = cs42l43_pin_set_db(priv, pin, val);394 if (ret)395 return ret;396 break;397 default:398 return -ENOTSUPP;399 }400 401 configs++;402 num_configs--;403 }404 405 return 0;406}407 408static int cs42l43_pin_config_group_get(struct pinctrl_dev *pctldev,409 unsigned int selector, unsigned long *config)410{411 int i, ret;412 413 for (i = 0; i < cs42l43_pin_groups[selector].npins; ++i) {414 ret = cs42l43_pin_config_get(pctldev,415 cs42l43_pin_groups[selector].pins[i],416 config);417 if (ret)418 return ret;419 }420 421 return 0;422}423 424static int cs42l43_pin_config_group_set(struct pinctrl_dev *pctldev,425 unsigned int selector,426 unsigned long *configs,427 unsigned int num_configs)428{429 int i, ret;430 431 for (i = 0; i < cs42l43_pin_groups[selector].npins; ++i) {432 ret = cs42l43_pin_config_set(pctldev,433 cs42l43_pin_groups[selector].pins[i],434 configs, num_configs);435 if (ret)436 return ret;437 }438 439 return 0;440}441 442static const struct pinconf_ops cs42l43_pin_conf_ops = {443 .is_generic = true,444 445 .pin_config_get = cs42l43_pin_config_get,446 .pin_config_set = cs42l43_pin_config_set,447 .pin_config_group_get = cs42l43_pin_config_group_get,448 .pin_config_group_set = cs42l43_pin_config_group_set,449};450 451static struct pinctrl_desc cs42l43_pin_desc = {452 .name = "cs42l43-pinctrl",453 .owner = THIS_MODULE,454 455 .pins = cs42l43_pin_pins,456 .npins = ARRAY_SIZE(cs42l43_pin_pins),457 458 .pctlops = &cs42l43_pin_group_ops,459 .pmxops = &cs42l43_pin_mux_ops,460 .confops = &cs42l43_pin_conf_ops,461};462 463static int cs42l43_gpio_get(struct gpio_chip *chip, unsigned int offset)464{465 struct cs42l43_pin *priv = gpiochip_get_data(chip);466 unsigned int val;467 int ret;468 469 ret = pm_runtime_resume_and_get(priv->dev);470 if (ret) {471 dev_err(priv->dev, "Failed to resume for get: %d\n", ret);472 return ret;473 }474 475 ret = regmap_read(priv->regmap, CS42L43_GPIO_STS, &val);476 if (ret)477 dev_err(priv->dev, "Failed to get gpio%d: %d\n", offset + 1, ret);478 else479 ret = !!(val & BIT(offset + CS42L43_GPIO1_STS_SHIFT));480 481 pm_runtime_put(priv->dev);482 483 return ret;484}485 486static void cs42l43_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)487{488 struct cs42l43_pin *priv = gpiochip_get_data(chip);489 unsigned int shift = offset + CS42L43_GPIO1_LVL_SHIFT;490 int ret;491 492 dev_dbg(priv->dev, "Setting gpio%d to %s\n",493 offset + 1, str_high_low(value));494 495 ret = pm_runtime_resume_and_get(priv->dev);496 if (ret) {497 dev_err(priv->dev, "Failed to resume for set: %d\n", ret);498 return;499 }500 501 ret = regmap_update_bits(priv->regmap, CS42L43_GPIO_CTRL1,502 BIT(shift), value << shift);503 if (ret)504 dev_err(priv->dev, "Failed to set gpio%d: %d\n", offset + 1, ret);505 506 pm_runtime_put(priv->dev);507}508 509static int cs42l43_gpio_direction_out(struct gpio_chip *chip,510 unsigned int offset, int value)511{512 cs42l43_gpio_set(chip, offset, value);513 514 return pinctrl_gpio_direction_output(chip, offset);515}516 517static int cs42l43_gpio_add_pin_ranges(struct gpio_chip *chip)518{519 struct cs42l43_pin *priv = gpiochip_get_data(chip);520 int ret;521 522 ret = gpiochip_add_pin_range(&priv->gpio_chip, priv->gpio_chip.label,523 0, 0, CS42L43_NUM_GPIOS);524 if (ret)525 dev_err(priv->dev, "Failed to add GPIO pin range: %d\n", ret);526 527 return ret;528}529 530static int cs42l43_pin_probe(struct platform_device *pdev)531{532 struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);533 struct cs42l43_pin *priv;534 struct pinctrl_dev *pctldev;535 struct fwnode_handle *fwnode = dev_fwnode(cs42l43->dev);536 int ret;537 538 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);539 if (!priv)540 return -ENOMEM;541 542 priv->dev = &pdev->dev;543 priv->regmap = cs42l43->regmap;544 545 priv->shutters_locked = cs42l43->hw_lock;546 547 priv->gpio_chip.request = gpiochip_generic_request;548 priv->gpio_chip.free = gpiochip_generic_free;549 priv->gpio_chip.direction_input = pinctrl_gpio_direction_input;550 priv->gpio_chip.direction_output = cs42l43_gpio_direction_out;551 priv->gpio_chip.add_pin_ranges = cs42l43_gpio_add_pin_ranges;552 priv->gpio_chip.get = cs42l43_gpio_get;553 priv->gpio_chip.set = cs42l43_gpio_set;554 priv->gpio_chip.label = dev_name(priv->dev);555 priv->gpio_chip.parent = priv->dev;556 priv->gpio_chip.can_sleep = true;557 priv->gpio_chip.base = -1;558 priv->gpio_chip.ngpio = CS42L43_NUM_GPIOS;559 560 if (is_of_node(fwnode)) {561 fwnode = fwnode_get_named_child_node(fwnode, "pinctrl");562 563 if (fwnode && !fwnode->dev)564 fwnode->dev = priv->dev;565 }566 567 priv->gpio_chip.fwnode = fwnode;568 569 device_set_node(priv->dev, fwnode);570 571 devm_pm_runtime_enable(priv->dev);572 pm_runtime_idle(priv->dev);573 574 pctldev = devm_pinctrl_register(priv->dev, &cs42l43_pin_desc, priv);575 if (IS_ERR(pctldev))576 return dev_err_probe(priv->dev, PTR_ERR(pctldev),577 "Failed to register pinctrl\n");578 579 ret = devm_gpiochip_add_data(priv->dev, &priv->gpio_chip, priv);580 if (ret)581 return dev_err_probe(priv->dev, ret,582 "Failed to register gpiochip\n");583 584 return 0;585}586 587static const struct platform_device_id cs42l43_pin_id_table[] = {588 { "cs42l43-pinctrl", },589 {}590};591MODULE_DEVICE_TABLE(platform, cs42l43_pin_id_table);592 593static struct platform_driver cs42l43_pin_driver = {594 .driver = {595 .name = "cs42l43-pinctrl",596 },597 .probe = cs42l43_pin_probe,598 .id_table = cs42l43_pin_id_table,599};600module_platform_driver(cs42l43_pin_driver);601 602MODULE_DESCRIPTION("CS42L43 Pinctrl Driver");603MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");604MODULE_LICENSE("GPL");605