2 * ES1370 Haiku Driver for ES1370 audio
4 * Copyright 2002-2007, Haiku, Inc.
5 * Distributed under the terms of the MIT License.
8 * Jerome Duval, jerome.duval@free.fr
11 #include <KernelExport.h>
13 #include <driver_settings.h>
26 status_t
init_hardware(void);
27 status_t
init_driver(void);
28 void uninit_driver(void);
29 const char ** publish_devices(void);
30 device_hooks
* find_device(const char *);
31 status_t
es1370_init(es1370_dev
* card
);
33 static char pci_name
[] = B_PCI_MODULE_NAME
;
37 es1370_dev cards
[NUM_CARDS
];
39 char * names
[NUM_CARDS
*20+1];
41 extern device_hooks multi_hooks
;
43 es1370_settings current_settings
= {
50 /* es1370 Memory management */
53 es1370_mem_new(es1370_dev
*card
, size_t size
)
57 if ((mem
= malloc(sizeof(*mem
))) == NULL
)
60 mem
->area
= alloc_mem(&mem
->phy_base
, &mem
->log_base
, size
, "es1370 buffer");
62 if (mem
->area
< B_OK
) {
70 es1370_mem_delete(es1370_mem
*mem
)
73 delete_area(mem
->area
);
78 es1370_mem_alloc(es1370_dev
*card
, size_t size
)
82 mem
= es1370_mem_new(card
, size
);
86 LIST_INSERT_HEAD(&(card
->mems
), mem
, next
);
92 es1370_mem_free(es1370_dev
*card
, void *ptr
)
96 LIST_FOREACH(mem
, &card
->mems
, next
) {
97 if (mem
->log_base
!= ptr
)
99 LIST_REMOVE(mem
, next
);
101 es1370_mem_delete(mem
);
106 /* es1370 stream functions */
109 es1370_stream_set_audioparms(es1370_stream
*stream
, uint8 channels
,
110 uint8 b16
, uint32 sample_rate
)
112 uint8 sample_size
, frame_size
;
113 LOG(("es1370_stream_set_audioparms\n"));
115 if ((stream
->channels
== channels
) &&
116 (stream
->b16
== b16
) &&
117 (stream
->sample_rate
== sample_rate
))
121 es1370_mem_free(stream
->card
, stream
->buffer
->log_base
);
124 stream
->sample_rate
= sample_rate
;
125 stream
->channels
= channels
;
127 sample_size
= stream
->b16
+ 1;
128 frame_size
= sample_size
* stream
->channels
;
130 stream
->buffer
= es1370_mem_alloc(stream
->card
, stream
->bufframes
* frame_size
* stream
->bufcount
);
132 stream
->trigblk
= 0; /* This shouldn't be needed */
133 stream
->blkmod
= stream
->bufcount
;
134 stream
->blksize
= stream
->bufframes
* frame_size
;
140 es1370_stream_commit_parms(es1370_stream
*stream
)
142 uint8 sample_size
, frame_size
;
144 es1370_dev
*card
= stream
->card
;
145 LOG(("es1370_stream_commit_parms\n"));
147 ctrl
= es1370_reg_read_32(&card
->config
, ES1370_REG_CONTROL
) & ~CTRL_PCLKDIV
;
148 ctrl
|= DAC2_SRTODIV((uint16
)stream
->sample_rate
) << CTRL_SH_PCLKDIV
;
149 es1370_reg_write_32(&card
->config
, ES1370_REG_CONTROL
, ctrl
);
151 sample_size
= stream
->b16
+ 1;
152 frame_size
= sample_size
* stream
->channels
;
154 if (stream
->use
& ES1370_USE_RECORD
) {
155 es1370_reg_write_32(&card
->config
, ES1370_REG_MEMPAGE
, 0xd);
156 es1370_reg_write_32(&card
->config
, ES1370_REG_ADC_FRAMEADR
& 0xff, (uint32
)stream
->buffer
->phy_base
);
157 es1370_reg_write_32(&card
->config
, ES1370_REG_ADC_FRAMECNT
& 0xff, ((stream
->blksize
* stream
->bufcount
) >> 2) - 1);
158 es1370_reg_write_32(&card
->config
, ES1370_REG_ADC_SCOUNT
& 0xff, stream
->bufframes
- 1);
160 es1370_reg_write_32(&card
->config
, ES1370_REG_MEMPAGE
, 0xc);
161 es1370_reg_write_32(&card
->config
, ES1370_REG_DAC2_FRAMEADR
& 0xff, (uint32
)stream
->buffer
->phy_base
);
162 es1370_reg_write_32(&card
->config
, ES1370_REG_DAC2_FRAMECNT
& 0xff, ((stream
->blksize
* stream
->bufcount
) >> 2) - 1);
163 es1370_reg_write_32(&card
->config
, ES1370_REG_DAC2_SCOUNT
& 0xff, stream
->bufframes
- 1);
164 LOG(("es1370_stream_commit_parms %ld %ld\n", ((stream
->blksize
* stream
->bufcount
) >> 2) - 1, (stream
->blksize
/ frame_size
) - 1));
171 es1370_stream_get_nth_buffer(es1370_stream
*stream
, uint8 chan
, uint8 buf
,
172 char** buffer
, size_t *stride
)
174 uint8 sample_size
, frame_size
;
175 LOG(("es1370_stream_get_nth_buffer\n"));
177 sample_size
= stream
->b16
+ 1;
178 frame_size
= sample_size
* stream
->channels
;
180 *buffer
= stream
->buffer
->log_base
+ (buf
* stream
->bufframes
* frame_size
)
181 + chan
* sample_size
;
182 *stride
= frame_size
;
188 es1370_stream_curaddr(es1370_stream
*stream
)
190 es1370_dev
*card
= stream
->card
;
191 uint32 reg
= 0, cnt
= 0;
192 if (stream
->use
& ES1370_USE_RECORD
) {
193 reg
= ES1370_REG_ADC_FRAMECNT
;
195 reg
= ES1370_REG_DAC2_FRAMECNT
;
197 es1370_reg_write_32(&card
->config
, ES1370_REG_MEMPAGE
, reg
>> 8);
198 cnt
= es1370_reg_read_32(&card
->config
, reg
& 0xff) >> 16;
199 //TRACE(("stream_curaddr %lx\n", (cnt << 2) / stream->blksize));
200 return (cnt
<< 2) / stream
->blksize
;
204 es1370_stream_start(es1370_stream
*stream
, void (*inth
) (void *), void *inthparam
)
206 uint32 sctrl
= 0, ctrl
= 0;
207 es1370_dev
*card
= stream
->card
;
208 LOG(("es1370_stream_start\n"));
211 stream
->inthparam
= inthparam
;
213 stream
->state
|= ES1370_STATE_STARTED
;
215 sctrl
= es1370_reg_read_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
);
216 ctrl
= es1370_reg_read_32(&card
->config
, ES1370_REG_CONTROL
);
218 if (stream
->use
& ES1370_USE_RECORD
) {
219 sctrl
&= ~(SCTRL_R1SEB
| SCTRL_R1SMB
);
221 sctrl
|= SCTRL_R1SEB
;
222 if (stream
->channels
== 2)
223 sctrl
|= SCTRL_R1SMB
;
224 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
& ~SCTRL_R1INTEN
);
225 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
| SCTRL_R1INTEN
);
229 sctrl
&= ~(SCTRL_P2SEB
| SCTRL_P2SMB
| 0x003f0000);
231 sctrl
|= SCTRL_P2SEB
;
232 if (stream
->channels
== 2)
233 sctrl
|= SCTRL_P2SMB
;
234 sctrl
|= (stream
->b16
+ 1) << SCTRL_SH_P2ENDINC
;
235 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
& ~SCTRL_P2INTEN
);
236 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
| SCTRL_P2INTEN
);
238 ctrl
|= CTRL_DAC2_EN
;
241 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
);
242 es1370_reg_write_32(&card
->config
, ES1370_REG_CONTROL
, ctrl
);
245 //dump_hardware_regs(&stream->card->config);
250 es1370_stream_halt(es1370_stream
*stream
)
253 es1370_dev
*card
= stream
->card
;
254 LOG(("es1370_stream_halt\n"));
256 stream
->state
&= ~ES1370_STATE_STARTED
;
258 ctrl
= es1370_reg_read_32(&card
->config
, ES1370_REG_CONTROL
);
259 if (stream
->use
& ES1370_USE_RECORD
)
260 ctrl
&= ~CTRL_ADC_EN
;
262 ctrl
&= ~CTRL_DAC2_EN
;
263 es1370_reg_write_32(&card
->config
, ES1370_REG_CONTROL
, ctrl
);
267 es1370_stream_new(es1370_dev
*card
, uint8 use
, uint32 bufframes
, uint8 bufcount
)
269 es1370_stream
*stream
;
271 LOG(("es1370_stream_new\n"));
273 stream
= malloc(sizeof(es1370_stream
));
278 stream
->state
= !ES1370_STATE_STARTED
;
280 stream
->sample_rate
= 0;
281 stream
->channels
= 0;
282 stream
->bufframes
= bufframes
;
283 stream
->bufcount
= bufcount
;
285 stream
->inthparam
= NULL
;
286 stream
->buffer
= NULL
;
291 stream
->buffer_cycle
= 0;
292 stream
->frames_count
= 0;
293 stream
->real_time
= 0;
294 stream
->update_needed
= false;
297 LIST_INSERT_HEAD((&card
->streams
), stream
, next
);
304 es1370_stream_delete(es1370_stream
*stream
)
307 LOG(("es1370_stream_delete\n"));
309 es1370_stream_halt(stream
);
312 es1370_mem_free(stream
->card
, stream
->buffer
->log_base
);
315 LIST_REMOVE(stream
, next
);
321 /* es1370 interrupt */
324 es1370_int(void *arg
)
326 es1370_dev
*card
= arg
;
329 es1370_stream
*stream
= NULL
;
332 // TRACE(("es1370_int(%p)\n", card));
334 sta
= es1370_reg_read_32(&card
->config
, ES1370_REG_STATUS
);
335 if (sta
& card
->interrupt_mask
) {
337 //TRACE(("interrupt !! %x\n", sta));
338 sctrl
= es1370_reg_read_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
);
340 LIST_FOREACH(stream
, &card
->streams
, next
) {
341 if (stream
->use
& ES1370_USE_RECORD
) {
342 if ((sta
& STAT_ADC
) == 0)
344 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
& ~SCTRL_R1INTEN
);
345 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
| SCTRL_R1INTEN
);
347 if ((sta
& STAT_DAC2
) == 0)
349 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
& ~SCTRL_P2INTEN
);
350 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, sctrl
| SCTRL_P2INTEN
);
353 curblk
= es1370_stream_curaddr(stream
);
354 // TRACE(("INTR at trigblk %lu, stream->trigblk %lu\n", curblk, stream->trigblk));
355 if (curblk
== stream
->trigblk
) {
357 stream
->trigblk
= stream
->trigblk
% stream
->blkmod
;
359 stream
->inth(stream
->inthparam
);
364 //TRACE(("interrupt masked %x, ", card->interrupt_mask));
365 //TRACE(("sta %x\n", sta));
369 return B_INVOKE_SCHEDULER
;
371 //TRACE(("Got unhandled interrupt\n"));
372 return B_UNHANDLED_INTERRUPT
;
376 /* es1370 driver functions */
379 /* detect presence of our hardware */
385 status_t err
= ENODEV
;
389 PRINT(("init_hardware()\n"));
391 if (get_module(pci_name
, (module_info
**)&pci
))
394 while ((*pci
->get_nth_pci_info
)(ix
, &info
) == B_OK
) {
395 if (info
.vendor_id
== 0x1274
396 && (info
.device_id
== 0x5000
397 /*|| info.device_id == 0x1371
398 || info.device_id == 0x5880*/)
406 put_module(pci_name
);
415 sprintf(card
->name
, "audio/hmulti/es1370/%ld", card
-cards
+1);
416 names
[num_names
++] = card
->name
;
418 names
[num_names
] = NULL
;
423 es1370_init(es1370_dev
* card
)
425 card
->interrupt_mask
= STAT_DAC2
| STAT_ADC
;
427 /* Init streams list */
428 LIST_INIT(&(card
->streams
));
431 LIST_INIT(&(card
->mems
));
437 es1370_setup(es1370_dev
* card
)
442 PRINT(("es1370_setup(%p)\n", card
));
444 make_device_names(card
);
446 card
->config
.base
= card
->info
.u
.h0
.base_registers
[0];
447 card
->config
.irq
= card
->info
.u
.h0
.interrupt_line
;
448 card
->config
.type
= 0;
450 PRINT(("%s deviceid = %#04x chiprev = %x model = %x enhanced at %lx\n", card
->name
, card
->info
.device_id
,
451 card
->info
.revision
, card
->info
.u
.h0
.subsystem_id
, card
->config
.base
));
453 cmd
= (*pci
->read_pci_config
)(card
->info
.bus
, card
->info
.device
, card
->info
.function
, PCI_command
, 2);
454 PRINT(("PCI command before: %x\n", cmd
));
455 (*pci
->write_pci_config
)(card
->info
.bus
, card
->info
.device
, card
->info
.function
, PCI_command
, 2, cmd
| PCI_command_io
);
456 cmd
= (*pci
->read_pci_config
)(card
->info
.bus
, card
->info
.device
, card
->info
.function
, PCI_command
, 2);
457 PRINT(("PCI command after: %x\n", cmd
));
459 es1370_reg_write_32(&card
->config
, ES1370_REG_SERIAL_CONTROL
, SCTRL_P2INTEN
| SCTRL_R1INTEN
);
460 es1370_reg_write_32(&card
->config
, ES1370_REG_CONTROL
, CTRL_CDC_EN
);
462 /* reset the codec */
463 PRINT(("codec reset\n"));
464 es1370_codec_write(&card
->config
, CODEC_RESET_PWRDWN
, 0x2);
466 es1370_codec_write(&card
->config
, CODEC_RESET_PWRDWN
, 0x3);
468 es1370_codec_write(&card
->config
, CODEC_CLOCK_SEL
, 0x0);
470 /* set max volume on master and mixer outputs */
471 es1370_codec_write(&card
->config
, CODEC_MASTER_VOL_L
, 0x0);
472 es1370_codec_write(&card
->config
, CODEC_MASTER_VOL_R
, 0x0);
473 es1370_codec_write(&card
->config
, CODEC_VOICE_VOL_L
, 0x0);
474 es1370_codec_write(&card
->config
, CODEC_VOICE_VOL_R
, 0x0);
476 /* unmute CD playback */
477 es1370_codec_write(&card
->config
, CODEC_OUTPUT_MIX1
, ES1370_OUTPUT_MIX1_CDL
| ES1370_OUTPUT_MIX1_CDR
);
478 /* unmute mixer output */
479 es1370_codec_write(&card
->config
, CODEC_OUTPUT_MIX2
, ES1370_OUTPUT_MIX2_VOICEL
| ES1370_OUTPUT_MIX2_VOICER
);
481 snooze(50000); // 50 ms
483 PRINT(("installing interrupt : %lx\n", card
->config
.irq
));
484 err
= install_io_interrupt_handler(card
->config
.irq
, es1370_int
, card
, 0);
486 PRINT(("failed to install interrupt\n"));
490 if ((err
= es1370_init(card
)))
493 PRINT(("init_driver done\n"));
502 void *settings_handle
;
508 PRINT(("init_driver()\n"));
510 // get driver settings
511 settings_handle
= load_driver_settings ("es1370.settings");
512 if (settings_handle
!= NULL
) {
517 item
= get_driver_parameter (settings_handle
, "sample_rate", "44100", "44100");
518 value
= strtoul (item
, &end
, 0);
519 if (*end
== '\0') current_settings
.sample_rate
= value
;
521 item
= get_driver_parameter (settings_handle
, "buffer_frames", "512", "512");
522 value
= strtoul (item
, &end
, 0);
523 if (*end
== '\0') current_settings
.buffer_frames
= value
;
525 item
= get_driver_parameter (settings_handle
, "buffer_count", "2", "2");
526 value
= strtoul (item
, &end
, 0);
527 if (*end
== '\0') current_settings
.buffer_count
= value
;
529 unload_driver_settings (settings_handle
);
532 if (get_module(pci_name
, (module_info
**) &pci
))
535 while ((*pci
->get_nth_pci_info
)(ix
++, &info
) == B_OK
) {
536 if (info
.vendor_id
== 0x1274
537 && (info
.device_id
== 0x5000
538 /*|| info.device_id == 0x1371
539 || info.device_id == 0x5880*/)
541 if (num_cards
== NUM_CARDS
) {
542 PRINT(("Too many es1370 cards installed!\n"));
545 memset(&cards
[num_cards
], 0, sizeof(es1370_dev
));
546 cards
[num_cards
].info
= info
;
548 if ((err
= (*pci
->reserve_device
)(info
.bus
, info
.device
, info
.function
,
549 DRIVER_NAME
, &cards
[num_cards
])) < B_OK
) {
550 dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n",
551 DRIVER_NAME
, info
.bus
, info
.device
, info
.function
,
556 if (es1370_setup(&cards
[num_cards
])) {
557 PRINT(("Setup of es1370 %ld failed\n", num_cards
+1));
559 (*pci
->unreserve_device
)(info
.bus
, info
.device
, info
.function
,
560 DRIVER_NAME
, &cards
[num_cards
]);
569 PRINT(("no cards\n"));
570 put_module(pci_name
);
571 PRINT(("no suitable cards found\n"));
580 es1370_shutdown(es1370_dev
*card
)
582 PRINT(("shutdown(%p)\n", card
));
583 //ac97_amp_enable(&card->config, false);
584 card
->interrupt_mask
= 0;
586 remove_io_interrupt_handler(card
->config
.irq
, es1370_int
, card
);
593 int ix
, cnt
= num_cards
;
596 PRINT(("uninit_driver()\n"));
597 for (ix
=0; ix
<cnt
; ix
++) {
598 es1370_shutdown(&cards
[ix
]);
600 (*pci
->unreserve_device
)(cards
[ix
].info
.bus
,
601 cards
[ix
].info
.device
, cards
[ix
].info
.function
,
602 DRIVER_NAME
, &cards
[ix
]);
605 memset(&cards
, 0, sizeof(cards
));
606 put_module(pci_name
);
611 publish_devices(void)
614 PRINT(("publish_devices()\n"));
616 for (ix
=0; names
[ix
]; ix
++) {
617 PRINT(("publish %s\n", names
[ix
]));
619 return (const char **)names
;
624 find_device(const char * name
)
628 PRINT(("find_device(%s)\n", name
));
630 for (ix
=0; ix
<num_cards
; ix
++) {
631 if (!strcmp(cards
[ix
].name
, name
)) {
635 PRINT(("find_device(%s) failed\n", name
));
639 int32 api_version
= B_CUR_DRIVER_API_VERSION
;