Home | History | Annotate | Line # | Download | only in mini2440
audio_mini2440.c revision 1.1.4.2
      1  1.1.4.2  yamt /*-
      2  1.1.4.2  yamt  * Copyright (c) 2012 The NetBSD Foundation, Inc.
      3  1.1.4.2  yamt  * All rights reserved.
      4  1.1.4.2  yamt  *
      5  1.1.4.2  yamt  * This code is derived from software contributed to The NetBSD Foundation
      6  1.1.4.2  yamt  * by Paul Fleischer <paul (at) xpg.dk>
      7  1.1.4.2  yamt  *
      8  1.1.4.2  yamt  * Redistribution and use in source and binary forms, with or without
      9  1.1.4.2  yamt  * modification, are permitted provided that the following conditions
     10  1.1.4.2  yamt  * are met:
     11  1.1.4.2  yamt  * 1. Redistributions of source code must retain the above copyright
     12  1.1.4.2  yamt  *    notice, this list of conditions and the following disclaimer.
     13  1.1.4.2  yamt  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1.4.2  yamt  *    notice, this list of conditions and the following disclaimer in the
     15  1.1.4.2  yamt  *    documentation and/or other materials provided with the distribution.
     16  1.1.4.2  yamt  *
     17  1.1.4.2  yamt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  1.1.4.2  yamt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  1.1.4.2  yamt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  1.1.4.2  yamt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  1.1.4.2  yamt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  1.1.4.2  yamt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  1.1.4.2  yamt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  1.1.4.2  yamt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  1.1.4.2  yamt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  1.1.4.2  yamt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  1.1.4.2  yamt  * POSSIBILITY OF SUCH DAMAGE.
     28  1.1.4.2  yamt  */
     29  1.1.4.2  yamt 
     30  1.1.4.2  yamt #include <sys/cdefs.h>
     31  1.1.4.2  yamt #include <sys/param.h>
     32  1.1.4.2  yamt #include <sys/device.h>
     33  1.1.4.2  yamt #include <sys/malloc.h>
     34  1.1.4.2  yamt #include <sys/fcntl.h>
     35  1.1.4.2  yamt #include <sys/audioio.h>
     36  1.1.4.2  yamt 
     37  1.1.4.2  yamt #include <sys/bus.h>
     38  1.1.4.2  yamt 
     39  1.1.4.2  yamt #include <dev/audio_if.h>
     40  1.1.4.2  yamt 
     41  1.1.4.2  yamt 
     42  1.1.4.2  yamt #include <dev/ic/uda1341var.h>
     43  1.1.4.2  yamt 
     44  1.1.4.2  yamt #include <arch/arm/s3c2xx0/s3c2440reg.h>
     45  1.1.4.2  yamt #include <arch/arm/s3c2xx0/s3c2440var.h>
     46  1.1.4.2  yamt 
     47  1.1.4.2  yamt #include <arch/arm/s3c2xx0/s3c2440_dma.h>
     48  1.1.4.2  yamt #include <arch/arm/s3c2xx0/s3c2440_i2s.h>
     49  1.1.4.2  yamt 
     50  1.1.4.2  yamt /*#define AUDIO_MINI2440_DEBUG*/
     51  1.1.4.2  yamt 
     52  1.1.4.2  yamt #ifdef AUDIO_MINI2440_DEBUG
     53  1.1.4.2  yamt #define DPRINTF(x) do {printf x; } while (/*CONSTCOND*/0)
     54  1.1.4.2  yamt #else
     55  1.1.4.2  yamt #define DPRINTF(s) do {} while (/*CONSTCOND*/0)
     56  1.1.4.2  yamt #endif
     57  1.1.4.2  yamt 
     58  1.1.4.2  yamt struct uda_softc {
     59  1.1.4.2  yamt 	device_t		sc_dev;
     60  1.1.4.2  yamt 	kmutex_t		sc_lock;
     61  1.1.4.2  yamt 	kmutex_t		sc_intr_lock;
     62  1.1.4.2  yamt 
     63  1.1.4.2  yamt 	struct uda1341_softc	sc_uda1341;
     64  1.1.4.2  yamt 
     65  1.1.4.2  yamt 	s3c2440_i2s_buf_t	sc_play_buf;
     66  1.1.4.2  yamt 	s3c2440_i2s_buf_t	sc_rec_buf;
     67  1.1.4.2  yamt 
     68  1.1.4.2  yamt 	void			*sc_i2s_handle;
     69  1.1.4.2  yamt 
     70  1.1.4.2  yamt 	bool			sc_open;
     71  1.1.4.2  yamt };
     72  1.1.4.2  yamt 
     73  1.1.4.2  yamt int	uda_ssio_open(void *, int);
     74  1.1.4.2  yamt void	uda_ssio_close(void *);
     75  1.1.4.2  yamt int	uda_ssio_set_params(void *, int, int, audio_params_t *, audio_params_t *,
     76  1.1.4.2  yamt 		       stream_filter_list_t *, stream_filter_list_t *);
     77  1.1.4.2  yamt int	uda_ssio_round_blocksize(void *, int, int, const audio_params_t *);
     78  1.1.4.2  yamt int	uda_ssio_start_output(void *, void *, int, void (*)(void *),
     79  1.1.4.2  yamt 			      void *);
     80  1.1.4.2  yamt int	uda_ssio_start_input(void *, void *, int, void (*)(void *),
     81  1.1.4.2  yamt 			      void *);
     82  1.1.4.2  yamt int	uda_ssio_halt_output(void *);
     83  1.1.4.2  yamt int	uda_ssio_halt_input(void *);
     84  1.1.4.2  yamt int	uda_ssio_getdev(void *, struct audio_device *ret);
     85  1.1.4.2  yamt void*	uda_ssio_allocm(void *, int, size_t);
     86  1.1.4.2  yamt void	uda_ssio_freem(void *, void *, size_t);
     87  1.1.4.2  yamt size_t	uda_ssio_round_buffersize(void *, int, size_t);
     88  1.1.4.2  yamt int	uda_ssio_getprops(void *);
     89  1.1.4.2  yamt void	uda_ssio_get_locks(void *, kmutex_t**, kmutex_t**);
     90  1.1.4.2  yamt 
     91  1.1.4.2  yamt struct audio_hw_if uda1341_hw_if = {
     92  1.1.4.2  yamt 	uda_ssio_open,
     93  1.1.4.2  yamt 	uda_ssio_close,
     94  1.1.4.2  yamt 	NULL,
     95  1.1.4.2  yamt 	uda1341_query_encodings,
     96  1.1.4.2  yamt 	uda_ssio_set_params,
     97  1.1.4.2  yamt 	uda_ssio_round_blocksize,
     98  1.1.4.2  yamt 	NULL,				/* commit_settings*/
     99  1.1.4.2  yamt 	NULL,
    100  1.1.4.2  yamt 	NULL,
    101  1.1.4.2  yamt 	uda_ssio_start_output,
    102  1.1.4.2  yamt 	uda_ssio_start_input,
    103  1.1.4.2  yamt 	uda_ssio_halt_output,
    104  1.1.4.2  yamt 	uda_ssio_halt_input,
    105  1.1.4.2  yamt 	NULL,
    106  1.1.4.2  yamt 	uda_ssio_getdev,
    107  1.1.4.2  yamt 	NULL,
    108  1.1.4.2  yamt 	uda1341_set_port,
    109  1.1.4.2  yamt 	uda1341_get_port,
    110  1.1.4.2  yamt 	uda1341_query_devinfo,
    111  1.1.4.2  yamt 	uda_ssio_allocm,
    112  1.1.4.2  yamt 	uda_ssio_freem,
    113  1.1.4.2  yamt 	uda_ssio_round_buffersize,
    114  1.1.4.2  yamt 	NULL,				/* mappage */
    115  1.1.4.2  yamt 	uda_ssio_getprops,
    116  1.1.4.2  yamt 	NULL,
    117  1.1.4.2  yamt 	NULL,
    118  1.1.4.2  yamt 	NULL,
    119  1.1.4.2  yamt 	uda_ssio_get_locks
    120  1.1.4.2  yamt };
    121  1.1.4.2  yamt 
    122  1.1.4.2  yamt static struct audio_device uda1341_device = {
    123  1.1.4.2  yamt 	"MINI2240-UDA1341",
    124  1.1.4.2  yamt 	"0.1",
    125  1.1.4.2  yamt 	"uda_ssio"
    126  1.1.4.2  yamt };
    127  1.1.4.2  yamt 
    128  1.1.4.2  yamt void uda_ssio_l3_write(void *,int mode, int value);
    129  1.1.4.2  yamt 
    130  1.1.4.2  yamt int uda_ssio_match(device_t, cfdata_t, void*);
    131  1.1.4.2  yamt void uda_ssio_attach(device_t, device_t, void*);
    132  1.1.4.2  yamt 
    133  1.1.4.2  yamt CFATTACH_DECL_NEW(udassio, sizeof(struct uda_softc),
    134  1.1.4.2  yamt 	      uda_ssio_match, uda_ssio_attach, NULL, NULL);
    135  1.1.4.2  yamt 
    136  1.1.4.2  yamt int
    137  1.1.4.2  yamt uda_ssio_match(device_t parent, cfdata_t match, void *aux)
    138  1.1.4.2  yamt {
    139  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    140  1.1.4.2  yamt 	/* Not quite sure how we can detect the UDA1341 chip */
    141  1.1.4.2  yamt 	return 1;
    142  1.1.4.2  yamt }
    143  1.1.4.2  yamt 
    144  1.1.4.2  yamt void
    145  1.1.4.2  yamt uda_ssio_attach(device_t parent, device_t self, void *aux)
    146  1.1.4.2  yamt {
    147  1.1.4.2  yamt 	/*	struct s3c2xx0_attach_args *sa = aux;*/
    148  1.1.4.2  yamt 	struct uda_softc *sc = device_private(self);
    149  1.1.4.2  yamt 	struct s3c2xx0_softc *s3sc = s3c2xx0_softc; /* Shortcut */
    150  1.1.4.2  yamt 	struct s3c2440_i2s_attach_args *aa = aux;
    151  1.1.4.2  yamt 	uint32_t reg;
    152  1.1.4.2  yamt 
    153  1.1.4.2  yamt 	sc->sc_dev = self;
    154  1.1.4.2  yamt 
    155  1.1.4.2  yamt 	sc->sc_play_buf = NULL;
    156  1.1.4.2  yamt 	sc->sc_i2s_handle = aa->i2sa_handle;
    157  1.1.4.2  yamt 	sc->sc_open = false;
    158  1.1.4.2  yamt 
    159  1.1.4.2  yamt 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    160  1.1.4.2  yamt 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
    161  1.1.4.2  yamt 
    162  1.1.4.2  yamt 	s3c2440_i2s_set_intr_lock(aa->i2sa_handle, &sc->sc_intr_lock);
    163  1.1.4.2  yamt 
    164  1.1.4.2  yamt 	/* arch/arm/s3c2xx0/s3c2440.c initializes the I2S subsystem for us */
    165  1.1.4.2  yamt 
    166  1.1.4.2  yamt 	/* Setup GPIO pins to output for L3 communication.
    167  1.1.4.2  yamt 	   GPB3 (L3DATA) will have to be switched to input when reading
    168  1.1.4.2  yamt 	   from the L3 bus.
    169  1.1.4.2  yamt 
    170  1.1.4.2  yamt 	   GPB2 - L3MODE
    171  1.1.4.2  yamt 	   GPB3 - L3DATA
    172  1.1.4.2  yamt 	   GPB4 - L3CLOCK
    173  1.1.4.2  yamt 	   TODO: Make this configurable
    174  1.1.4.2  yamt 	*/
    175  1.1.4.2  yamt 	reg = bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBCON);
    176  1.1.4.2  yamt 	reg = GPIO_SET_FUNC(reg, 2, 1);
    177  1.1.4.2  yamt 	reg = GPIO_SET_FUNC(reg, 3, 1);
    178  1.1.4.2  yamt 	reg = GPIO_SET_FUNC(reg, 4, 1);
    179  1.1.4.2  yamt 	bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBCON, reg);
    180  1.1.4.2  yamt 
    181  1.1.4.2  yamt 	reg = bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT);
    182  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, 4, 1);
    183  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, 3, 0);
    184  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, 2, 1);
    185  1.1.4.2  yamt 	bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT, reg);
    186  1.1.4.2  yamt 
    187  1.1.4.2  yamt 	printf("\n");
    188  1.1.4.2  yamt 
    189  1.1.4.2  yamt 	/* uda1341_attach resets the uda1341 sc, so it has to be called before
    190  1.1.4.2  yamt 	   attributes are set on the sc.*/
    191  1.1.4.2  yamt 	uda1341_attach(&sc->sc_uda1341);
    192  1.1.4.2  yamt 
    193  1.1.4.2  yamt 	/* Configure the UDA1341 Codec */
    194  1.1.4.2  yamt 	sc->sc_uda1341.parent = sc;
    195  1.1.4.2  yamt 	sc->sc_uda1341.sc_l3_write = uda_ssio_l3_write;
    196  1.1.4.2  yamt 	sc->sc_uda1341.sc_bus_format = UDA1341_BUS_MSB;
    197  1.1.4.2  yamt 
    198  1.1.4.2  yamt 	/* Configure I2S controller */
    199  1.1.4.2  yamt 	s3c2440_i2s_set_bus_format(sc->sc_i2s_handle, S3C2440_I2S_BUS_MSB);
    200  1.1.4.2  yamt 	// Attach
    201  1.1.4.2  yamt 	audio_attach_mi(&uda1341_hw_if, &sc->sc_uda1341, self);
    202  1.1.4.2  yamt }
    203  1.1.4.2  yamt 
    204  1.1.4.2  yamt int
    205  1.1.4.2  yamt uda_ssio_open(void *handle, int flags)
    206  1.1.4.2  yamt {
    207  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    208  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    209  1.1.4.2  yamt 	int retval;
    210  1.1.4.2  yamt 
    211  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    212  1.1.4.2  yamt 
    213  1.1.4.2  yamt 	if (sc->sc_open)
    214  1.1.4.2  yamt 		return EBUSY;
    215  1.1.4.2  yamt 
    216  1.1.4.2  yamt 	/* We only support write operations */
    217  1.1.4.2  yamt 	if (!(flags & FREAD) && !(flags & FWRITE))
    218  1.1.4.2  yamt 		return EINVAL;
    219  1.1.4.2  yamt 
    220  1.1.4.2  yamt 	/* We can't do much more at this point than to
    221  1.1.4.2  yamt 	   ask the UDA1341 codec to initialize itself
    222  1.1.4.2  yamt 	   (for an unknown system clock)
    223  1.1.4.2  yamt 	*/
    224  1.1.4.2  yamt 	retval = uda1341_open(handle, flags);
    225  1.1.4.2  yamt 	if (retval != 0) {
    226  1.1.4.2  yamt 		return retval;
    227  1.1.4.2  yamt 	}
    228  1.1.4.2  yamt 
    229  1.1.4.2  yamt 	sc->sc_open = true;
    230  1.1.4.2  yamt 
    231  1.1.4.2  yamt 	return 0; /* SUCCESS */
    232  1.1.4.2  yamt }
    233  1.1.4.2  yamt 
    234  1.1.4.2  yamt void
    235  1.1.4.2  yamt uda_ssio_close(void *handle)
    236  1.1.4.2  yamt {
    237  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    238  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    239  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    240  1.1.4.2  yamt 
    241  1.1.4.2  yamt 	uda1341_close(handle);
    242  1.1.4.2  yamt 	sc->sc_open = false;
    243  1.1.4.2  yamt }
    244  1.1.4.2  yamt 
    245  1.1.4.2  yamt int
    246  1.1.4.2  yamt uda_ssio_set_params(void *handle, int setmode, int usemode,
    247  1.1.4.2  yamt 		    audio_params_t *play, audio_params_t *rec,
    248  1.1.4.2  yamt 		    stream_filter_list_t *pfil, stream_filter_list_t *rfil)
    249  1.1.4.2  yamt {
    250  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    251  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    252  1.1.4.2  yamt 	const struct audio_format *selected_format;
    253  1.1.4.2  yamt 	audio_params_t *params;
    254  1.1.4.2  yamt 	stream_filter_list_t *fil;
    255  1.1.4.2  yamt 	int retval;
    256  1.1.4.2  yamt 
    257  1.1.4.2  yamt 	DPRINTF(("%s: setmode: %d\n", __func__, setmode));
    258  1.1.4.2  yamt 	DPRINTF(("%s: usemode: %d\n", __func__, usemode));
    259  1.1.4.2  yamt 
    260  1.1.4.2  yamt 	if (setmode == 0)
    261  1.1.4.2  yamt 		setmode = usemode;
    262  1.1.4.2  yamt 
    263  1.1.4.2  yamt 	if (setmode & AUMODE_PLAY) {
    264  1.1.4.2  yamt 		params = play;
    265  1.1.4.2  yamt 		fil = pfil;
    266  1.1.4.2  yamt 	} else if (setmode == AUMODE_RECORD) {
    267  1.1.4.2  yamt 		params = rec;
    268  1.1.4.2  yamt 		fil = rfil;
    269  1.1.4.2  yamt 	} else {
    270  1.1.4.2  yamt 		return EINVAL;
    271  1.1.4.2  yamt 	}
    272  1.1.4.2  yamt 
    273  1.1.4.2  yamt 	DPRINTF(("%s: %dHz, encoding: %d, precision: %d, channels: %d\n",
    274  1.1.4.2  yamt 		 __func__, params->sample_rate, params->encoding, play->precision,
    275  1.1.4.2  yamt 		 params->channels));
    276  1.1.4.2  yamt 
    277  1.1.4.2  yamt 	if (params->sample_rate != 8000 &&
    278  1.1.4.2  yamt 	    params->sample_rate != 11025 &&
    279  1.1.4.2  yamt 	    params->sample_rate != 22050 &&
    280  1.1.4.2  yamt 	    params->sample_rate != 32000 &&
    281  1.1.4.2  yamt 	    params->sample_rate != 44100 &&
    282  1.1.4.2  yamt 	    params->sample_rate != 48000) {
    283  1.1.4.2  yamt 		return EINVAL;
    284  1.1.4.2  yamt 	}
    285  1.1.4.2  yamt 
    286  1.1.4.2  yamt 	retval = auconv_set_converter(uda1341_formats, UDA1341_NFORMATS,
    287  1.1.4.2  yamt 				    setmode, params, true, fil);
    288  1.1.4.2  yamt 	if (retval < 0) {
    289  1.1.4.2  yamt 		printf("Could not find valid format\n");
    290  1.1.4.2  yamt 		return EINVAL;
    291  1.1.4.2  yamt 	}
    292  1.1.4.2  yamt 
    293  1.1.4.2  yamt 	selected_format = &uda1341_formats[retval];
    294  1.1.4.2  yamt 
    295  1.1.4.2  yamt 	if (setmode == AUMODE_PLAY) {
    296  1.1.4.2  yamt 		s3c2440_i2s_set_direction(sc->sc_i2s_handle,
    297  1.1.4.2  yamt 					  S3C2440_I2S_TRANSMIT);
    298  1.1.4.2  yamt 	} else {
    299  1.1.4.2  yamt 		s3c2440_i2s_set_direction(sc->sc_i2s_handle,
    300  1.1.4.2  yamt 					  S3C2440_I2S_RECEIVE);
    301  1.1.4.2  yamt 	}
    302  1.1.4.2  yamt 
    303  1.1.4.2  yamt 	s3c2440_i2s_set_sample_rate(sc->sc_i2s_handle, params->sample_rate);
    304  1.1.4.2  yamt 	s3c2440_i2s_set_sample_width(sc->sc_i2s_handle,
    305  1.1.4.2  yamt 				     selected_format->precision);
    306  1.1.4.2  yamt 
    307  1.1.4.2  yamt 	/* It is vital that sc_system_clock is set PRIOR to calling
    308  1.1.4.2  yamt 	   uda1341_set_params. */
    309  1.1.4.2  yamt 	switch (s3c2440_i2s_get_master_clock(sc->sc_i2s_handle)) {
    310  1.1.4.2  yamt 	case 384:
    311  1.1.4.2  yamt 		uc->sc_system_clock = UDA1341_CLOCK_384;
    312  1.1.4.2  yamt 		break;
    313  1.1.4.2  yamt 	case 256:
    314  1.1.4.2  yamt 		uc->sc_system_clock = UDA1341_CLOCK_256;
    315  1.1.4.2  yamt 		break;
    316  1.1.4.2  yamt 	default:
    317  1.1.4.2  yamt 		return EINVAL;
    318  1.1.4.2  yamt 	}
    319  1.1.4.2  yamt 
    320  1.1.4.2  yamt 	retval = uda1341_set_params(handle, setmode, usemode,
    321  1.1.4.2  yamt 				    play, rec, pfil, rfil);
    322  1.1.4.2  yamt 	if (retval != 0) {
    323  1.1.4.2  yamt 		return retval;
    324  1.1.4.2  yamt 	}
    325  1.1.4.2  yamt 
    326  1.1.4.2  yamt 	/* Setup and enable I2S controller */
    327  1.1.4.2  yamt 	retval = s3c2440_i2s_commit(sc->sc_i2s_handle);
    328  1.1.4.2  yamt 	if (retval != 0) {
    329  1.1.4.2  yamt 		printf("Failed to setup I2S controller\n");
    330  1.1.4.2  yamt 		return retval;
    331  1.1.4.2  yamt 	}
    332  1.1.4.2  yamt 
    333  1.1.4.2  yamt 	return 0;
    334  1.1.4.2  yamt }
    335  1.1.4.2  yamt 
    336  1.1.4.2  yamt int
    337  1.1.4.2  yamt uda_ssio_round_blocksize(void *handle, int bs, int mode,
    338  1.1.4.2  yamt 			 const audio_params_t *param)
    339  1.1.4.2  yamt {
    340  1.1.4.2  yamt 	int out_bs;
    341  1.1.4.2  yamt 	DPRINTF(("%s: %d\n", __func__, bs));
    342  1.1.4.2  yamt 
    343  1.1.4.2  yamt 	out_bs =  (bs + 0x03) & ~0x03;
    344  1.1.4.2  yamt 	DPRINTF(("%s: out_bs: %d\n", __func__, out_bs));
    345  1.1.4.2  yamt 	return out_bs;
    346  1.1.4.2  yamt }
    347  1.1.4.2  yamt 
    348  1.1.4.2  yamt int
    349  1.1.4.2  yamt uda_ssio_start_output(void *handle, void *block, int bsize,
    350  1.1.4.2  yamt 		      void (*intr)(void *), void *intrarg)
    351  1.1.4.2  yamt {
    352  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    353  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    354  1.1.4.2  yamt 
    355  1.1.4.2  yamt 	return s3c2440_i2s_output(sc->sc_play_buf, block, bsize, intr, intrarg);
    356  1.1.4.2  yamt }
    357  1.1.4.2  yamt 
    358  1.1.4.2  yamt int
    359  1.1.4.2  yamt uda_ssio_start_input(void *handle, void *block, int bsize,
    360  1.1.4.2  yamt 		     void (*intr)(void *), void *intrarg)
    361  1.1.4.2  yamt {
    362  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    363  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    364  1.1.4.2  yamt 
    365  1.1.4.2  yamt 	return s3c2440_i2s_input(sc->sc_rec_buf, block, bsize, intr, intrarg);
    366  1.1.4.2  yamt }
    367  1.1.4.2  yamt 
    368  1.1.4.2  yamt int
    369  1.1.4.2  yamt uda_ssio_halt_output(void *handle)
    370  1.1.4.2  yamt {
    371  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    372  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    373  1.1.4.2  yamt 
    374  1.1.4.2  yamt 	return s3c2440_i2s_halt_output(sc->sc_play_buf);
    375  1.1.4.2  yamt }
    376  1.1.4.2  yamt 
    377  1.1.4.2  yamt int
    378  1.1.4.2  yamt uda_ssio_halt_input(void *handle)
    379  1.1.4.2  yamt {
    380  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    381  1.1.4.2  yamt 	return 0;
    382  1.1.4.2  yamt }
    383  1.1.4.2  yamt 
    384  1.1.4.2  yamt int
    385  1.1.4.2  yamt uda_ssio_getdev(void *handle, struct audio_device *ret)
    386  1.1.4.2  yamt {
    387  1.1.4.2  yamt 	*ret = uda1341_device;
    388  1.1.4.2  yamt 	return 0;
    389  1.1.4.2  yamt }
    390  1.1.4.2  yamt 
    391  1.1.4.2  yamt void *
    392  1.1.4.2  yamt uda_ssio_allocm(void *handle, int direction, size_t size)
    393  1.1.4.2  yamt {
    394  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    395  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    396  1.1.4.2  yamt 	void *retval = NULL;
    397  1.1.4.2  yamt 
    398  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    399  1.1.4.2  yamt 
    400  1.1.4.2  yamt 	if (direction == AUMODE_PLAY ) {
    401  1.1.4.2  yamt 		if (sc->sc_play_buf != NULL)
    402  1.1.4.2  yamt 			return NULL;
    403  1.1.4.2  yamt 
    404  1.1.4.2  yamt 		s3c2440_i2s_alloc(sc->sc_i2s_handle, direction, size, 0x00, &sc->sc_play_buf);
    405  1.1.4.2  yamt 		DPRINTF(("%s: addr of ring buffer: %p\n", __func__, sc->sc_play_buf->i2b_addr));
    406  1.1.4.2  yamt 		retval = sc->sc_play_buf->i2b_addr;
    407  1.1.4.2  yamt 	} else if (direction == AUMODE_RECORD) {
    408  1.1.4.2  yamt 		if (sc->sc_rec_buf != NULL)
    409  1.1.4.2  yamt 			return NULL;
    410  1.1.4.2  yamt 
    411  1.1.4.2  yamt 		s3c2440_i2s_alloc(sc->sc_i2s_handle, direction, size, 0x00, &sc->sc_rec_buf);
    412  1.1.4.2  yamt 		DPRINTF(("%s: addr of ring buffer: %p\n", __func__, sc->sc_rec_buf->i2b_addr));
    413  1.1.4.2  yamt 		retval = sc->sc_rec_buf->i2b_addr;
    414  1.1.4.2  yamt 	}
    415  1.1.4.2  yamt 
    416  1.1.4.2  yamt 	DPRINTF(("buffer: %p", retval));
    417  1.1.4.2  yamt 
    418  1.1.4.2  yamt 	return retval;
    419  1.1.4.2  yamt }
    420  1.1.4.2  yamt 
    421  1.1.4.2  yamt void
    422  1.1.4.2  yamt uda_ssio_freem(void *handle, void *ptr, size_t size)
    423  1.1.4.2  yamt {
    424  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    425  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    426  1.1.4.2  yamt 	DPRINTF(("%s\n", __func__));
    427  1.1.4.2  yamt 
    428  1.1.4.2  yamt 	if (ptr == sc->sc_play_buf->i2b_addr)
    429  1.1.4.2  yamt 		s3c2440_i2s_free(sc->sc_play_buf);
    430  1.1.4.2  yamt 	else if (ptr == sc->sc_rec_buf->i2b_addr)
    431  1.1.4.2  yamt 		s3c2440_i2s_free(sc->sc_rec_buf);
    432  1.1.4.2  yamt }
    433  1.1.4.2  yamt 
    434  1.1.4.2  yamt size_t
    435  1.1.4.2  yamt uda_ssio_round_buffersize(void *handle, int direction, size_t bufsize)
    436  1.1.4.2  yamt {
    437  1.1.4.2  yamt 	DPRINTF(("%s: %d\n", __func__, (int)bufsize));
    438  1.1.4.2  yamt 	return bufsize;
    439  1.1.4.2  yamt }
    440  1.1.4.2  yamt 
    441  1.1.4.2  yamt int
    442  1.1.4.2  yamt uda_ssio_getprops(void *handle)
    443  1.1.4.2  yamt {
    444  1.1.4.2  yamt 	return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE;
    445  1.1.4.2  yamt }
    446  1.1.4.2  yamt 
    447  1.1.4.2  yamt void
    448  1.1.4.2  yamt uda_ssio_get_locks(void *handle, kmutex_t **intr, kmutex_t **thread)
    449  1.1.4.2  yamt {
    450  1.1.4.2  yamt 	struct uda1341_softc *uc = handle;
    451  1.1.4.2  yamt 	struct uda_softc *sc = uc->parent;
    452  1.1.4.2  yamt 	//struct uda_softc *sc = handle;
    453  1.1.4.2  yamt 
    454  1.1.4.2  yamt 	*intr = &sc->sc_intr_lock;
    455  1.1.4.2  yamt 	*thread = &sc->sc_lock;
    456  1.1.4.2  yamt }
    457  1.1.4.2  yamt 
    458  1.1.4.2  yamt void
    459  1.1.4.2  yamt uda_ssio_l3_write(void *cookie, int mode, int value)
    460  1.1.4.2  yamt {
    461  1.1.4.2  yamt 	struct s3c2xx0_softc *s3sc = s3c2xx0_softc; /* Shortcut */
    462  1.1.4.2  yamt 	uint32_t reg;
    463  1.1.4.2  yamt 
    464  1.1.4.2  yamt 	/* GPB2: L3MODE
    465  1.1.4.2  yamt 	   GPB3: L2DATA
    466  1.1.4.2  yamt 	   GPB4: L3CLOCK */
    467  1.1.4.2  yamt #define L3MODE	2
    468  1.1.4.2  yamt #define L3DATA	3
    469  1.1.4.2  yamt #define L3CLOCK 4
    470  1.1.4.2  yamt #define READ_GPIO() bus_space_read_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT)
    471  1.1.4.2  yamt #define WRITE_GPIO(val) bus_space_write_4(s3sc->sc_iot, s3sc->sc_gpio_ioh, GPIO_PBDAT, val)
    472  1.1.4.2  yamt 
    473  1.1.4.2  yamt #define DELAY_TIME 1
    474  1.1.4.2  yamt 
    475  1.1.4.2  yamt 	reg = READ_GPIO();
    476  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
    477  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3MODE, mode);
    478  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3DATA, 0);
    479  1.1.4.2  yamt 	WRITE_GPIO(reg);
    480  1.1.4.2  yamt 
    481  1.1.4.2  yamt 	if (mode == 1 ) {
    482  1.1.4.2  yamt 		reg = READ_GPIO();
    483  1.1.4.2  yamt 		reg = GPIO_SET_DATA(reg, L3MODE, 1);
    484  1.1.4.2  yamt 		WRITE_GPIO(reg);
    485  1.1.4.2  yamt 	}
    486  1.1.4.2  yamt 
    487  1.1.4.2  yamt 	DELAY(1); /* L3MODE setup time: min 190ns */
    488  1.1.4.2  yamt 
    489  1.1.4.2  yamt 	for(int i = 0; i<8; i++) {
    490  1.1.4.2  yamt 		char bval = (value >> i) & 0x1;
    491  1.1.4.2  yamt 
    492  1.1.4.2  yamt 		reg = READ_GPIO();
    493  1.1.4.2  yamt 		reg = GPIO_SET_DATA(reg, L3CLOCK, 0);
    494  1.1.4.2  yamt 		reg = GPIO_SET_DATA(reg, L3DATA, bval);
    495  1.1.4.2  yamt 		WRITE_GPIO(reg);
    496  1.1.4.2  yamt 
    497  1.1.4.2  yamt 		DELAY(DELAY_TIME);
    498  1.1.4.2  yamt 
    499  1.1.4.2  yamt 		reg = READ_GPIO();
    500  1.1.4.2  yamt 		reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
    501  1.1.4.2  yamt 		reg = GPIO_SET_DATA(reg, L3DATA, bval);
    502  1.1.4.2  yamt 		WRITE_GPIO(reg);
    503  1.1.4.2  yamt 
    504  1.1.4.2  yamt 		DELAY(DELAY_TIME);
    505  1.1.4.2  yamt 	}
    506  1.1.4.2  yamt 
    507  1.1.4.2  yamt 	reg = READ_GPIO();
    508  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3MODE, 1);
    509  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3CLOCK, 1);
    510  1.1.4.2  yamt 	reg = GPIO_SET_DATA(reg, L3DATA, 0);
    511  1.1.4.2  yamt 	WRITE_GPIO(reg);
    512  1.1.4.2  yamt 
    513  1.1.4.2  yamt #undef L3MODE
    514  1.1.4.2  yamt #undef L3DATA
    515  1.1.4.2  yamt #undef L3CLOCK
    516  1.1.4.2  yamt #undef DELAY_TIME
    517  1.1.4.2  yamt #undef READ_GPIO
    518  1.1.4.2  yamt #undef WRITE_GPIO
    519  1.1.4.2  yamt }
    520