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> 14 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 15 MODULE_LICENSE("GPL"); 16 MODULE_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 24 struct toonie { 25 struct aoa_codec codec; 26 }; 27 #define codec_to_toonie(c) container_of(c, struct toonie, codec) 28 29 static int toonie_dev_register(struct snd_device *dev) 30 { 31 return 0; 32 } 33 34 static struct snd_device_ops ops = { 35 .dev_register = toonie_dev_register, 36 }; 37 38 static 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 54 static 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 62 static 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 68 static int toonie_resume(struct codec_info_item *cii) 69 { 70 return 0; 71 } 72 #endif /* CONFIG_PM */ 73 74 static 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 86 static 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 110 static 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 121 static struct toonie *toonie; 122 123 static 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 143 static void __exit toonie_exit(void) 144 { 145 aoa_codec_unregister(&toonie->codec); 146 kfree(toonie); 147 } 148 149 module_init(toonie_init); 150 module_exit(toonie_exit); 151