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