linux/sound/aoa/soundbus/soundbus.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * soundbus generic definitions
   4 *
   5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   6 */
   7#ifndef __SOUNDBUS_H
   8#define __SOUNDBUS_H
   9
  10#include <linux/of_device.h>
  11#include <sound/pcm.h>
  12#include <linux/list.h>
  13
  14
  15/* When switching from master to slave or the other way around,
  16 * you don't want to have the codec chip acting as clock source
  17 * while the bus still is.
  18 * More importantly, while switch from slave to master, you need
  19 * to turn off the chip's master function first, but then there's
  20 * no clock for a while and other chips might reset, so we notify
  21 * their drivers after having switched.
  22 * The constants here are codec-point of view, so when we switch
  23 * the soundbus to master we tell the codec we're going to switch
  24 * and give it CLOCK_SWITCH_PREPARE_SLAVE!
  25 */
  26enum clock_switch {
  27        CLOCK_SWITCH_PREPARE_SLAVE,
  28        CLOCK_SWITCH_PREPARE_MASTER,
  29        CLOCK_SWITCH_SLAVE,
  30        CLOCK_SWITCH_MASTER,
  31        CLOCK_SWITCH_NOTIFY,
  32};
  33
  34/* information on a transfer the codec can take */
  35struct transfer_info {
  36        u64 formats;            /* SNDRV_PCM_FMTBIT_* */
  37        unsigned int rates;     /* SNDRV_PCM_RATE_* */
  38        /* flags */
  39        u32 transfer_in:1, /* input = 1, output = 0 */
  40            must_be_clock_source:1;
  41        /* for codecs to distinguish among their TIs */
  42        int tag;
  43};
  44
  45struct codec_info_item {
  46        struct codec_info *codec;
  47        void *codec_data;
  48        struct soundbus_dev *sdev;
  49        /* internal, to be used by the soundbus provider */
  50        struct list_head list;
  51};
  52
  53/* for prepare, where the codecs need to know
  54 * what we're going to drive the bus with */
  55struct bus_info {
  56        /* see below */
  57        int sysclock_factor;
  58        int bus_factor;
  59};
  60
  61/* information on the codec itself, plus function pointers */
  62struct codec_info {
  63        /* the module this lives in */
  64        struct module *owner;
  65
  66        /* supported transfer possibilities, array terminated by
  67         * formats or rates being 0. */
  68        struct transfer_info *transfers;
  69
  70        /* Master clock speed factor
  71         * to be used (master clock speed = sysclock_factor * sampling freq)
  72         * Unused if the soundbus provider has no such notion.
  73         */
  74        int sysclock_factor;
  75
  76        /* Bus factor, bus clock speed = bus_factor * sampling freq)
  77         * Unused if the soundbus provider has no such notion.
  78         */
  79        int bus_factor;
  80
  81        /* operations */
  82        /* clock switching, see above */
  83        int (*switch_clock)(struct codec_info_item *cii,
  84                            enum clock_switch clock);
  85
  86        /* called for each transfer_info when the user
  87         * opens the pcm device to determine what the
  88         * hardware can support at this point in time.
  89         * That can depend on other user-switchable controls.
  90         * Return 1 if usable, 0 if not.
  91         * out points to another instance of a transfer_info
  92         * which is initialised to the values in *ti, and
  93         * it's format and rate values can be modified by
  94         * the callback if it is necessary to further restrict
  95         * the formats that can be used at the moment, for
  96         * example when one codec has multiple logical codec
  97         * info structs for multiple inputs.
  98         */
  99        int (*usable)(struct codec_info_item *cii,
 100                      struct transfer_info *ti,
 101                      struct transfer_info *out);
 102
 103        /* called when pcm stream is opened, probably not implemented
 104         * most of the time since it isn't too useful */
 105        int (*open)(struct codec_info_item *cii,
 106                    struct snd_pcm_substream *substream);
 107
 108        /* called when the pcm stream is closed, at this point
 109         * the user choices can all be unlocked (see below) */
 110        int (*close)(struct codec_info_item *cii,
 111                     struct snd_pcm_substream *substream);
 112
 113        /* if the codec must forbid some user choices because
 114         * they are not valid with the substream/transfer info,
 115         * it must do so here. Example: no digital output for
 116         * incompatible framerate, say 8KHz, on Onyx.
 117         * If the selected stuff in the substream is NOT
 118         * compatible, you have to reject this call! */
 119        int (*prepare)(struct codec_info_item *cii,
 120                       struct bus_info *bi,
 121                       struct snd_pcm_substream *substream);
 122
 123        /* start() is called before data is pushed to the codec.
 124         * Note that start() must be atomic! */
 125        int (*start)(struct codec_info_item *cii,
 126                     struct snd_pcm_substream *substream);
 127
 128        /* stop() is called after data is no longer pushed to the codec.
 129         * Note that stop() must be atomic! */
 130        int (*stop)(struct codec_info_item *cii,
 131                    struct snd_pcm_substream *substream);
 132
 133        int (*suspend)(struct codec_info_item *cii, pm_message_t state);
 134        int (*resume)(struct codec_info_item *cii);
 135};
 136
 137/* information on a soundbus device */
 138struct soundbus_dev {
 139        /* the bus it belongs to */
 140        struct list_head onbuslist;
 141
 142        /* the of device it represents */
 143        struct platform_device ofdev;
 144
 145        /* what modules go by */
 146        char modalias[32];
 147
 148        /* These fields must be before attach_codec can be called.
 149         * They should be set by the owner of the alsa card object
 150         * that is needed, and whoever sets them must make sure
 151         * that they are unique within that alsa card object. */
 152        char *pcmname;
 153        int pcmid;
 154
 155        /* this is assigned by the soundbus provider in attach_codec */
 156        struct snd_pcm *pcm;
 157
 158        /* operations */
 159        /* attach a codec to this soundbus, give the alsa
 160         * card object the PCMs for this soundbus should be in.
 161         * The 'data' pointer must be unique, it is used as the
 162         * key for detach_codec(). */
 163        int (*attach_codec)(struct soundbus_dev *dev, struct snd_card *card,
 164                            struct codec_info *ci, void *data);
 165        void (*detach_codec)(struct soundbus_dev *dev, void *data);
 166        /* TODO: suspend/resume */
 167
 168        /* private for the soundbus provider */
 169        struct list_head codec_list;
 170        u32 have_out:1, have_in:1;
 171};
 172#define to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev.dev)
 173#define of_to_soundbus_device(d) container_of(d, struct soundbus_dev, ofdev)
 174
 175extern int soundbus_add_one(struct soundbus_dev *dev);
 176extern void soundbus_remove_one(struct soundbus_dev *dev);
 177
 178extern struct soundbus_dev *soundbus_dev_get(struct soundbus_dev *dev);
 179extern void soundbus_dev_put(struct soundbus_dev *dev);
 180
 181struct soundbus_driver {
 182        char *name;
 183        struct module *owner;
 184
 185        /* we don't implement any matching at all */
 186
 187        int     (*probe)(struct soundbus_dev* dev);
 188        int     (*remove)(struct soundbus_dev* dev);
 189
 190        int     (*shutdown)(struct soundbus_dev* dev);
 191
 192        struct device_driver driver;
 193};
 194#define to_soundbus_driver(drv) container_of(drv,struct soundbus_driver, driver)
 195
 196extern int soundbus_register_driver(struct soundbus_driver *drv);
 197extern void soundbus_unregister_driver(struct soundbus_driver *drv);
 198
 199extern struct attribute *soundbus_dev_attrs[];
 200
 201#endif /* __SOUNDBUS_H */
 202