1 // SPDX-License-Identifier: GPL-2.0-only
3 * HD-audio core bus driver
6 #include <linux/init.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/export.h>
11 #include <sound/hdaudio.h>
15 static void snd_hdac_bus_process_unsol_events(struct work_struct
*work
);
17 static const struct hdac_bus_ops default_ops
= {
18 .command
= snd_hdac_bus_send_cmd
,
19 .get_response
= snd_hdac_bus_get_response
,
20 .link_power
= snd_hdac_bus_link_power
,
24 * snd_hdac_bus_init - initialize a HD-audio bas bus
25 * @bus: the pointer to bus object
26 * @dev: device pointer
27 * @ops: bus verb operators
29 * Returns 0 if successful, or a negative error code.
31 int snd_hdac_bus_init(struct hdac_bus
*bus
, struct device
*dev
,
32 const struct hdac_bus_ops
*ops
)
34 memset(bus
, 0, sizeof(*bus
));
39 bus
->ops
= &default_ops
;
40 bus
->dma_type
= SNDRV_DMA_TYPE_DEV
;
41 INIT_LIST_HEAD(&bus
->stream_list
);
42 INIT_LIST_HEAD(&bus
->codec_list
);
43 INIT_WORK(&bus
->unsol_work
, snd_hdac_bus_process_unsol_events
);
44 spin_lock_init(&bus
->reg_lock
);
45 mutex_init(&bus
->cmd_mutex
);
46 mutex_init(&bus
->lock
);
47 INIT_LIST_HEAD(&bus
->hlink_list
);
48 init_waitqueue_head(&bus
->rirb_wq
);
52 * Default value of '8' is as per the HD audio specification (Rev 1.0a).
53 * Following relation is used to derive STRIPE control value.
54 * For sample rate <= 48K:
55 * { ((num_channels * bits_per_sample) / number of SDOs) >= 8 }
56 * For sample rate > 48K:
57 * { ((num_channels * bits_per_sample * rate/48000) /
58 * number of SDOs) >= 8 }
64 EXPORT_SYMBOL_GPL(snd_hdac_bus_init
);
67 * snd_hdac_bus_exit - clean up a HD-audio bas bus
68 * @bus: the pointer to bus object
70 void snd_hdac_bus_exit(struct hdac_bus
*bus
)
72 WARN_ON(!list_empty(&bus
->stream_list
));
73 WARN_ON(!list_empty(&bus
->codec_list
));
74 cancel_work_sync(&bus
->unsol_work
);
76 EXPORT_SYMBOL_GPL(snd_hdac_bus_exit
);
79 * snd_hdac_bus_exec_verb - execute a HD-audio verb on the given bus
81 * @addr: the HDAC device address
82 * @cmd: HD-audio encoded verb
83 * @res: pointer to store the response, NULL if performing asynchronously
85 * Returns 0 if successful, or a negative error code.
87 int snd_hdac_bus_exec_verb(struct hdac_bus
*bus
, unsigned int addr
,
88 unsigned int cmd
, unsigned int *res
)
92 mutex_lock(&bus
->cmd_mutex
);
93 err
= snd_hdac_bus_exec_verb_unlocked(bus
, addr
, cmd
, res
);
94 mutex_unlock(&bus
->cmd_mutex
);
99 * snd_hdac_bus_exec_verb_unlocked - unlocked version
101 * @addr: the HDAC device address
102 * @cmd: HD-audio encoded verb
103 * @res: pointer to store the response, NULL if performing asynchronously
105 * Returns 0 if successful, or a negative error code.
107 int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus
*bus
, unsigned int addr
,
108 unsigned int cmd
, unsigned int *res
)
118 else if (bus
->sync_write
)
121 trace_hda_send_cmd(bus
, cmd
);
122 err
= bus
->ops
->command(bus
, cmd
);
125 /* process pending verbs */
126 err
= bus
->ops
->get_response(bus
, addr
, &tmp
);
131 err
= bus
->ops
->get_response(bus
, addr
, res
);
132 trace_hda_get_response(bus
, addr
, *res
);
136 EXPORT_SYMBOL_GPL(snd_hdac_bus_exec_verb_unlocked
);
139 * snd_hdac_bus_queue_event - add an unsolicited event to queue
141 * @res: unsolicited event (lower 32bit of RIRB entry)
142 * @res_ex: codec addr and flags (upper 32bit or RIRB entry)
144 * Adds the given event to the queue. The events are processed in
145 * the workqueue asynchronously. Call this function in the interrupt
146 * hanlder when RIRB receives an unsolicited event.
148 void snd_hdac_bus_queue_event(struct hdac_bus
*bus
, u32 res
, u32 res_ex
)
155 trace_hda_unsol_event(bus
, res
, res_ex
);
156 wp
= (bus
->unsol_wp
+ 1) % HDA_UNSOL_QUEUE_SIZE
;
160 bus
->unsol_queue
[wp
] = res
;
161 bus
->unsol_queue
[wp
+ 1] = res_ex
;
163 schedule_work(&bus
->unsol_work
);
167 * process queued unsolicited events
169 static void snd_hdac_bus_process_unsol_events(struct work_struct
*work
)
171 struct hdac_bus
*bus
= container_of(work
, struct hdac_bus
, unsol_work
);
172 struct hdac_device
*codec
;
173 struct hdac_driver
*drv
;
174 unsigned int rp
, caddr
, res
;
176 spin_lock_irq(&bus
->reg_lock
);
177 while (bus
->unsol_rp
!= bus
->unsol_wp
) {
178 rp
= (bus
->unsol_rp
+ 1) % HDA_UNSOL_QUEUE_SIZE
;
181 res
= bus
->unsol_queue
[rp
];
182 caddr
= bus
->unsol_queue
[rp
+ 1];
183 if (!(caddr
& (1 << 4))) /* no unsolicited event? */
185 codec
= bus
->caddr_tbl
[caddr
& 0x0f];
186 if (!codec
|| !codec
->registered
)
188 spin_unlock_irq(&bus
->reg_lock
);
189 drv
= drv_to_hdac_driver(codec
->dev
.driver
);
190 if (drv
->unsol_event
)
191 drv
->unsol_event(codec
, res
);
192 spin_lock_irq(&bus
->reg_lock
);
194 spin_unlock_irq(&bus
->reg_lock
);
198 * snd_hdac_bus_add_device - Add a codec to bus
200 * @codec: HDA core device to add
202 * Adds the given codec to the list in the bus. The caddr_tbl array
203 * and codec_powered bits are updated, as well.
204 * Returns zero if success, or a negative error code.
206 int snd_hdac_bus_add_device(struct hdac_bus
*bus
, struct hdac_device
*codec
)
208 if (bus
->caddr_tbl
[codec
->addr
]) {
209 dev_err(bus
->dev
, "address 0x%x is already occupied\n",
214 list_add_tail(&codec
->list
, &bus
->codec_list
);
215 bus
->caddr_tbl
[codec
->addr
] = codec
;
216 set_bit(codec
->addr
, &bus
->codec_powered
);
222 * snd_hdac_bus_remove_device - Remove a codec from bus
224 * @codec: HDA core device to remove
226 void snd_hdac_bus_remove_device(struct hdac_bus
*bus
,
227 struct hdac_device
*codec
)
229 WARN_ON(bus
!= codec
->bus
);
230 if (list_empty(&codec
->list
))
232 list_del_init(&codec
->list
);
233 bus
->caddr_tbl
[codec
->addr
] = NULL
;
234 clear_bit(codec
->addr
, &bus
->codec_powered
);
236 flush_work(&bus
->unsol_work
);
239 #ifdef CONFIG_SND_HDA_ALIGNED_MMIO
240 /* Helpers for aligned read/write of mmio space, for Tegra */
241 unsigned int snd_hdac_aligned_read(void __iomem
*addr
, unsigned int mask
)
243 void __iomem
*aligned_addr
=
244 (void __iomem
*)((unsigned long)(addr
) & ~0x3);
245 unsigned int shift
= ((unsigned long)(addr
) & 0x3) << 3;
248 v
= readl(aligned_addr
);
249 return (v
>> shift
) & mask
;
251 EXPORT_SYMBOL_GPL(snd_hdac_aligned_read
);
253 void snd_hdac_aligned_write(unsigned int val
, void __iomem
*addr
,
256 void __iomem
*aligned_addr
=
257 (void __iomem
*)((unsigned long)(addr
) & ~0x3);
258 unsigned int shift
= ((unsigned long)(addr
) & 0x3) << 3;
261 v
= readl(aligned_addr
);
262 v
&= ~(mask
<< shift
);
264 writel(v
, aligned_addr
);
266 EXPORT_SYMBOL_GPL(snd_hdac_aligned_write
);
267 #endif /* CONFIG_SND_HDA_ALIGNED_MMIO */
269 void snd_hdac_codec_link_up(struct hdac_device
*codec
)
271 struct hdac_bus
*bus
= codec
->bus
;
273 if (bus
->ops
->link_power
)
274 bus
->ops
->link_power(codec
, true);
276 snd_hdac_bus_link_power(codec
, true);
278 EXPORT_SYMBOL_GPL(snd_hdac_codec_link_up
);
280 void snd_hdac_codec_link_down(struct hdac_device
*codec
)
282 struct hdac_bus
*bus
= codec
->bus
;
284 if (bus
->ops
->link_power
)
285 bus
->ops
->link_power(codec
, false);
287 snd_hdac_bus_link_power(codec
, false);
289 EXPORT_SYMBOL_GPL(snd_hdac_codec_link_down
);