Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Apple Onboard Audio driver for Toonie codec
0004  *
0005  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
0006  *
0007  * This is a driver for the toonie codec chip. This chip is present
0008  * on the Mac Mini and is nothing but a DAC.
0009  */
0010 #include <linux/delay.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
0014 MODULE_LICENSE("GPL");
0015 MODULE_DESCRIPTION("toonie codec driver for snd-aoa");
0016 
0017 #include "../aoa.h"
0018 #include "../soundbus/soundbus.h"
0019 
0020 
0021 #define PFX "snd-aoa-codec-toonie: "
0022 
0023 struct toonie {
0024     struct aoa_codec    codec;
0025 };
0026 #define codec_to_toonie(c) container_of(c, struct toonie, codec)
0027 
0028 static int toonie_dev_register(struct snd_device *dev)
0029 {
0030     return 0;
0031 }
0032 
0033 static const struct snd_device_ops ops = {
0034     .dev_register = toonie_dev_register,
0035 };
0036 
0037 static struct transfer_info toonie_transfers[] = {
0038     /* This thing *only* has analog output,
0039      * the rates are taken from Info.plist
0040      * from Darwin. */
0041     {
0042         .formats = SNDRV_PCM_FMTBIT_S16_BE |
0043                SNDRV_PCM_FMTBIT_S24_BE,
0044         .rates = SNDRV_PCM_RATE_32000 |
0045              SNDRV_PCM_RATE_44100 |
0046              SNDRV_PCM_RATE_48000 |
0047              SNDRV_PCM_RATE_88200 |
0048              SNDRV_PCM_RATE_96000,
0049     },
0050     {}
0051 };
0052 
0053 static int toonie_usable(struct codec_info_item *cii,
0054              struct transfer_info *ti,
0055              struct transfer_info *out)
0056 {
0057     return 1;
0058 }
0059 
0060 #ifdef CONFIG_PM
0061 static int toonie_suspend(struct codec_info_item *cii, pm_message_t state)
0062 {
0063     /* can we turn it off somehow? */
0064     return 0;
0065 }
0066 
0067 static int toonie_resume(struct codec_info_item *cii)
0068 {
0069     return 0;
0070 }
0071 #endif /* CONFIG_PM */
0072 
0073 static struct codec_info toonie_codec_info = {
0074     .transfers = toonie_transfers,
0075     .sysclock_factor = 256,
0076     .bus_factor = 64,
0077     .owner = THIS_MODULE,
0078     .usable = toonie_usable,
0079 #ifdef CONFIG_PM
0080     .suspend = toonie_suspend,
0081     .resume = toonie_resume,
0082 #endif
0083 };
0084 
0085 static int toonie_init_codec(struct aoa_codec *codec)
0086 {
0087     struct toonie *toonie = codec_to_toonie(codec);
0088 
0089     /* nothing connected? what a joke! */
0090     if (toonie->codec.connected != 1)
0091         return -ENOTCONN;
0092 
0093     if (aoa_snd_device_new(SNDRV_DEV_CODEC, toonie, &ops)) {
0094         printk(KERN_ERR PFX "failed to create toonie snd device!\n");
0095         return -ENODEV;
0096     }
0097 
0098     if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev,
0099                              aoa_get_card(),
0100                              &toonie_codec_info, toonie)) {
0101         printk(KERN_ERR PFX "error creating toonie pcm\n");
0102         snd_device_free(aoa_get_card(), toonie);
0103         return -ENODEV;
0104     }
0105 
0106     return 0;
0107 }
0108 
0109 static void toonie_exit_codec(struct aoa_codec *codec)
0110 {
0111     struct toonie *toonie = codec_to_toonie(codec);
0112 
0113     if (!toonie->codec.soundbus_dev) {
0114         printk(KERN_ERR PFX "toonie_exit_codec called without soundbus_dev!\n");
0115         return;
0116     }
0117     toonie->codec.soundbus_dev->detach_codec(toonie->codec.soundbus_dev, toonie);
0118 }
0119 
0120 static struct toonie *toonie;
0121 
0122 static int __init toonie_init(void)
0123 {
0124     toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL);
0125 
0126     if (!toonie)
0127         return -ENOMEM;
0128 
0129     strscpy(toonie->codec.name, "toonie", sizeof(toonie->codec.name));
0130     toonie->codec.owner = THIS_MODULE;
0131     toonie->codec.init = toonie_init_codec;
0132     toonie->codec.exit = toonie_exit_codec;
0133 
0134     if (aoa_codec_register(&toonie->codec)) {
0135         kfree(toonie);
0136         return -EINVAL;
0137     }
0138 
0139     return 0;
0140 }
0141 
0142 static void __exit toonie_exit(void)
0143 {
0144     aoa_codec_unregister(&toonie->codec);
0145     kfree(toonie);
0146 }
0147 
0148 module_init(toonie_init);
0149 module_exit(toonie_exit);