Changeset 8d070710 in mainline
- Timestamp:
- 2014-08-14T11:12:19Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d2d5329
- Parents:
- 7978d1e7
- Location:
- uspace/drv/audio/hdaudio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/hdaudio/hdactl.c
r7978d1e7 r8d070710 48 48 enum { 49 49 ctrl_init_wait_max = 10, 50 codec_enum_wait_us = 512 50 codec_enum_wait_us = 512, 51 corb_wait_max = 10 51 52 }; 52 53 … … 104 105 ddf_msg(LVL_NOTE, "hda_corb_init()"); 105 106 106 /* Stop CORB if not stopped .*/107 /* Stop CORB if not stopped */ 107 108 ctl = hda_reg8_read(&hda->regs->corbctl); 108 109 if ((ctl & BIT_V(uint8_t, corbctl_run)) != 0) { … … 148 149 hda_reg32_write(&hda->regs->corbubase, UPPER32(hda->ctl->corb_phys)); 149 150 150 ddf_msg(LVL_NOTE, "R set CORB Read/Write pointers");151 ddf_msg(LVL_NOTE, "Reset CORB Read/Write pointers"); 151 152 152 153 /* Reset CORB Read Pointer */ … … 155 156 /* Reset CORB Write Poitner */ 156 157 hda_reg16_write(&hda->regs->corbwp, 0); 158 159 /* Start CORB */ 160 ctl = hda_reg8_read(&hda->regs->corbctl); 161 ddf_msg(LVL_NOTE, "CORBctl (0x%x) = 0x%x", 162 (unsigned)((void *)&hda->regs->corbctl - (void *)hda->regs), ctl | BIT_V(uint8_t, corbctl_run)); 163 hda_reg8_write(&hda->regs->corbctl, ctl | BIT_V(uint8_t, corbctl_run)); 157 164 158 165 ddf_msg(LVL_NOTE, "CORB initialized"); … … 174 181 ddf_msg(LVL_NOTE, "hda_rirb_init()"); 175 182 176 /* Stop RIRB if not stopped .*/183 /* Stop RIRB if not stopped */ 177 184 ctl = hda_reg8_read(&hda->regs->rirbctl); 178 185 if ((ctl & BIT_V(uint8_t, rirbctl_run)) != 0) { … … 218 225 hda_reg32_write(&hda->regs->rirbubase, UPPER32(hda->ctl->rirb_phys)); 219 226 220 ddf_msg(LVL_NOTE, "R set RIRB Write pointer");227 ddf_msg(LVL_NOTE, "Reset RIRB Write pointer"); 221 228 222 229 /* Reset RIRB Write Pointer */ 223 230 hda_reg16_write(&hda->regs->rirbwp, BIT_V(uint16_t, rirbwp_rst)); 231 232 /* Set RINTCNT - Qemu won't read from CORB if this is zero */ 233 hda_reg16_write(&hda->regs->rintcnt, 2); 234 235 hda->ctl->rirb_rp = 0; 236 237 /* Start RIRB */ 238 ctl = hda_reg8_read(&hda->regs->rirbctl); 239 ddf_msg(LVL_NOTE, "RIRBctl (0x%x) = 0x%x", 240 (unsigned)((void *)&hda->regs->rirbctl - (void *)hda->regs), ctl | BIT_V(uint8_t, rirbctl_run)); 241 hda_reg8_write(&hda->regs->rirbctl, ctl | BIT_V(uint8_t, rirbctl_run)); 224 242 225 243 ddf_msg(LVL_NOTE, "RIRB initialized"); … … 229 247 } 230 248 249 static size_t hda_get_corbrp(hda_t *hda) 250 { 251 uint16_t corbrp; 252 253 corbrp = hda_reg16_read(&hda->regs->corbrp); 254 return BIT_RANGE_EXTRACT(uint16_t, corbrp_rp_h, corbrp_rp_l, corbrp); 255 } 256 257 static size_t hda_get_corbwp(hda_t *hda) 258 { 259 uint16_t corbwp; 260 261 corbwp = hda_reg16_read(&hda->regs->corbwp); 262 return BIT_RANGE_EXTRACT(uint16_t, corbwp_wp_h, corbwp_wp_l, corbwp); 263 } 264 265 static void hda_set_corbwp(hda_t *hda, size_t wp) 266 { 267 ddf_msg(LVL_NOTE, "Set CORBWP = %d", wp); 268 hda_reg16_write(&hda->regs->corbwp, wp); 269 } 270 271 static size_t hda_get_rirbwp(hda_t *hda) 272 { 273 uint16_t rirbwp; 274 275 rirbwp = hda_reg16_read(&hda->regs->rirbwp); 276 return BIT_RANGE_EXTRACT(uint16_t, rirbwp_wp_h, rirbwp_wp_l, rirbwp); 277 } 278 279 /** Determine number of free entries in CORB */ 280 static size_t hda_corb_avail(hda_t *hda) 281 { 282 int rp, wp; 283 int avail; 284 285 rp = hda_get_corbrp(hda); 286 wp = hda_get_corbwp(hda); 287 288 avail = rp - wp - 1; 289 while (avail < 0) 290 avail += hda->ctl->corb_entries; 291 292 return avail; 293 } 294 295 /** Write to CORB */ 296 static int hda_corb_write(hda_t *hda, uint32_t *data, size_t count) 297 { 298 size_t avail; 299 size_t wp; 300 size_t idx; 301 size_t now; 302 size_t i; 303 uint32_t *corb; 304 int wcnt; 305 306 avail = hda_corb_avail(hda); 307 wp = hda_get_corbwp(hda); 308 corb = (uint32_t *)hda->ctl->corb_virt; 309 310 idx = 0; 311 while (idx < count) { 312 now = min(avail, count - idx); 313 314 for (i = 0; i < now; i++) { 315 wp = (wp + 1) % hda->ctl->corb_entries; 316 corb[wp] = data[idx++]; 317 } 318 319 hda_set_corbwp(hda, wp); 320 321 if (idx < count) { 322 /* We filled up CORB but still data remaining */ 323 wcnt = corb_wait_max; 324 while (hda_corb_avail(hda) < 1 && wcnt > 0) { 325 async_usleep(100); 326 --wcnt; 327 } 328 329 /* If CORB is still full return timeout error */ 330 if (hda_corb_avail(hda) < 1) 331 return ETIMEOUT; 332 } 333 } 334 335 return EOK; 336 } 337 338 static void hda_rirb_read(hda_t *hda) 339 { 340 size_t wp; 341 hda_rirb_entry_t resp; 342 hda_rirb_entry_t *rirb; 343 344 rirb = (hda_rirb_entry_t *)hda->ctl->rirb_virt; 345 346 wp = hda_get_rirbwp(hda); 347 ddf_msg(LVL_NOTE, "hda_rirb_read: wp=%d", wp); 348 while (hda->ctl->rirb_rp != wp) { 349 ++hda->ctl->rirb_rp; 350 resp = rirb[hda->ctl->rirb_rp]; 351 352 ddf_msg(LVL_NOTE, "RESPONSE resp=0x%x respex=0x%x", 353 resp.resp, resp.respex); 354 } 355 } 356 357 #include "spec/codec.h" 231 358 hda_ctl_t *hda_ctl_init(hda_t *hda) 232 359 { … … 299 426 goto error; 300 427 428 uint32_t verb; 429 verb = (0 << 28) | (0 << 20) | ((hda_get_param) << 8) | (hda_sub_nc); 430 rc = hda_corb_write(hda, &verb, 1); 431 ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc); 432 rc = hda_corb_write(hda, &verb, 1); 433 ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc); 434 rc = hda_corb_write(hda, &verb, 1); 435 ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc); 436 rc = hda_corb_write(hda, &verb, 1); 437 ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc); 438 439 async_usleep(100*1000); 440 hda_rirb_read(hda); 441 301 442 return ctl; 302 443 error: -
uspace/drv/audio/hdaudio/hdactl.h
r7978d1e7 r8d070710 46 46 void *rirb_virt; 47 47 size_t rirb_entries; 48 size_t rirb_rp; 48 49 } hda_ctl_t; 49 50 -
uspace/drv/audio/hdaudio/spec/codec.h
r7978d1e7 r8d070710 70 70 hda_spdif_ctl_set1 = 0x70d, 71 71 /** S/PDIF Converter Control / Set 2 */ 72 hda_spdif_ctl_set 1= 0x70e,72 hda_spdif_ctl_set2 = 0x70e, 73 73 /** S/PDIF Converter Control / Set 3 */ 74 hda_spdif_ctl_set 1= 0x73e,74 hda_spdif_ctl_set3 = 0x73e, 75 75 /** S/PDIF Converter Control / Set 4 */ 76 hda_spdif_ctl_set 1= 0x73f,76 hda_spdif_ctl_set4 = 0x73f, 77 77 /** Power State / Get */ 78 78 hda_power_state_get = 0xf05, … … 91 91 /** Enable VRef / Set */ 92 92 hda_enable_vref_set = 0x707, 93 /** Connection SelectControl / Get */94 hda_ conn_sel_get = 0xf08,95 /** Connection SelectControl / Set */96 hda_ conn_sel_set = 0x70893 /** Unsolicited Response Control / Get */ 94 hda_unsol_resp_get = 0xf08, 95 /** Unsolicied Response Control / Set */ 96 hda_unsol_resp_set = 0x708 97 97 } hda_verb_t; 98 98 -
uspace/drv/audio/hdaudio/spec/regs.h
r7978d1e7 r8d070710 201 201 202 202 typedef enum { 203 /** CORB Write Pointer (H) */ 204 corbwp_wp_h = 7, 205 /** CORB Write Pointer (L) */ 206 corbwp_wp_l = 0 207 } hda_corbwp_bits_t; 208 209 typedef enum { 203 210 /** Enable CORB DMA Engine */ 204 211 corbctl_run = 1, … … 224 231 rirbwp_wp_h = 7, 225 232 /** RIRB Write Pointer (L) */ 226 rirb rp_wp_l = 0233 rirbwp_wp_l = 0 227 234 } hda_rirbwp_bits_t; 228 235 … … 247 254 } hda_rirbsize_bits_t; 248 255 256 typedef struct { 257 /** Response - data received from codec */ 258 uint32_t resp; 259 /** Response Extended - added by controller */ 260 uint32_t respex; 261 } hda_rirb_entry_t; 262 263 typedef enum { 264 /** Unsolicited response */ 265 respex_unsol = 4, 266 /** Codec Address (H) */ 267 respex_addr_h = 3, 268 /** Codec Address (L) */ 269 respex_addr_l = 0 270 } hda_respex_bits_t; 271 249 272 #endif 250 273
Note:
See TracChangeset
for help on using the changeset viewer.