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