root/sound/aoa/core/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. attach_codec_to_fabric
  2. aoa_codec_register
  3. aoa_codec_unregister
  4. aoa_fabric_register
  5. aoa_fabric_unregister
  6. aoa_fabric_unlink_codec
  7. aoa_init
  8. aoa_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Apple Onboard Audio driver core
   4  *
   5  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/module.h>
  10 #include <linux/list.h>
  11 #include "../aoa.h"
  12 #include "alsa.h"
  13 
  14 MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
  15 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
  16 MODULE_LICENSE("GPL");
  17 
  18 /* We allow only one fabric. This simplifies things,
  19  * and more don't really make that much sense */
  20 static struct aoa_fabric *fabric;
  21 static LIST_HEAD(codec_list);
  22 
  23 static int attach_codec_to_fabric(struct aoa_codec *c)
  24 {
  25         int err;
  26 
  27         if (!try_module_get(c->owner))
  28                 return -EBUSY;
  29         /* found_codec has to be assigned */
  30         err = -ENOENT;
  31         if (fabric->found_codec)
  32                 err = fabric->found_codec(c);
  33         if (err) {
  34                 module_put(c->owner);
  35                 printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
  36                                 c->name);
  37                 return err;
  38         }
  39         c->fabric = fabric;
  40 
  41         err = 0;
  42         if (c->init)
  43                 err = c->init(c);
  44         if (err) {
  45                 printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
  46                 c->fabric = NULL;
  47                 if (fabric->remove_codec)
  48                         fabric->remove_codec(c);
  49                 module_put(c->owner);
  50                 return err;
  51         }
  52         if (fabric->attached_codec)
  53                 fabric->attached_codec(c);
  54         return 0;
  55 }
  56 
  57 int aoa_codec_register(struct aoa_codec *codec)
  58 {
  59         int err = 0;
  60 
  61         /* if there's a fabric already, we can tell if we
  62          * will want to have this codec, so propagate error
  63          * through. Otherwise, this will happen later... */
  64         if (fabric)
  65                 err = attach_codec_to_fabric(codec);
  66         if (!err)
  67                 list_add(&codec->list, &codec_list);
  68         return err;
  69 }
  70 EXPORT_SYMBOL_GPL(aoa_codec_register);
  71 
  72 void aoa_codec_unregister(struct aoa_codec *codec)
  73 {
  74         list_del(&codec->list);
  75         if (codec->fabric && codec->exit)
  76                 codec->exit(codec);
  77         if (fabric && fabric->remove_codec)
  78                 fabric->remove_codec(codec);
  79         codec->fabric = NULL;
  80         module_put(codec->owner);
  81 }
  82 EXPORT_SYMBOL_GPL(aoa_codec_unregister);
  83 
  84 int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev)
  85 {
  86         struct aoa_codec *c;
  87         int err;
  88 
  89         /* allow querying for presence of fabric
  90          * (i.e. do this test first!) */
  91         if (new_fabric == fabric) {
  92                 err = -EALREADY;
  93                 goto attach;
  94         }
  95         if (fabric)
  96                 return -EEXIST;
  97         if (!new_fabric)
  98                 return -EINVAL;
  99 
 100         err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev);
 101         if (err)
 102                 return err;
 103 
 104         fabric = new_fabric;
 105 
 106  attach:
 107         list_for_each_entry(c, &codec_list, list) {
 108                 if (c->fabric != fabric)
 109                         attach_codec_to_fabric(c);
 110         }
 111         return err;
 112 }
 113 EXPORT_SYMBOL_GPL(aoa_fabric_register);
 114 
 115 void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
 116 {
 117         struct aoa_codec *c;
 118 
 119         if (fabric != old_fabric)
 120                 return;
 121 
 122         list_for_each_entry(c, &codec_list, list) {
 123                 if (c->fabric)
 124                         aoa_fabric_unlink_codec(c);
 125         }
 126 
 127         aoa_alsa_cleanup();
 128 
 129         fabric = NULL;
 130 }
 131 EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
 132 
 133 void aoa_fabric_unlink_codec(struct aoa_codec *codec)
 134 {
 135         if (!codec->fabric) {
 136                 printk(KERN_ERR "snd-aoa: fabric unassigned "
 137                                 "in aoa_fabric_unlink_codec\n");
 138                 dump_stack();
 139                 return;
 140         }
 141         if (codec->exit)
 142                 codec->exit(codec);
 143         if (codec->fabric->remove_codec)
 144                 codec->fabric->remove_codec(codec);
 145         codec->fabric = NULL;
 146         module_put(codec->owner);
 147 }
 148 EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
 149 
 150 static int __init aoa_init(void)
 151 {
 152         return 0;
 153 }
 154 
 155 static void __exit aoa_exit(void)
 156 {
 157         aoa_alsa_cleanup();
 158 }
 159 
 160 module_init(aoa_init);
 161 module_exit(aoa_exit);

/* [<][>][^][v][top][bottom][index][help] */