Changeset 8d070710 in mainline for uspace/drv/audio/hdaudio/hdactl.c
- 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
- File:
-
- 1 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:
Note:
See TracChangeset
for help on using the changeset viewer.