linux/sound/soc/soc-ac97.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// soc-ac97.c  --  ALSA SoC Audio Layer AC97 support
   4//
   5// Copyright 2005 Wolfson Microelectronics PLC.
   6// Copyright 2005 Openedhand Ltd.
   7// Copyright (C) 2010 Slimlogic Ltd.
   8// Copyright (C) 2010 Texas Instruments Inc.
   9//
  10// Author: Liam Girdwood <lrg@slimlogic.co.uk>
  11//         with code, comments and ideas from :-
  12//         Richard Purdie <richard@openedhand.com>
  13
  14#include <linux/ctype.h>
  15#include <linux/delay.h>
  16#include <linux/export.h>
  17#include <linux/gpio.h>
  18#include <linux/gpio/driver.h>
  19#include <linux/init.h>
  20#include <linux/of_gpio.h>
  21#include <linux/of.h>
  22#include <linux/pinctrl/consumer.h>
  23#include <linux/slab.h>
  24#include <sound/ac97_codec.h>
  25#include <sound/soc.h>
  26
  27struct snd_ac97_reset_cfg {
  28        struct pinctrl *pctl;
  29        struct pinctrl_state *pstate_reset;
  30        struct pinctrl_state *pstate_warm_reset;
  31        struct pinctrl_state *pstate_run;
  32        int gpio_sdata;
  33        int gpio_sync;
  34        int gpio_reset;
  35};
  36
  37struct snd_ac97_gpio_priv {
  38#ifdef CONFIG_GPIOLIB
  39        struct gpio_chip gpio_chip;
  40#endif
  41        unsigned int gpios_set;
  42        struct snd_soc_component *component;
  43};
  44
  45static struct snd_ac97_bus soc_ac97_bus = {
  46        .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
  47};
  48
  49static void soc_ac97_device_release(struct device *dev)
  50{
  51        kfree(to_ac97_t(dev));
  52}
  53
  54#ifdef CONFIG_GPIOLIB
  55static inline struct snd_soc_component *gpio_to_component(struct gpio_chip *chip)
  56{
  57        struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
  58
  59        return gpio_priv->component;
  60}
  61
  62static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
  63{
  64        if (offset >= AC97_NUM_GPIOS)
  65                return -EINVAL;
  66
  67        return 0;
  68}
  69
  70static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
  71                                          unsigned offset)
  72{
  73        struct snd_soc_component *component = gpio_to_component(chip);
  74
  75        dev_dbg(component->dev, "set gpio %d to output\n", offset);
  76        return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
  77                                   1 << offset, 1 << offset);
  78}
  79
  80static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
  81{
  82        struct snd_soc_component *component = gpio_to_component(chip);
  83        int ret;
  84
  85        if (snd_soc_component_read(component, AC97_GPIO_STATUS, &ret) < 0)
  86                ret = -1;
  87
  88        dev_dbg(component->dev, "get gpio %d : %d\n", offset,
  89                ret < 0 ? ret : ret & (1 << offset));
  90
  91        return ret < 0 ? ret : !!(ret & (1 << offset));
  92}
  93
  94static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
  95                                  int value)
  96{
  97        struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
  98        struct snd_soc_component *component = gpio_to_component(chip);
  99
 100        gpio_priv->gpios_set &= ~(1 << offset);
 101        gpio_priv->gpios_set |= (!!value) << offset;
 102        snd_soc_component_write(component, AC97_GPIO_STATUS,
 103                                gpio_priv->gpios_set);
 104        dev_dbg(component->dev, "set gpio %d to %d\n", offset, !!value);
 105}
 106
 107static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
 108                                     unsigned offset, int value)
 109{
 110        struct snd_soc_component *component = gpio_to_component(chip);
 111
 112        dev_dbg(component->dev, "set gpio %d to output\n", offset);
 113        snd_soc_ac97_gpio_set(chip, offset, value);
 114        return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
 115                                             1 << offset, 0);
 116}
 117
 118static const struct gpio_chip snd_soc_ac97_gpio_chip = {
 119        .label                  = "snd_soc_ac97",
 120        .owner                  = THIS_MODULE,
 121        .request                = snd_soc_ac97_gpio_request,
 122        .direction_input        = snd_soc_ac97_gpio_direction_in,
 123        .get                    = snd_soc_ac97_gpio_get,
 124        .direction_output       = snd_soc_ac97_gpio_direction_out,
 125        .set                    = snd_soc_ac97_gpio_set,
 126        .can_sleep              = 1,
 127};
 128
 129static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
 130                                  struct snd_soc_component *component)
 131{
 132        struct snd_ac97_gpio_priv *gpio_priv;
 133        int ret;
 134
 135        gpio_priv = devm_kzalloc(component->dev, sizeof(*gpio_priv), GFP_KERNEL);
 136        if (!gpio_priv)
 137                return -ENOMEM;
 138        ac97->gpio_priv = gpio_priv;
 139        gpio_priv->component = component;
 140        gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
 141        gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
 142        gpio_priv->gpio_chip.parent = component->dev;
 143        gpio_priv->gpio_chip.base = -1;
 144
 145        ret = gpiochip_add_data(&gpio_priv->gpio_chip, gpio_priv);
 146        if (ret != 0)
 147                dev_err(component->dev, "Failed to add GPIOs: %d\n", ret);
 148        return ret;
 149}
 150
 151static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 152{
 153        gpiochip_remove(&ac97->gpio_priv->gpio_chip);
 154}
 155#else
 156static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
 157                                  struct snd_soc_component *component)
 158{
 159        return 0;
 160}
 161
 162static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 163{
 164}
 165#endif
 166
 167/**
 168 * snd_soc_alloc_ac97_component() - Allocate new a AC'97 device
 169 * @component: The COMPONENT for which to create the AC'97 device
 170 *
 171 * Allocated a new snd_ac97 device and intializes it, but does not yet register
 172 * it. The caller is responsible to either call device_add(&ac97->dev) to
 173 * register the device, or to call put_device(&ac97->dev) to free the device.
 174 *
 175 * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
 176 */
 177struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component)
 178{
 179        struct snd_ac97 *ac97;
 180
 181        ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
 182        if (ac97 == NULL)
 183                return ERR_PTR(-ENOMEM);
 184
 185        ac97->bus = &soc_ac97_bus;
 186        ac97->num = 0;
 187
 188        ac97->dev.bus = &ac97_bus_type;
 189        ac97->dev.parent = component->card->dev;
 190        ac97->dev.release = soc_ac97_device_release;
 191
 192        dev_set_name(&ac97->dev, "%d-%d:%s",
 193                     component->card->snd_card->number, 0,
 194                     component->name);
 195
 196        device_initialize(&ac97->dev);
 197
 198        return ac97;
 199}
 200EXPORT_SYMBOL(snd_soc_alloc_ac97_component);
 201
 202/**
 203 * snd_soc_new_ac97_component - initailise AC97 device
 204 * @component: audio component
 205 * @id: The expected device ID
 206 * @id_mask: Mask that is applied to the device ID before comparing with @id
 207 *
 208 * Initialises AC97 component resources for use by ad-hoc devices only.
 209 *
 210 * If @id is not 0 this function will reset the device, then read the ID from
 211 * the device and check if it matches the expected ID. If it doesn't match an
 212 * error will be returned and device will not be registered.
 213 *
 214 * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
 215 */
 216struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
 217        unsigned int id, unsigned int id_mask)
 218{
 219        struct snd_ac97 *ac97;
 220        int ret;
 221
 222        ac97 = snd_soc_alloc_ac97_component(component);
 223        if (IS_ERR(ac97))
 224                return ac97;
 225
 226        if (id) {
 227                ret = snd_ac97_reset(ac97, false, id, id_mask);
 228                if (ret < 0) {
 229                        dev_err(component->dev, "Failed to reset AC97 device: %d\n",
 230                                ret);
 231                        goto err_put_device;
 232                }
 233        }
 234
 235        ret = device_add(&ac97->dev);
 236        if (ret)
 237                goto err_put_device;
 238
 239        ret = snd_soc_ac97_init_gpio(ac97, component);
 240        if (ret)
 241                goto err_put_device;
 242
 243        return ac97;
 244
 245err_put_device:
 246        put_device(&ac97->dev);
 247        return ERR_PTR(ret);
 248}
 249EXPORT_SYMBOL_GPL(snd_soc_new_ac97_component);
 250
 251/**
 252 * snd_soc_free_ac97_component - free AC97 component device
 253 * @ac97: snd_ac97 device to be freed
 254 *
 255 * Frees AC97 component device resources.
 256 */
 257void snd_soc_free_ac97_component(struct snd_ac97 *ac97)
 258{
 259        snd_soc_ac97_free_gpio(ac97);
 260        device_del(&ac97->dev);
 261        ac97->bus = NULL;
 262        put_device(&ac97->dev);
 263}
 264EXPORT_SYMBOL_GPL(snd_soc_free_ac97_component);
 265
 266static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
 267
 268static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
 269{
 270        struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
 271
 272        pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
 273
 274        gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
 275
 276        udelay(10);
 277
 278        gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
 279
 280        pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
 281        msleep(2);
 282}
 283
 284static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
 285{
 286        struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
 287
 288        pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
 289
 290        gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
 291        gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
 292        gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
 293
 294        udelay(10);
 295
 296        gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
 297
 298        pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
 299        msleep(2);
 300}
 301
 302static int snd_soc_ac97_parse_pinctl(struct device *dev,
 303                struct snd_ac97_reset_cfg *cfg)
 304{
 305        struct pinctrl *p;
 306        struct pinctrl_state *state;
 307        int gpio;
 308        int ret;
 309
 310        p = devm_pinctrl_get(dev);
 311        if (IS_ERR(p)) {
 312                dev_err(dev, "Failed to get pinctrl\n");
 313                return PTR_ERR(p);
 314        }
 315        cfg->pctl = p;
 316
 317        state = pinctrl_lookup_state(p, "ac97-reset");
 318        if (IS_ERR(state)) {
 319                dev_err(dev, "Can't find pinctrl state ac97-reset\n");
 320                return PTR_ERR(state);
 321        }
 322        cfg->pstate_reset = state;
 323
 324        state = pinctrl_lookup_state(p, "ac97-warm-reset");
 325        if (IS_ERR(state)) {
 326                dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
 327                return PTR_ERR(state);
 328        }
 329        cfg->pstate_warm_reset = state;
 330
 331        state = pinctrl_lookup_state(p, "ac97-running");
 332        if (IS_ERR(state)) {
 333                dev_err(dev, "Can't find pinctrl state ac97-running\n");
 334                return PTR_ERR(state);
 335        }
 336        cfg->pstate_run = state;
 337
 338        gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
 339        if (gpio < 0) {
 340                dev_err(dev, "Can't find ac97-sync gpio\n");
 341                return gpio;
 342        }
 343        ret = devm_gpio_request(dev, gpio, "AC97 link sync");
 344        if (ret) {
 345                dev_err(dev, "Failed requesting ac97-sync gpio\n");
 346                return ret;
 347        }
 348        cfg->gpio_sync = gpio;
 349
 350        gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
 351        if (gpio < 0) {
 352                dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
 353                return gpio;
 354        }
 355        ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
 356        if (ret) {
 357                dev_err(dev, "Failed requesting ac97-sdata gpio\n");
 358                return ret;
 359        }
 360        cfg->gpio_sdata = gpio;
 361
 362        gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
 363        if (gpio < 0) {
 364                dev_err(dev, "Can't find ac97-reset gpio\n");
 365                return gpio;
 366        }
 367        ret = devm_gpio_request(dev, gpio, "AC97 link reset");
 368        if (ret) {
 369                dev_err(dev, "Failed requesting ac97-reset gpio\n");
 370                return ret;
 371        }
 372        cfg->gpio_reset = gpio;
 373
 374        return 0;
 375}
 376
 377struct snd_ac97_bus_ops *soc_ac97_ops;
 378EXPORT_SYMBOL_GPL(soc_ac97_ops);
 379
 380int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
 381{
 382        if (ops == soc_ac97_ops)
 383                return 0;
 384
 385        if (soc_ac97_ops && ops)
 386                return -EBUSY;
 387
 388        soc_ac97_ops = ops;
 389        soc_ac97_bus.ops = ops;
 390
 391        return 0;
 392}
 393EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
 394
 395/**
 396 * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
 397 *
 398 * This function sets the reset and warm_reset properties of ops and parses
 399 * the device node of pdev to get pinctrl states and gpio numbers to use.
 400 */
 401int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
 402                struct platform_device *pdev)
 403{
 404        struct device *dev = &pdev->dev;
 405        struct snd_ac97_reset_cfg cfg;
 406        int ret;
 407
 408        ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
 409        if (ret)
 410                return ret;
 411
 412        ret = snd_soc_set_ac97_ops(ops);
 413        if (ret)
 414                return ret;
 415
 416        ops->warm_reset = snd_soc_ac97_warm_reset;
 417        ops->reset = snd_soc_ac97_reset;
 418
 419        snd_ac97_rst_cfg = cfg;
 420        return 0;
 421}
 422EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
 423