Changeset 772 for GPL/trunk/alsa-kernel/hda/ext
- Timestamp:
- Apr 19, 2025, 8:08:37 PM (7 months ago)
- Location:
- GPL/trunk
- Files:
-
- 4 edited
-
. (modified) (1 prop)
-
alsa-kernel/hda/ext/hdac_ext_bus.c (modified) (1 diff)
-
alsa-kernel/hda/ext/hdac_ext_controller.c (modified) (16 diffs)
-
alsa-kernel/hda/ext/hdac_ext_stream.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk
- Property svn:mergeinfo changed
/GPL/branches/uniaud32-6.6-LTS (added) merged: 765,768-769 /GPL/branches/uniaud32-exp (added) merged: 735-741,743-744,748-751,753-760,762-764 /GPL/branches/uniaud32-next merged: 718-734
- Property svn:mergeinfo changed
-
GPL/trunk/alsa-kernel/hda/ext/hdac_ext_bus.c
r629 r772 60 60 } 61 61 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit); 62 63 static void default_release(struct device *dev)64 {65 snd_hdac_ext_bus_device_exit(dev_to_hdac_dev(dev));66 }67 68 /**69 * snd_hdac_ext_bus_device_init - initialize the HDA extended codec base device70 * @bus: hdac bus to attach to71 * @addr: codec address72 * @hdev: hdac device to init73 * @type: codec type (HDAC_DEV_*) to use for this device74 *75 * Returns zero for success or a negative error code.76 */77 int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,78 struct hdac_device *hdev, int type)79 {80 char name[15];81 int ret;82 83 hdev->bus = bus;84 85 snprintf(name, sizeof(name), "ehdaudio%dD%d", bus->idx, addr);86 87 ret = snd_hdac_device_init(hdev, bus, name, addr);88 if (ret < 0) {89 dev_err(bus->dev, "device init failed for hdac device\n");90 return ret;91 }92 hdev->type = type;93 hdev->dev.release = default_release;94 95 ret = snd_hdac_device_register(hdev);96 if (ret) {97 dev_err(bus->dev, "failed to register hdac device\n");98 snd_hdac_ext_bus_device_exit(hdev);99 return ret;100 }101 102 return 0;103 }104 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init);105 106 /**107 * snd_hdac_ext_bus_device_exit - clean up a HD-audio extended codec base device108 * @hdev: hdac device to clean up109 */110 void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev)111 {112 snd_hdac_device_exit(hdev);113 }114 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit);115 62 116 63 /** -
GPL/trunk/alsa-kernel/hda/ext/hdac_ext_controller.c
r695 r772 14 14 #include <sound/hda_register.h> 15 15 #include <sound/hdaudio_ext.h> 16 17 /*18 * maximum HDAC capablities we should parse to avoid endless looping:19 * currently we have 4 extended caps, so this is future proof for now.20 * extend when this limit is seen meeting in real HW21 */22 #define HDAC_MAX_CAPS 1023 16 24 17 /* … … 116 109 117 110 /** 118 * snd_hdac_ link_free_all- free hdac extended link objects119 * 120 * @bus: the pointer to HDAC bus object 121 */ 122 123 void snd_hdac_ link_free_all(struct hdac_bus *bus)124 { 125 struct hdac_ext_link * l;111 * snd_hdac_ext_link_free_all- free hdac extended link objects 112 * 113 * @bus: the pointer to HDAC bus object 114 */ 115 116 void snd_hdac_ext_link_free_all(struct hdac_bus *bus) 117 { 118 struct hdac_ext_link *hlink; 126 119 127 120 while (!list_empty(&bus->hlink_list)) { 128 l = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list); 129 list_del(&l->list); 130 kfree(l); 131 } 132 } 133 EXPORT_SYMBOL_GPL(snd_hdac_link_free_all); 134 135 /** 136 * snd_hdac_ext_bus_get_link - get link based on codec name 121 hlink = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list); 122 list_del(&hlink->list); 123 kfree(hlink); 124 } 125 } 126 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_free_all); 127 128 /** 129 * snd_hdac_ext_bus_get_hlink_by_addr - get hlink at specified address 130 * @bus: hlink's parent bus device 131 * @addr: codec device address 132 * 133 * Returns hlink object or NULL if matching hlink is not found. 134 */ 135 struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr) 136 { 137 struct hdac_ext_link *hlink; 138 139 list_for_each_entry(hlink, &bus->hlink_list, list) 140 if (hlink->lsdiid & (0x1 << addr)) 141 return hlink; 142 return NULL; 143 } 144 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_addr); 145 146 /** 147 * snd_hdac_ext_bus_get_hlink_by_name - get hlink based on codec name 137 148 * @bus: the pointer to HDAC bus object 138 149 * @codec_name: codec name 139 150 */ 140 struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, 141 const char *codec_name) 142 { 143 int i; 144 struct hdac_ext_link *hlink = NULL; 151 struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus, 152 const char *codec_name) 153 { 145 154 int bus_idx, addr; 146 155 … … 152 161 return NULL; 153 162 154 list_for_each_entry(hlink, &bus->hlink_list, list) { 155 for (i = 0; i < HDA_MAX_CODECS; i++) { 156 if (hlink->lsdiid & (0x1 << addr)) 157 return hlink; 158 } 159 } 160 161 return NULL; 162 } 163 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_link); 164 165 static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable) 163 return snd_hdac_ext_bus_get_hlink_by_addr(bus, addr); 164 } 165 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_name); 166 167 static int check_hdac_link_power_active(struct hdac_ext_link *hlink, bool enable) 166 168 { 167 169 int timeout; 168 170 u32 val; 169 int mask = (1 << AZX_ML CTL_CPA_SHIFT);171 int mask = (1 << AZX_ML_LCTL_CPA_SHIFT); 170 172 171 173 udelay(3); … … 173 175 174 176 do { 175 val = readl( link->ml_addr + AZX_REG_ML_LCTL);177 val = readl(hlink->ml_addr + AZX_REG_ML_LCTL); 176 178 if (enable) { 177 if (((val & mask) >> AZX_ML CTL_CPA_SHIFT))179 if (((val & mask) >> AZX_ML_LCTL_CPA_SHIFT)) 178 180 return 0; 179 181 } else { 180 if (!((val & mask) >> AZX_ML CTL_CPA_SHIFT))182 if (!((val & mask) >> AZX_ML_LCTL_CPA_SHIFT)) 181 183 return 0; 182 184 } … … 189 191 /** 190 192 * snd_hdac_ext_bus_link_power_up -power up hda link 191 * @ link: HD-audio extended link192 */ 193 int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link * link)194 { 195 snd_hdac_updatel( link->ml_addr, AZX_REG_ML_LCTL,196 AZX_ML CTL_SPA, AZX_MLCTL_SPA);197 198 return check_hdac_link_power_active( link, true);193 * @hlink: HD-audio extended link 194 */ 195 int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *hlink) 196 { 197 snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, 198 AZX_ML_LCTL_SPA, AZX_ML_LCTL_SPA); 199 200 return check_hdac_link_power_active(hlink, true); 199 201 } 200 202 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_up); … … 202 204 /** 203 205 * snd_hdac_ext_bus_link_power_down -power down hda link 204 * @ link: HD-audio extended link205 */ 206 int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link * link)207 { 208 snd_hdac_updatel( link->ml_addr, AZX_REG_ML_LCTL, AZX_MLCTL_SPA, 0);209 210 return check_hdac_link_power_active( link, false);206 * @hlink: HD-audio extended link 207 */ 208 int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *hlink) 209 { 210 snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, AZX_ML_LCTL_SPA, 0); 211 212 return check_hdac_link_power_active(hlink, false); 211 213 } 212 214 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down); … … 222 224 223 225 list_for_each_entry(hlink, &bus->hlink_list, list) { 224 snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, 225 AZX_MLCTL_SPA, AZX_MLCTL_SPA); 226 ret = check_hdac_link_power_active(hlink, true); 226 ret = snd_hdac_ext_bus_link_power_up(hlink); 227 227 if (ret < 0) 228 228 return ret; … … 243 243 244 244 list_for_each_entry(hlink, &bus->hlink_list, list) { 245 snd_hdac_updatel(hlink->ml_addr, AZX_REG_ML_LCTL, 246 AZX_MLCTL_SPA, 0); 247 ret = check_hdac_link_power_active(hlink, false); 245 ret = snd_hdac_ext_bus_link_power_down(hlink); 248 246 if (ret < 0) 249 247 return ret; … … 254 252 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); 255 253 254 /** 255 * snd_hdac_ext_bus_link_set_stream_id - maps stream id to link output 256 * @link: HD-audio ext link to set up 257 * @stream: stream id 258 */ 259 void snd_hdac_ext_bus_link_set_stream_id(struct hdac_ext_link *link, 260 int stream) 261 { 262 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 1 << stream); 263 } 264 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_set_stream_id); 265 266 /** 267 * snd_hdac_ext_bus_link_clear_stream_id - maps stream id to link output 268 * @link: HD-audio ext link to set up 269 * @stream: stream id 270 */ 271 void snd_hdac_ext_bus_link_clear_stream_id(struct hdac_ext_link *link, 272 int stream) 273 { 274 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0); 275 } 276 EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_clear_stream_id); 277 256 278 int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, 257 struct hdac_ext_link * link)279 struct hdac_ext_link *hlink) 258 280 { 259 281 unsigned long codec_mask; … … 266 288 * as well, also check the dma status and trigger that 267 289 */ 268 if (++ link->ref_count == 1) {290 if (++hlink->ref_count == 1) { 269 291 if (!bus->cmd_dma_state) { 270 292 snd_hdac_bus_init_cmd_io(bus); … … 272 294 } 273 295 274 ret = snd_hdac_ext_bus_link_power_up( link);296 ret = snd_hdac_ext_bus_link_power_up(hlink); 275 297 276 298 /* 277 299 * clear the register to invalidate all the output streams 278 300 */ 279 snd_hdac_updatew( link->ml_addr, AZX_REG_ML_LOSIDV,280 ML_LOSIDV_STREAM_MASK, 0);301 snd_hdac_updatew(hlink->ml_addr, AZX_REG_ML_LOSIDV, 302 AZX_ML_LOSIDV_STREAM_MASK, 0); 281 303 /* 282 304 * wait for 521usec for codec to report status … … 297 319 298 320 int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, 299 struct hdac_ext_link *link)321 struct hdac_ext_link *hlink) 300 322 { 301 323 int ret = 0; 302 struct hdac_ext_link *hlink ;324 struct hdac_ext_link *hlink_tmp; 303 325 bool link_up = false; 304 326 … … 309 331 * so power down this link as well 310 332 */ 311 if (-- link->ref_count == 0) {312 ret = snd_hdac_ext_bus_link_power_down( link);333 if (--hlink->ref_count == 0) { 334 ret = snd_hdac_ext_bus_link_power_down(hlink); 313 335 314 336 /* … … 316 338 * cmd dma as well 317 339 */ 318 list_for_each_entry(hlink , &bus->hlink_list, list) {319 if (hlink ->ref_count) {340 list_for_each_entry(hlink_tmp, &bus->hlink_list, list) { 341 if (hlink_tmp->ref_count) { 320 342 link_up = true; 321 343 break; … … 338 360 const char *devname = dev_name(&codec->dev); 339 361 struct hdac_ext_link *hlink = 340 snd_hdac_ext_bus_get_ link(codec->bus, devname);362 snd_hdac_ext_bus_get_hlink_by_name(codec->bus, devname); 341 363 342 364 if (hlink) … … 348 370 const char *devname = dev_name(&codec->dev); 349 371 struct hdac_ext_link *hlink = 350 snd_hdac_ext_bus_get_ link(codec->bus, devname);372 snd_hdac_ext_bus_get_hlink_by_name(codec->bus, devname); 351 373 352 374 if (hlink) -
GPL/trunk/alsa-kernel/hda/ext/hdac_ext_stream.c
r717 r772 15 15 #include <sound/hda_register.h> 16 16 #include <sound/hdaudio_ext.h> 17 #include <sound/compress_driver.h> 17 18 18 19 /** 19 20 * snd_hdac_ext_stream_init - initialize each stream (aka device) 20 21 * @bus: HD-audio core bus 21 * @ stream: HD-audio ext core stream object to initialize22 * @hext_stream: HD-audio ext core stream object to initialize 22 23 * @idx: stream index number 23 24 * @direction: stream direction (SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE) … … 27 28 * invoke hdac stream initialization routine 28 29 */ 29 void snd_hdac_ext_stream_init(struct hdac_bus *bus,30 struct hdac_ext_stream *stream,31 int idx, int direction, int tag)30 static void snd_hdac_ext_stream_init(struct hdac_bus *bus, 31 struct hdac_ext_stream *hext_stream, 32 int idx, int direction, int tag) 32 33 { 33 34 if (bus->ppcap) { 34 stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +35 hext_stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE + 35 36 AZX_PPHC_INTERVAL * idx; 36 37 37 stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE +38 hext_stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE + 38 39 AZX_PPLC_MULTI * bus->num_streams + 39 40 AZX_PPLC_INTERVAL * idx; 40 41 } 41 42 42 if (bus->spbcap) { 43 stream->spib_addr = bus->spbcap + AZX_SPB_BASE + 44 AZX_SPB_INTERVAL * idx + 45 AZX_SPB_SPIB; 46 47 stream->fifo_addr = bus->spbcap + AZX_SPB_BASE + 48 AZX_SPB_INTERVAL * idx + 49 AZX_SPB_MAXFIFO; 50 } 51 52 if (bus->drsmcap) 53 stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE + 54 AZX_DRSM_INTERVAL * idx; 55 56 stream->decoupled = false; 57 snd_hdac_stream_init(bus, &stream->hstream, idx, direction, tag); 58 } 59 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init); 43 hext_stream->decoupled = false; 44 snd_hdac_stream_init(bus, &hext_stream->hstream, idx, direction, tag); 45 } 60 46 61 47 /** … … 68 54 */ 69 55 int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, 70 int num_stream, int dir)56 int num_stream, int dir) 71 57 { 72 58 int stream_tag = 0; … … 74 60 75 61 for (i = 0; i < num_stream; i++) { 76 struct hdac_ext_stream * stream =77 kzalloc(sizeof(* stream), GFP_KERNEL);78 if (! stream)62 struct hdac_ext_stream *hext_stream = 63 kzalloc(sizeof(*hext_stream), GFP_KERNEL); 64 if (!hext_stream) 79 65 return -ENOMEM; 80 66 tag = ++stream_tag; 81 snd_hdac_ext_stream_init(bus, stream, idx, dir, tag);67 snd_hdac_ext_stream_init(bus, hext_stream, idx, dir, tag); 82 68 idx++; 83 69 } … … 89 75 90 76 /** 91 * snd_hdac_ stream_free_all - free hdac extended stream objects92 * 93 * @bus: HD-audio core bus 94 */ 95 void snd_hdac_ stream_free_all(struct hdac_bus *bus)77 * snd_hdac_ext_stream_free_all - free hdac extended stream objects 78 * 79 * @bus: HD-audio core bus 80 */ 81 void snd_hdac_ext_stream_free_all(struct hdac_bus *bus) 96 82 { 97 83 struct hdac_stream *s, *_s; 98 struct hdac_ext_stream * stream;84 struct hdac_ext_stream *hext_stream; 99 85 100 86 list_for_each_entry_safe(s, _s, &bus->stream_list, list) { 101 stream = stream_to_hdac_ext_stream(s);102 snd_hdac_ext_stream_decouple(bus, stream, false);87 hext_stream = stream_to_hdac_ext_stream(s); 88 snd_hdac_ext_stream_decouple(bus, hext_stream, false); 103 89 list_del(&s->list); 104 kfree( stream);105 } 106 } 107 EXPORT_SYMBOL_GPL(snd_hdac_ stream_free_all);90 kfree(hext_stream); 91 } 92 } 93 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_free_all); 108 94 109 95 void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus, 110 struct hdac_ext_stream * stream,96 struct hdac_ext_stream *hext_stream, 111 97 bool decouple) 112 98 { 113 struct hdac_stream *hstream = & stream->hstream;99 struct hdac_stream *hstream = &hext_stream->hstream; 114 100 u32 val; 115 101 int mask = AZX_PPCTL_PROCEN(hstream->index); … … 122 108 snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, 0); 123 109 124 stream->decoupled = decouple;110 hext_stream->decoupled = decouple; 125 111 } 126 112 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple_locked); … … 129 115 * snd_hdac_ext_stream_decouple - decouple the hdac stream 130 116 * @bus: HD-audio core bus 131 * @ stream: HD-audio ext core stream object to initialize117 * @hext_stream: HD-audio ext core stream object to initialize 132 118 * @decouple: flag to decouple 133 119 */ 134 120 void snd_hdac_ext_stream_decouple(struct hdac_bus *bus, 135 struct hdac_ext_stream * stream, bool decouple)121 struct hdac_ext_stream *hext_stream, bool decouple) 136 122 { 137 123 spin_lock_irq(&bus->reg_lock); 138 snd_hdac_ext_stream_decouple_locked(bus, stream, decouple);124 snd_hdac_ext_stream_decouple_locked(bus, hext_stream, decouple); 139 125 spin_unlock_irq(&bus->reg_lock); 140 126 } … … 142 128 143 129 /** 144 * snd_hdac_ext_ link_stream_start - start a stream145 * @ stream: HD-audio ext core stream to start146 */ 147 void snd_hdac_ext_ link_stream_start(struct hdac_ext_stream *stream)148 { 149 snd_hdac_updatel( stream->pplc_addr, AZX_REG_PPLCCTL,130 * snd_hdac_ext_stream_start - start a stream 131 * @hext_stream: HD-audio ext core stream to start 132 */ 133 void snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream) 134 { 135 snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, 150 136 AZX_PPLCCTL_RUN, AZX_PPLCCTL_RUN); 151 137 } 152 EXPORT_SYMBOL_GPL(snd_hdac_ext_ link_stream_start);153 154 /** 155 * snd_hdac_ext_ link_stream_clear - stop a stream DMA156 * @ stream: HD-audio ext core stream to stop157 */ 158 void snd_hdac_ext_ link_stream_clear(struct hdac_ext_stream *stream)159 { 160 snd_hdac_updatel( stream->pplc_addr, AZX_REG_PPLCCTL, AZX_PPLCCTL_RUN, 0);161 } 162 EXPORT_SYMBOL_GPL(snd_hdac_ext_ link_stream_clear);163 164 /** 165 * snd_hdac_ext_ link_stream_reset - reset a stream166 * @ stream: HD-audio ext core stream to reset167 */ 168 void snd_hdac_ext_ link_stream_reset(struct hdac_ext_stream *stream)138 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_start); 139 140 /** 141 * snd_hdac_ext_stream_clear - stop a stream DMA 142 * @hext_stream: HD-audio ext core stream to stop 143 */ 144 void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream) 145 { 146 snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, AZX_PPLCCTL_RUN, 0); 147 } 148 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_clear); 149 150 /** 151 * snd_hdac_ext_stream_reset - reset a stream 152 * @hext_stream: HD-audio ext core stream to reset 153 */ 154 void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream) 169 155 { 170 156 unsigned char val; 171 157 int timeout; 172 158 173 snd_hdac_ext_ link_stream_clear(stream);174 175 snd_hdac_updatel( stream->pplc_addr, AZX_REG_PPLCCTL,159 snd_hdac_ext_stream_clear(hext_stream); 160 161 snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, 176 162 AZX_PPLCCTL_STRST, AZX_PPLCCTL_STRST); 177 163 udelay(3); 178 164 timeout = 50; 179 165 do { 180 val = readl( stream->pplc_addr + AZX_REG_PPLCCTL) &166 val = readl(hext_stream->pplc_addr + AZX_REG_PPLCCTL) & 181 167 AZX_PPLCCTL_STRST; 182 168 if (val) … … 185 171 } while (--timeout); 186 172 val &= ~AZX_PPLCCTL_STRST; 187 writel(val, stream->pplc_addr + AZX_REG_PPLCCTL);173 writel(val, hext_stream->pplc_addr + AZX_REG_PPLCCTL); 188 174 udelay(3); 189 175 … … 191 177 /* waiting for hardware to report that the stream is out of reset */ 192 178 do { 193 val = readl( stream->pplc_addr + AZX_REG_PPLCCTL) & AZX_PPLCCTL_STRST;179 val = readl(hext_stream->pplc_addr + AZX_REG_PPLCCTL) & AZX_PPLCCTL_STRST; 194 180 if (!val) 195 181 break; … … 198 184 199 185 } 200 EXPORT_SYMBOL_GPL(snd_hdac_ext_ link_stream_reset);201 202 /** 203 * snd_hdac_ext_ link_stream_setup - set up the SD for streaming204 * @ stream: HD-audio ext core stream to set up186 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_reset); 187 188 /** 189 * snd_hdac_ext_stream_setup - set up the SD for streaming 190 * @hext_stream: HD-audio ext core stream to set up 205 191 * @fmt: stream format 206 192 */ 207 int snd_hdac_ext_ link_stream_setup(struct hdac_ext_stream *stream, int fmt)208 { 209 struct hdac_stream *hstream = & stream->hstream;193 int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt) 194 { 195 struct hdac_stream *hstream = &hext_stream->hstream; 210 196 unsigned int val; 211 197 212 198 /* make sure the run bit is zero for SD */ 213 snd_hdac_ext_ link_stream_clear(stream);199 snd_hdac_ext_stream_clear(hext_stream); 214 200 /* program the stream_tag */ 215 val = readl( stream->pplc_addr + AZX_REG_PPLCCTL);201 val = readl(hext_stream->pplc_addr + AZX_REG_PPLCCTL); 216 202 val = (val & ~AZX_PPLCCTL_STRM_MASK) | 217 203 (hstream->stream_tag << AZX_PPLCCTL_STRM_SHIFT); 218 writel(val, stream->pplc_addr + AZX_REG_PPLCCTL);204 writel(val, hext_stream->pplc_addr + AZX_REG_PPLCCTL); 219 205 220 206 /* program the stream format */ 221 writew(fmt, stream->pplc_addr + AZX_REG_PPLCFMT);207 writew(fmt, hext_stream->pplc_addr + AZX_REG_PPLCFMT); 222 208 223 209 return 0; 224 210 } 225 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_setup); 226 227 /** 228 * snd_hdac_ext_link_set_stream_id - maps stream id to link output 229 * @link: HD-audio ext link to set up 230 * @stream: stream id 231 */ 232 void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link, 233 int stream) 234 { 235 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 1 << stream); 236 } 237 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id); 238 239 /** 240 * snd_hdac_ext_link_clear_stream_id - maps stream id to link output 241 * @link: HD-audio ext link to set up 242 * @stream: stream id 243 */ 244 void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, 245 int stream) 246 { 247 snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0); 248 } 249 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id); 211 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_setup); 250 212 251 213 static struct hdac_ext_stream * 252 hdac_ext_link_ stream_assign(struct hdac_bus *bus,214 hdac_ext_link_dma_stream_assign(struct hdac_bus *bus, 253 215 struct snd_pcm_substream *substream) 254 216 { 255 217 struct hdac_ext_stream *res = NULL; 256 struct hdac_stream * stream = NULL;218 struct hdac_stream *hstream = NULL; 257 219 258 220 if (!bus->ppcap) { … … 262 224 263 225 spin_lock_irq(&bus->reg_lock); 264 list_for_each_entry( stream, &bus->stream_list, list) {265 struct hdac_ext_stream *h stream = container_of(stream,266 struct hdac_ext_stream,267 hstream);268 if ( stream->direction != substream->stream)226 list_for_each_entry(hstream, &bus->stream_list, list) { 227 struct hdac_ext_stream *hext_stream = container_of(hstream, 228 struct hdac_ext_stream, 229 hstream); 230 if (hstream->direction != substream->stream) 269 231 continue; 270 232 271 /* check if decoupled stream and not in useis available */272 if ( hstream->decoupled && !hstream->link_locked) {273 res = h stream;233 /* check if link stream is available */ 234 if (!hext_stream->link_locked) { 235 res = hext_stream; 274 236 break; 275 237 } 276 238 277 if (!hstream->link_locked) {278 snd_hdac_ext_stream_decouple_locked(bus, hstream, true);279 res = hstream;280 break;281 }282 239 } 283 240 if (res) { 241 snd_hdac_ext_stream_decouple_locked(bus, res, true); 284 242 res->link_locked = 1; 285 243 res->link_substream = substream; … … 290 248 291 249 static struct hdac_ext_stream * 292 hdac_ext_host_ stream_assign(struct hdac_bus *bus,250 hdac_ext_host_dma_stream_assign(struct hdac_bus *bus, 293 251 struct snd_pcm_substream *substream) 294 252 { 295 253 struct hdac_ext_stream *res = NULL; 296 struct hdac_stream * stream = NULL;254 struct hdac_stream *hstream = NULL; 297 255 298 256 if (!bus->ppcap) { … … 302 260 303 261 spin_lock_irq(&bus->reg_lock); 304 list_for_each_entry( stream, &bus->stream_list, list) {305 struct hdac_ext_stream *h stream = container_of(stream,306 struct hdac_ext_stream,307 hstream);308 if ( stream->direction != substream->stream)262 list_for_each_entry(hstream, &bus->stream_list, list) { 263 struct hdac_ext_stream *hext_stream = container_of(hstream, 264 struct hdac_ext_stream, 265 hstream); 266 if (hstream->direction != substream->stream) 309 267 continue; 310 268 311 if (!stream->opened) { 312 if (!hstream->decoupled) 313 snd_hdac_ext_stream_decouple_locked(bus, hstream, true); 314 res = hstream; 269 if (!hstream->opened) { 270 res = hext_stream; 315 271 break; 316 272 } 317 273 } 318 274 if (res) { 275 snd_hdac_ext_stream_decouple_locked(bus, res, true); 319 276 res->hstream.opened = 1; 320 277 res->hstream.running = 0; … … 347 304 int type) 348 305 { 349 struct hdac_ext_stream *h stream = NULL;350 struct hdac_stream * stream = NULL;306 struct hdac_ext_stream *hext_stream = NULL; 307 struct hdac_stream *hstream = NULL; 351 308 352 309 switch (type) { 353 310 case HDAC_EXT_STREAM_TYPE_COUPLED: 354 stream = snd_hdac_stream_assign(bus, substream); 355 if (stream) 356 hstream = container_of(stream, 357 struct hdac_ext_stream, hstream); 358 return hstream; 311 hstream = snd_hdac_stream_assign(bus, substream); 312 if (hstream) 313 hext_stream = container_of(hstream, 314 struct hdac_ext_stream, 315 hstream); 316 return hext_stream; 359 317 360 318 case HDAC_EXT_STREAM_TYPE_HOST: 361 return hdac_ext_host_ stream_assign(bus, substream);319 return hdac_ext_host_dma_stream_assign(bus, substream); 362 320 363 321 case HDAC_EXT_STREAM_TYPE_LINK: 364 return hdac_ext_link_ stream_assign(bus, substream);322 return hdac_ext_link_dma_stream_assign(bus, substream); 365 323 366 324 default: … … 372 330 /** 373 331 * snd_hdac_ext_stream_release - release the assigned stream 374 * @ stream: HD-audio ext core stream to release332 * @hext_stream: HD-audio ext core stream to release 375 333 * @type: type of stream (coupled, host or link stream) 376 334 * 377 335 * Release the stream that has been assigned by snd_hdac_ext_stream_assign(). 378 336 */ 379 void snd_hdac_ext_stream_release(struct hdac_ext_stream * stream, int type)380 { 381 struct hdac_bus *bus = stream->hstream.bus;337 void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type) 338 { 339 struct hdac_bus *bus = hext_stream->hstream.bus; 382 340 383 341 switch (type) { 384 342 case HDAC_EXT_STREAM_TYPE_COUPLED: 385 snd_hdac_stream_release(& stream->hstream);343 snd_hdac_stream_release(&hext_stream->hstream); 386 344 break; 387 345 388 346 case HDAC_EXT_STREAM_TYPE_HOST: 389 347 spin_lock_irq(&bus->reg_lock); 390 if (stream->decoupled && !stream->link_locked) 391 snd_hdac_ext_stream_decouple_locked(bus, stream, false); 348 /* couple link only if not in use */ 349 if (!hext_stream->link_locked) 350 snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false); 351 snd_hdac_stream_release_locked(&hext_stream->hstream); 392 352 spin_unlock_irq(&bus->reg_lock); 393 snd_hdac_stream_release(&stream->hstream);394 353 break; 395 354 396 355 case HDAC_EXT_STREAM_TYPE_LINK: 397 356 spin_lock_irq(&bus->reg_lock); 398 if (stream->decoupled && !stream->hstream.opened) 399 snd_hdac_ext_stream_decouple_locked(bus, stream, false); 400 stream->link_locked = 0; 401 stream->link_substream = NULL; 357 /* couple host only if not in use */ 358 if (!hext_stream->hstream.opened) 359 snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false); 360 hext_stream->link_locked = 0; 361 hext_stream->link_substream = NULL; 402 362 spin_unlock_irq(&bus->reg_lock); 403 363 break; … … 411 371 412 372 /** 413 * snd_hdac_ext_stream_spbcap_enable - enable SPIB for a stream 414 * @bus: HD-audio core bus 415 * @enable: flag to enable/disable SPIB 416 * @index: stream index for which SPIB need to be enabled 417 */ 418 void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus, 419 bool enable, int index) 420 { 421 u32 mask = 0; 422 423 if (!bus->spbcap) { 424 dev_err(bus->dev, "Address of SPB capability is NULL\n"); 425 return; 426 } 427 428 mask |= (1 << index); 429 430 if (enable) 431 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, mask); 432 else 433 snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); 434 } 435 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); 436 437 /** 438 * snd_hdac_ext_stream_set_spib - sets the spib value of a stream 439 * @bus: HD-audio core bus 440 * @stream: hdac_ext_stream 441 * @value: spib value to set 442 */ 443 int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus, 444 struct hdac_ext_stream *stream, u32 value) 445 { 446 447 if (!bus->spbcap) { 448 dev_err(bus->dev, "Address of SPB capability is NULL\n"); 449 return -EINVAL; 450 } 451 452 writel(value, stream->spib_addr); 453 454 return 0; 455 } 456 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_spib); 457 458 /** 459 * snd_hdac_ext_stream_get_spbmaxfifo - gets the spib value of a stream 460 * @bus: HD-audio core bus 461 * @stream: hdac_ext_stream 462 * 463 * Return maxfifo for the stream 464 */ 465 int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus, 466 struct hdac_ext_stream *stream) 467 { 468 469 if (!bus->spbcap) { 470 dev_err(bus->dev, "Address of SPB capability is NULL\n"); 471 return -EINVAL; 472 } 473 474 return readl(stream->fifo_addr); 475 } 476 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo); 477 478 479 /** 480 * snd_hdac_ext_stop_streams - stop all stream if running 481 * @bus: HD-audio core bus 482 */ 483 void snd_hdac_ext_stop_streams(struct hdac_bus *bus) 484 { 485 struct hdac_stream *stream; 486 487 if (bus->chip_init) { 488 list_for_each_entry(stream, &bus->stream_list, list) 489 snd_hdac_stream_stop(stream); 490 snd_hdac_bus_stop_chip(bus); 491 } 492 } 493 EXPORT_SYMBOL_GPL(snd_hdac_ext_stop_streams); 494 495 /** 496 * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream 497 * @bus: HD-audio core bus 498 * @enable: flag to enable/disable DRSM 499 * @index: stream index for which DRSM need to be enabled 500 */ 501 void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus, 502 bool enable, int index) 503 { 504 u32 mask = 0; 505 506 if (!bus->drsmcap) { 507 dev_err(bus->dev, "Address of DRSM capability is NULL\n"); 508 return; 509 } 510 511 mask |= (1 << index); 512 513 if (enable) 514 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, mask); 515 else 516 snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); 517 } 518 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); 519 520 /** 521 * snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream 522 * @bus: HD-audio core bus 523 * @stream: hdac_ext_stream 524 * @value: dpib value to set 525 */ 526 int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, 527 struct hdac_ext_stream *stream, u32 value) 528 { 529 530 if (!bus->drsmcap) { 531 dev_err(bus->dev, "Address of DRSM capability is NULL\n"); 532 return -EINVAL; 533 } 534 535 writel(value, stream->dpibr_addr); 536 537 return 0; 538 } 539 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr); 540 541 /** 542 * snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream 543 * @stream: hdac_ext_stream 544 * @value: lpib value to set 545 */ 546 int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *stream, u32 value) 547 { 548 snd_hdac_stream_writel(&stream->hstream, SD_LPIB, value); 549 550 return 0; 551 } 552 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_lpib); 373 * snd_hdac_ext_cstream_assign - assign a host stream for compress 374 * @bus: HD-audio core bus 375 * @cstream: Compress stream to assign 376 * 377 * Assign an unused host stream for the given compress stream. 378 * If no stream is free, NULL is returned. Stream is decoupled 379 * before assignment. 380 */ 381 struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus, 382 struct snd_compr_stream *cstream) 383 { 384 struct hdac_ext_stream *res = NULL; 385 struct hdac_stream *hstream; 386 387 spin_lock_irq(&bus->reg_lock); 388 list_for_each_entry(hstream, &bus->stream_list, list) { 389 struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream); 390 391 if (hstream->direction != cstream->direction) 392 continue; 393 394 if (!hstream->opened) { 395 res = hext_stream; 396 break; 397 } 398 } 399 400 if (res) { 401 snd_hdac_ext_stream_decouple_locked(bus, res, true); 402 res->hstream.opened = 1; 403 res->hstream.running = 0; 404 res->hstream.cstream = cstream; 405 } 406 spin_unlock_irq(&bus->reg_lock); 407 408 return res; 409 } 410 EXPORT_SYMBOL_GPL(snd_hdac_ext_cstream_assign);
Note:
See TracChangeset
for help on using the changeset viewer.
