Home | History | Annotate | Line # | Download | only in i2c
mt2131.c revision 1.1
      1  1.1  jakllsch /* $NetBSD: mt2131.c,v 1.1 2011/08/04 01:45:37 jakllsch Exp $ */
      2  1.1  jakllsch 
      3  1.1  jakllsch /*
      4  1.1  jakllsch  * Copyright (c) 2008, 2011 Jonathan A. Kollasch
      5  1.1  jakllsch  * All rights reserved.
      6  1.1  jakllsch  *
      7  1.1  jakllsch  * Redistribution and use in source and binary forms, with or without
      8  1.1  jakllsch  * modification, are permitted provided that the following conditions
      9  1.1  jakllsch  * are met:
     10  1.1  jakllsch  * 1. Redistributions of source code must retain the above copyright
     11  1.1  jakllsch  *    notice, this list of conditions and the following disclaimer.
     12  1.1  jakllsch  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jakllsch  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  jakllsch  *    documentation and/or other materials provided with the distribution.
     15  1.1  jakllsch  *
     16  1.1  jakllsch  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17  1.1  jakllsch  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  1.1  jakllsch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  1.1  jakllsch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     20  1.1  jakllsch  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21  1.1  jakllsch  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  1.1  jakllsch  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23  1.1  jakllsch  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  1.1  jakllsch  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25  1.1  jakllsch  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26  1.1  jakllsch  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  1.1  jakllsch  */
     28  1.1  jakllsch 
     29  1.1  jakllsch #include <sys/cdefs.h>
     30  1.1  jakllsch __KERNEL_RCSID(0, "$NetBSD: mt2131.c,v 1.1 2011/08/04 01:45:37 jakllsch Exp $");
     31  1.1  jakllsch 
     32  1.1  jakllsch #include <sys/param.h>
     33  1.1  jakllsch #include <sys/systm.h>
     34  1.1  jakllsch #include <sys/device.h>
     35  1.1  jakllsch #include <sys/kmem.h>
     36  1.1  jakllsch #include <sys/syslog.h>
     37  1.1  jakllsch #include <sys/proc.h>
     38  1.1  jakllsch 
     39  1.1  jakllsch #include <dev/i2c/mt2131var.h>
     40  1.1  jakllsch 
     41  1.1  jakllsch #define PWR 0x07
     42  1.1  jakllsch #define UPC_1 0x0b
     43  1.1  jakllsch #define AGC_RL 0x10
     44  1.1  jakllsch #define MISC_2 0x15
     45  1.1  jakllsch 
     46  1.1  jakllsch #define IF1 1220
     47  1.1  jakllsch #define IF2 44000
     48  1.1  jakllsch #define REF 16000
     49  1.1  jakllsch 
     50  1.1  jakllsch static const uint8_t mt2131_initstring[] = {
     51  1.1  jakllsch 	0x01,
     52  1.1  jakllsch 	0x50, 0x00, 0x50, 0x80, 0x00, 0x49,
     53  1.1  jakllsch 	0xfa, 0x88, 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
     54  1.1  jakllsch 	0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80, 0xff, 0x68,
     55  1.1  jakllsch 	0xa0, 0xff, 0xdd, 0x00, 0x00
     56  1.1  jakllsch };
     57  1.1  jakllsch 
     58  1.1  jakllsch static const uint8_t mt2131_agcinitstring[] = {
     59  1.1  jakllsch         AGC_RL,
     60  1.1  jakllsch         0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
     61  1.1  jakllsch };
     62  1.1  jakllsch 
     63  1.1  jakllsch 
     64  1.1  jakllsch struct mt2131_softc {
     65  1.1  jakllsch 	device_t		parent;
     66  1.1  jakllsch 	i2c_tag_t		tag;
     67  1.1  jakllsch 	i2c_addr_t		addr;
     68  1.1  jakllsch 	uint32_t		frequency;
     69  1.1  jakllsch 	uint32_t		bandwidth;
     70  1.1  jakllsch };
     71  1.1  jakllsch 
     72  1.1  jakllsch static int mt2131_init(struct mt2131_softc *);
     73  1.1  jakllsch 
     74  1.1  jakllsch static int mt2131_read(struct mt2131_softc *, uint8_t, uint8_t *);
     75  1.1  jakllsch static int mt2131_write(struct mt2131_softc *, uint8_t, uint8_t);
     76  1.1  jakllsch 
     77  1.1  jakllsch struct mt2131_softc *
     78  1.1  jakllsch mt2131_open(device_t parent, i2c_tag_t t, i2c_addr_t a)
     79  1.1  jakllsch {
     80  1.1  jakllsch 	struct mt2131_softc *sc;
     81  1.1  jakllsch 	int ret;
     82  1.1  jakllsch 
     83  1.1  jakllsch 	uint8_t cmd, reg;
     84  1.1  jakllsch 
     85  1.1  jakllsch 	cmd = reg = 0;
     86  1.1  jakllsch 
     87  1.1  jakllsch 	printf("%s\n", __func__);
     88  1.1  jakllsch 
     89  1.1  jakllsch 	/* get id reg */
     90  1.1  jakllsch 	iic_acquire_bus(t, I2C_F_POLL);
     91  1.1  jakllsch 	ret = iic_exec(t, I2C_OP_READ_WITH_STOP, a, &cmd, 1, &reg, 1, I2C_F_POLL);
     92  1.1  jakllsch 	iic_release_bus(t, I2C_F_POLL);
     93  1.1  jakllsch 
     94  1.1  jakllsch 	if (ret) {
     95  1.1  jakllsch 		printf("%s read fail\n", __func__);
     96  1.1  jakllsch 		return NULL;
     97  1.1  jakllsch 	}
     98  1.1  jakllsch 
     99  1.1  jakllsch 	printf("%s %02x\n", __func__, reg);
    100  1.1  jakllsch 
    101  1.1  jakllsch 	if ((reg & 0xfe) != 0x3e)
    102  1.1  jakllsch 		return NULL;
    103  1.1  jakllsch 
    104  1.1  jakllsch 	sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
    105  1.1  jakllsch 	if (sc == NULL)
    106  1.1  jakllsch                 return NULL;
    107  1.1  jakllsch 
    108  1.1  jakllsch 	sc->parent = parent;
    109  1.1  jakllsch 	sc->tag = t;
    110  1.1  jakllsch 	sc->addr = a;
    111  1.1  jakllsch 
    112  1.1  jakllsch 	mt2131_init(sc);
    113  1.1  jakllsch 
    114  1.1  jakllsch 	return sc;
    115  1.1  jakllsch }
    116  1.1  jakllsch 
    117  1.1  jakllsch void
    118  1.1  jakllsch mt2131_close(struct mt2131_softc *sc)
    119  1.1  jakllsch {
    120  1.1  jakllsch 	kmem_free(sc, sizeof(*sc));
    121  1.1  jakllsch }
    122  1.1  jakllsch 
    123  1.1  jakllsch int
    124  1.1  jakllsch mt2131_tune_dtv(struct mt2131_softc *sc, const struct dvb_frontend_parameters *p)
    125  1.1  jakllsch {
    126  1.1  jakllsch 	int rv;
    127  1.1  jakllsch 	uint64_t o1, o2;
    128  1.1  jakllsch 	uint64_t d1, d2;
    129  1.1  jakllsch 	uint32_t r1, r2;
    130  1.1  jakllsch 	uint32_t fr;
    131  1.1  jakllsch 	uint8_t b[7];
    132  1.1  jakllsch 	uint8_t regval;
    133  1.1  jakllsch 
    134  1.1  jakllsch 	mt2131_init(sc);
    135  1.1  jakllsch 
    136  1.1  jakllsch 	b[0] = 0x01;
    137  1.1  jakllsch 
    138  1.1  jakllsch 	if(p->frequency != 0 &&
    139  1.1  jakllsch 		(p->frequency < 50000000 || p->frequency > 1000000000))
    140  1.1  jakllsch 		return EINVAL;
    141  1.1  jakllsch 
    142  1.1  jakllsch 	fr = p->frequency / 1000;
    143  1.1  jakllsch 
    144  1.1  jakllsch 	o1 = fr + IF1 * 1000;
    145  1.1  jakllsch 	o2 = o1 - fr - IF2;
    146  1.1  jakllsch 
    147  1.1  jakllsch 	d1 = (o1 * 8192)/REF;
    148  1.1  jakllsch 	d2 = (o2 * 8192)/REF;
    149  1.1  jakllsch 
    150  1.1  jakllsch 	r1 = d1/8192;
    151  1.1  jakllsch 	r2 = d2/8192;
    152  1.1  jakllsch 
    153  1.1  jakllsch 	printf("mt2131 %lu %lu %lu %u\n", o1, d1, d1&0x1fff, r1);
    154  1.1  jakllsch 	printf("mt2131 %lu %lu %lu %u\n", o2, d2, d2&0x1fff, r2);
    155  1.1  jakllsch 
    156  1.1  jakllsch 	b[1] = (d1 & 0x1fe0) >> 5;
    157  1.1  jakllsch 	b[2] = (d1 & 0x001f);
    158  1.1  jakllsch 	b[3] = r1;
    159  1.1  jakllsch 	b[4] = (d2 & 0x1fe0) >> 5;
    160  1.1  jakllsch 	b[5] = (d2 & 0x001f);
    161  1.1  jakllsch 	b[6] = r2;
    162  1.1  jakllsch 
    163  1.1  jakllsch 	iic_acquire_bus(sc->tag, I2C_F_POLL);
    164  1.1  jakllsch 	rv = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr, b, 7, NULL, 0, I2C_F_POLL);
    165  1.1  jakllsch 	iic_release_bus(sc->tag, I2C_F_POLL);
    166  1.1  jakllsch 
    167  1.1  jakllsch 	regval = (fr - 27501) / 55000;
    168  1.1  jakllsch 
    169  1.1  jakllsch 	if(regval > 0x13)
    170  1.1  jakllsch 		regval = 0x13;
    171  1.1  jakllsch 
    172  1.1  jakllsch 	printf("mt2131 %u\n", regval);
    173  1.1  jakllsch 
    174  1.1  jakllsch 	rv = mt2131_write(sc, UPC_1, regval);
    175  1.1  jakllsch 
    176  1.1  jakllsch 	if (rv != 0)
    177  1.1  jakllsch 		printf("%s\n", __func__);
    178  1.1  jakllsch 
    179  1.1  jakllsch 	sc->frequency = (o1 - o2 - IF2) * 1000;
    180  1.1  jakllsch 	printf("%s freq %d\n", __func__, sc->frequency);
    181  1.1  jakllsch 
    182  1.1  jakllsch 	int i;
    183  1.1  jakllsch 	b[0] = 0x08;
    184  1.1  jakllsch 
    185  1.1  jakllsch 	for ( i = 0; i < 100; i++) {
    186  1.1  jakllsch 		rv = mt2131_read(sc, 0x08, &regval);
    187  1.1  jakllsch 
    188  1.1  jakllsch 		if (( regval & 0x88 ) == 0x88 ) {
    189  1.1  jakllsch 			printf("mt2131 - locked\n");
    190  1.1  jakllsch 			break;
    191  1.1  jakllsch 		} else {
    192  1.1  jakllsch 			printf("mt2131 - not locked - %02x\n", b[1]);
    193  1.1  jakllsch 		}
    194  1.1  jakllsch 		kpause("mt2131", true, 1, NULL);
    195  1.1  jakllsch 	}
    196  1.1  jakllsch 
    197  1.1  jakllsch 	return rv;
    198  1.1  jakllsch }
    199  1.1  jakllsch 
    200  1.1  jakllsch static int
    201  1.1  jakllsch mt2131_init(struct mt2131_softc *sc)
    202  1.1  jakllsch {
    203  1.1  jakllsch 	int ret;
    204  1.1  jakllsch 
    205  1.1  jakllsch 	printf("%s\n", __func__);
    206  1.1  jakllsch 
    207  1.1  jakllsch 	ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
    208  1.1  jakllsch 	if (ret)
    209  1.1  jakllsch 		return -1;
    210  1.1  jakllsch 	ret = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr,
    211  1.1  jakllsch 	    mt2131_initstring, sizeof(mt2131_initstring), NULL, 0, I2C_F_POLL);
    212  1.1  jakllsch 	if (ret)
    213  1.1  jakllsch 		return -1;
    214  1.1  jakllsch 	iic_release_bus(sc->tag, I2C_F_POLL);
    215  1.1  jakllsch 
    216  1.1  jakllsch 	ret = mt2131_write(sc, UPC_1, 0x09);
    217  1.1  jakllsch 	ret = mt2131_write(sc, MISC_2, 0x47);
    218  1.1  jakllsch 	ret = mt2131_write(sc, PWR, 0xf2);
    219  1.1  jakllsch 	ret = mt2131_write(sc, UPC_1, 0x01);
    220  1.1  jakllsch 
    221  1.1  jakllsch 	ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
    222  1.1  jakllsch 	if (ret)
    223  1.1  jakllsch 		return -1;
    224  1.1  jakllsch 	ret = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr,
    225  1.1  jakllsch 	    mt2131_agcinitstring, sizeof(mt2131_agcinitstring),
    226  1.1  jakllsch 	    NULL, 0, I2C_F_POLL);
    227  1.1  jakllsch 	iic_release_bus(sc->tag, I2C_F_POLL);
    228  1.1  jakllsch 	if (ret)
    229  1.1  jakllsch 		return -1;
    230  1.1  jakllsch 
    231  1.1  jakllsch 	return 0;
    232  1.1  jakllsch }
    233  1.1  jakllsch 
    234  1.1  jakllsch static int
    235  1.1  jakllsch mt2131_read(struct mt2131_softc *sc, uint8_t r, uint8_t *v)
    236  1.1  jakllsch {
    237  1.1  jakllsch 	int ret;
    238  1.1  jakllsch 
    239  1.1  jakllsch 	ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
    240  1.1  jakllsch 	if (ret)
    241  1.1  jakllsch 		return ret;
    242  1.1  jakllsch 	ret = iic_exec(sc->tag, I2C_OP_READ_WITH_STOP, sc->addr,
    243  1.1  jakllsch 	    &r, 1, v, 1, I2C_F_POLL);
    244  1.1  jakllsch 
    245  1.1  jakllsch 	iic_release_bus(sc->tag, I2C_F_POLL);
    246  1.1  jakllsch 
    247  1.1  jakllsch 	return ret;
    248  1.1  jakllsch }
    249  1.1  jakllsch 
    250  1.1  jakllsch static int
    251  1.1  jakllsch mt2131_write(struct mt2131_softc *sc, uint8_t a, uint8_t v)
    252  1.1  jakllsch {
    253  1.1  jakllsch 	int ret;
    254  1.1  jakllsch 	uint8_t b[] = { a, v };
    255  1.1  jakllsch 
    256  1.1  jakllsch 	ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
    257  1.1  jakllsch 	if (ret)
    258  1.1  jakllsch 		return ret;
    259  1.1  jakllsch 
    260  1.1  jakllsch 	ret = iic_exec(sc->tag, I2C_OP_READ_WITH_STOP, sc->addr,
    261  1.1  jakllsch 	    b, sizeof(b), NULL, 0, I2C_F_POLL);
    262  1.1  jakllsch 
    263  1.1  jakllsch 	iic_release_bus(sc->tag, I2C_F_POLL);
    264  1.1  jakllsch 
    265  1.1  jakllsch 	return ret;
    266  1.1  jakllsch }
    267