linux/sound/aoa/codecs/toonie.c
<<
>>
Prefs
   1/*
   2 * Apple Onboard Audio driver for Toonie codec
   3 *
   4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   5 *
   6 * GPL v2, can be found in COPYING.
   7 *
   8 *
   9 * This is a driver for the toonie codec chip. This chip is present
  10 * on the Mac Mini and is nothing but a DAC.
  11 */
  12#include <linux/delay.h>
  13#include <linux/module.h>
  14MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
  15MODULE_LICENSE("GPL");
  16MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
  17
  18#include "../aoa.h"
  19#include "../soundbus/soundbus.h"
  20
  21
  22#define PFX "snd-aoa-codec-toonie: "
  23
  24struct toonie {
  25        struct aoa_codec        codec;
  26};
  27#define codec_to_toonie(c) container_of(c, struct toonie, codec)
  28
  29static int toonie_dev_register(struct snd_device *dev)
  30{
  31        return 0;
  32}
  33
  34static struct snd_device_ops ops = {
  35        .dev_register = toonie_dev_register,
  36};
  37
  38static struct transfer_info toonie_transfers[] = {
  39        /* This thing *only* has analog output,
  40         * the rates are taken from Info.plist
  41         * from Darwin. */
  42        {
  43                .formats = SNDRV_PCM_FMTBIT_S16_BE |
  44                           SNDRV_PCM_FMTBIT_S24_BE,
  45                .rates = SNDRV_PCM_RATE_32000 |
  46                         SNDRV_PCM_RATE_44100 |
  47                         SNDRV_PCM_RATE_48000 |
  48                         SNDRV_PCM_RATE_88200 |
  49                         SNDRV_PCM_RATE_96000,
  50        },
  51        {}
  52};
  53
  54static int toonie_usable(struct codec_info_item *cii,
  55                         struct transfer_info *ti,
  56                         struct transfer_info *out)
  57{
  58        return 1;
  59}
  60
  61#ifdef CONFIG_PM
  62static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
  63{
  64        /* can we turn it off somehow? */
  65        return 0;
  66}
  67
  68static int toonie_resume(struct codec_info_item *cii)
  69{
  70        return 0;
  71}
  72#endif /* CONFIG_PM */
  73
  74static struct codec_info toonie_codec_info = {
  75        .transfers = toonie_transfers,
  76        .sysclock_factor = 256,
  77        .bus_factor = 64,
  78        .owner = THIS_MODULE,
  79        .usable = toonie_usable,
  80#ifdef CONFIG_PM
  81        .suspend = toonie_suspend,
  82        .resume = toonie_resume,
  83#endif
  84};
  85
  86static int toonie_init_codec(struct aoa_codec *codec)
  87{
  88        struct toonie *toonie = codec_to_toonie(codec);
  89
  90        /* nothing connected? what a joke! */
  91        if (toonie->codec.connected != 1)
  92                return -ENOTCONN;
  93
  94        if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
  95                printk(KERN_ERR PFX "failed to create toonie snd device!\n");
  96                return -ENODEV;
  97        }
  98
  99        if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
 100                                                     aoa_get_card(),
 101                                                     &toonie_codec_info, toonie)) {
 102                printk(KERN_ERR PFX "error creating toonie pcm\n");
 103                snd_device_free(aoa_get_card(), toonie);
 104                return -ENODEV;
 105        }
 106
 107        return 0;
 108}
 109
 110static void toonie_exit_codec(struct aoa_codec *codec)
 111{
 112        struct toonie *toonie = codec_to_toonie(codec);
 113
 114        if (!toonie->codec.soundbus_dev) {
 115                printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
 116                return;
 117        }
 118        toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
 119}
 120
 121static struct toonie *toonie;
 122
 123static int __init toonie_init(void)
 124{
 125        toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
 126
 127        if (!toonie)
 128                return -ENOMEM;
 129
 130        strlcpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
 131        toonie->codec.owner = THIS_MODULE;
 132        toonie->codec.init = toonie_init_codec;
 133        toonie->codec.exit = toonie_exit_codec;
 134
 135        if (aoa_codec_register(&toonie->codec)) {
 136                kfree(toonie);
 137                return -EINVAL;
 138        }
 139
 140        return 0;
 141}
 142
 143static void __exit toonie_exit(void)
 144{
 145        aoa_codec_unregister(&toonie->codec);
 146        kfree(toonie);
 147}
 148
 149module_init(toonie_init);
 150module_exit(toonie_exit);
 151