Advertisement
Guest User

FreeBSD DVB-S satellite receiver driver for Technotrend DVB-S Nova satellite receiver PCI card

a guest
Jun 2nd, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 25.98 KB | Source Code | 0 0
  1. /* newsat - new satellite receiver driver
  2.  *
  3.  * (C) XXXXXXXXXXXX
  4.  *
  5.  */
  6.  
  7. #ifndef _NEWSAT_H_
  8. #define _NEWSAT_H_
  9.  
  10. #include <sys/types.h>
  11.  
  12. struct sat_param {
  13.   int pol; /* Polarisation */
  14.   int freq; /* Frequency */
  15.   int baud; /* Baud rate */
  16.   int fec; /* Forward error correction */
  17.   int mod; /* reacquire if set */
  18. };
  19.  
  20.  
  21. #ifdef _KERNEL
  22. struct newsat_softc {
  23.   dev_t newsat_dev_t;
  24.   device_t device;
  25.   int initialised; /* Device is initialised */
  26.  
  27.  
  28.   /* MMIO Registers */
  29.   int regs_rid;
  30.   struct resource *regs_res;
  31.   bus_space_handle_t *regs_h;
  32.   uint8_t *regs_base;
  33.  
  34.   /* IRQ */
  35.   int irq_rid;
  36.   struct resource *irq_res;
  37.   void *irq_h;
  38.  
  39.   /* DMA */
  40.   int dma_running;
  41.   uint32_t *pagetbl_base;
  42.   vm_offset_t pagetbl_phy_addr;
  43.  
  44.   struct {
  45.     uint8_t *data;
  46.     int psize;
  47.     int size;
  48.     unsigned long rptr, wptr, wptr_s; /* Read / write pointers */
  49.     int head;
  50.     int tail;
  51.     int space;
  52.   } ring;
  53.  
  54.   struct {
  55.     int band, pol;
  56.   } tuner;
  57.  
  58.   struct sat_param param;
  59. };
  60.  
  61. #define CHIPR32(n) *((volatile uint32_t *) (sc->regs_base + (n)))
  62.  
  63. #define IIC_SEND_STOP       (1 << 0)
  64. #define IIC_ERR_ADDRESS     -1
  65. #define IIC_ERR_DATA        -2
  66.  
  67. #define IIC_WRITE       0
  68. #define IIC_READ        1
  69.  
  70. #endif /* _KERNEL */
  71.  
  72. /* ioctls */
  73. #define SAT_GET_SIGNAL    _IOR('x', 1, int) /* get signal meter */
  74. #define SAT_GET_STATUS    _IOR('x', 2, int) /* get status */
  75. #define SAT_GET_BER       _IOR('x', 3, int) /* get bit error rate */
  76. #define SAT_GET_AFC       _IOR('x', 4, int) /* get bit error rate */
  77. #define SAT_ACQUIRE       _IOW('x', 10, struct sat_param) /* receive signal */
  78. #define SAT_FIFO_SYNC     _IO('x', 100) /* Reset the ring buffer */
  79. #define SAT_FIFO_GETENT   _IOR('x', 101, int) /* Get number of pending bytes */
  80.  
  81. #define SATSTATUS_SIGNAL    (1 << 0)
  82. #define SATSTATUS_CARRIER   (1 << 1)
  83. #define SATSTATUS_VITERBI   (1 << 2)
  84. #define SATSTATUS_FSYNC     (1 << 3)
  85. #define SATSTATUS_FRONT     (1 << 4)
  86. #define SATSTATUS_MEASVALID (1 << 5)
  87.  
  88. #endif /* _NEWSAT_H_ */
  89.  
  90.  
  91.  
  92. /* newsat - new satellite receiver driver
  93.  *
  94.  * (C) XXXXXXXXXXXXXXXXXXX
  95.  *
  96.  */
  97.  
  98. #include <sys/types.h>
  99. #include <sys/module.h>
  100. #include <sys/systm.h>
  101. #include <sys/errno.h>
  102. #include <sys/param.h>
  103. #include <sys/kernel.h>
  104. #include <sys/conf.h>
  105. #include <sys/uio.h>
  106. #include <sys/ioccom.h>
  107. #include <sys/malloc.h>
  108. #include <sys/bus.h> /* device_t */
  109. #include <machine/bus.h>
  110. #include <sys/rman.h>
  111. #include <machine/resource.h>
  112. #include <vm/vm.h>
  113. #include <vm/pmap.h>
  114. #include <vm/vm_kern.h>
  115. #include <vm/vm_extern.h>
  116. #include <pci/pcireg.h>
  117. #include <pci/pcivar.h>
  118.  
  119. #include "newsat.h"
  120. #include "saa7146.h"
  121. #include "ves1893.h"
  122.  
  123. /* This specifies the dimensions of the DMA ring buffer in memory */
  124. #define SAA_DMA_ROW_SIZE 5
  125. #define SAA_DMA_NUM_ROWS 4096
  126.  
  127. /* probe,attach,detach, etc. */
  128. static int newsat_probe(device_t);
  129. static int newsat_attach(device_t);
  130. static int newsat_detach(device_t);
  131. static int newsat_shutdown(device_t);
  132.  
  133. static device_method_t newsat_methods[] = {
  134.   DEVMETHOD(device_probe, newsat_probe),
  135.   DEVMETHOD(device_attach, newsat_attach),
  136.   DEVMETHOD(device_detach, newsat_detach),
  137.   DEVMETHOD(device_shutdown, newsat_shutdown),
  138.   {0, 0}
  139. };
  140.  
  141. static driver_t newsat_driver = {
  142.   "newsat",
  143.   newsat_methods,
  144.   sizeof(struct newsat_softc)
  145. };
  146.  
  147. static devclass_t newsat_devclass;
  148.  
  149. DRIVER_MODULE(newsat, pci, newsat_driver, newsat_devclass, 0, 0);
  150. MODULE_VERSION(newsat, 1)
  151.  
  152. static d_open_t newsat_open;
  153. static d_close_t newsat_close;
  154. static d_read_t newsat_read;
  155. static d_ioctl_t newsat_ioctl;
  156.  
  157. static struct cdevsw newsat_cdevsw = {
  158.   newsat_open,
  159.   newsat_close,
  160.   newsat_read,
  161.   nowrite,
  162.   newsat_ioctl,
  163.   nopoll,
  164.   nommap,
  165.   nostrategy,
  166.   "newsat",
  167.   33,
  168.   nodump,
  169.   nopsize,
  170.   0,
  171.   -1
  172. };
  173.  
  174. static void newsat_cleanup(device_t);
  175. static void newsat_intr(void *);
  176. static void newsat_regset(struct newsat_softc *, int, uint32_t, uint32_t);
  177. static void newsat_MC1_prog(struct newsat_softc *, uint16_t, uint16_t);
  178. static void newsat_MC2_prog(struct newsat_softc *, uint16_t, uint16_t);
  179. static void newsat_MC1_set(struct newsat_softc *, uint16_t);
  180. static void newsat_MC2_set(struct newsat_softc *, uint16_t);
  181. static void newsat_MC1_clear(struct newsat_softc *, uint16_t);
  182. static void newsat_MC2_clear(struct newsat_softc *, uint16_t);
  183. static void newsat_dma_start(struct newsat_softc *);
  184. static void newsat_dma_stop(struct newsat_softc *);
  185. static void newsat_dma_sync(struct newsat_softc *);
  186. static void newsat_dma_unlock(struct newsat_softc *);
  187. static int newsat_dma_getpending(struct newsat_softc *);
  188. static void newsat_hw_reset(struct newsat_softc *);
  189. static void newsat_iic_upload(struct newsat_softc *);
  190. static void newsat_iic_reset(struct newsat_softc *);
  191. static void newsat_iic_init(struct newsat_softc *);
  192. static int newsat_iic_wait(struct newsat_softc *);
  193. static int newsat_iic_address(struct newsat_softc *, int, int);
  194. static int newsat_iic_writeN(struct newsat_softc *, int, uint8_t *, int, int);
  195. static int newsat_iic_readN(struct newsat_softc *, int, uint8_t *, int, int);
  196. static void tuner_init(struct newsat_softc *);
  197. static int tuner_demod_write(struct newsat_softc *, int, int);
  198. static int tuner_demod_read(struct newsat_softc *, int);
  199. static void tuner_demod_reset(struct newsat_softc *);
  200. static void tuner_demod_init(struct newsat_softc *);
  201. static int tuner_demod_status(struct newsat_softc *);
  202. static int tuner_demod_sigmeter(struct newsat_softc *);
  203. static int tuner_demod_ber(struct newsat_softc *);
  204. static int tuner_demod_afc(struct newsat_softc *);
  205. static int tuner_demod_setbaud(struct newsat_softc *, int, int);
  206. static void tuner_set_pol(struct newsat_softc *, int);
  207. static void tuner_set_band(struct newsat_softc *, int);
  208. static int tuner_tuneto(struct newsat_softc *, int, int);
  209.  
  210. /* Interrupt handler */
  211. static void newsat_intr(void *p)
  212. {
  213.   struct newsat_softc *sc;
  214.   sc = (struct newsat_softc *) p;
  215.  
  216.   return;
  217. }
  218.  
  219. /* Probe, Attach, Detach and Shutdown subroutines */
  220.  
  221. static int newsat_probe(device_t dev)
  222. {
  223.   switch(pci_get_devid(dev)) {
  224.   case SAA7146_PCI_ID:
  225.     return 0;
  226.   }
  227.   return ENXIO;
  228. }
  229.  
  230. static int newsat_attach(device_t dev)
  231. {
  232.   struct newsat_softc *sc;
  233.   int unit, error, ptr;
  234.   u_long conf; /* config reg. */
  235.   vm_offset_t addr; /* pagetable address */
  236.  
  237.   sc = device_get_softc(dev);
  238.   unit = device_get_unit(dev);
  239.  
  240.   bzero(sc, sizeof(sc));
  241.  
  242.   sc->device = dev;
  243.  
  244.   /* Allocate MMIO registers */
  245.   sc->regs_rid = PCIR_MAPS + 0x00;
  246.   sc->regs_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regs_rid,
  247.                     0, ~0, 1, RF_ACTIVE);
  248.   if(sc->regs_res == NULL) {
  249.     device_printf(dev, "MMIO register space allocation failed\n");
  250.     goto failed;
  251.   }
  252.   sc->regs_h = (bus_space_handle_t *) rman_get_bushandle(sc->regs_res);
  253.   sc->regs_base = (u_int8_t *) sc->regs_h;
  254.  
  255.   /* Allocate interrupt */
  256.   sc->irq_rid = 0;
  257.   sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
  258.                    0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
  259.   if(sc->irq_res == NULL) {
  260.     device_printf(dev, "could not allocate interrupt\n");
  261.     goto failed;
  262.   }
  263.   error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_TTY, newsat_intr,
  264.              sc, &sc->irq_h);
  265.   if(error) {
  266.     device_printf(dev, "could not setup interrupt\n");
  267.     goto failed;
  268.   }
  269.  
  270.   sc->newsat_dev_t = make_dev(&newsat_cdevsw, unit, 0, 0, 0600,
  271.                   "newsat%d", unit);
  272.   if(sc->newsat_dev_t == NULL) {
  273.     device_printf(dev, "could not create device\n");
  274.     goto failed;
  275.   }
  276.  
  277.   /* Allocate memory for page translation table */
  278.   addr = vm_page_alloc_contig(4096 / PAGE_SIZE, 0, ~0, PAGE_SIZE);
  279.   if(addr == 0) {
  280.     device_printf(dev, "could not allocate contiguous memory");
  281.     goto failed;
  282.   }
  283.   sc->pagetbl_base = (uint32_t *) addr;
  284.   sc->pagetbl_phy_addr = vtophys(addr);
  285.  
  286.   /* Allocate DMA buffer */
  287.   sc->ring.size = 188 * SAA_DMA_ROW_SIZE * SAA_DMA_NUM_ROWS;
  288.   sc->ring.psize = 4096 * 1024;
  289.   sc->ring.data = (uint8_t *) malloc(sc->ring.psize, M_DEVBUF, M_WAITOK);
  290.   if(sc->ring.data == NULL) {
  291.     device_printf(dev, "could not allocate ring buffer\n");
  292.     goto failed;
  293.   }
  294. #define BYTESTOK(n) ((n) >> 10)
  295.   device_printf(dev, "Using %dKB of %dKB allocated for DMA ring buffer\n",
  296.         BYTESTOK(sc->ring.size), BYTESTOK(sc->ring.psize));
  297.  
  298.   /* Initialise the page table */
  299.   ptr = 0;
  300.   for(addr = 0; addr < sc->ring.psize; addr += 4096) {
  301.     sc->pagetbl_base[ptr++] = vtophys((caddr_t) ((uint8_t *)sc->ring.data +
  302.                          addr));
  303.   }
  304.  
  305.   /* Enable register access and bus mastering */
  306.   conf = pci_read_config(dev, PCIR_COMMAND, 2);
  307.   conf |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
  308.   pci_write_config(dev, PCIR_COMMAND, conf, 2);
  309.  
  310.   device_printf(dev, "build date " __DATE__ " " __TIME__ "\n");
  311.   return 0;
  312.  
  313.  failed:
  314.   newsat_cleanup(dev);
  315.   return ENXIO;
  316. }
  317.  
  318. static int newsat_detach(device_t dev)
  319. {
  320.   newsat_cleanup(dev);
  321.   return 0;
  322. }
  323.  
  324. static int newsat_shutdown(device_t dev)
  325. {
  326.   newsat_cleanup(dev);
  327.   return 0;
  328. }
  329.  
  330. static void newsat_cleanup(device_t dev)
  331. {
  332.   struct newsat_softc *sc;
  333.  
  334.   if((sc = device_get_softc(dev)) == NULL)
  335.     return;
  336.  
  337.   if(sc->regs_res != NULL) {
  338.     bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid,
  339.              sc->regs_res);
  340.     sc->regs_res = NULL;
  341.   }
  342.  
  343.   if(sc->irq_res != NULL) {
  344.     bus_teardown_intr(dev, sc->irq_res, sc->irq_h);
  345.     bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
  346.                              sc->irq_res);
  347.     sc->irq_res = NULL;
  348.   }
  349.  
  350.   if(sc->pagetbl_base != NULL) {
  351.     kmem_free(kernel_map, (vm_offset_t) sc->pagetbl_base, 4096);
  352.     sc->pagetbl_base = NULL;
  353.   }
  354.  
  355.   if(sc->ring.data != NULL) {
  356.     free((caddr_t) sc->ring.data, M_DEVBUF);
  357.     sc->ring.data = NULL;
  358.   }
  359.  
  360.   if(sc->newsat_dev_t != NULL) {
  361.     destroy_dev(sc->newsat_dev_t);
  362.     sc->newsat_dev_t = NULL;
  363.   }
  364.   return;
  365. }
  366.  
  367. /* Hardware interface **************************************************/
  368.  
  369. /* register programming routines */
  370. static void newsat_regset(struct newsat_softc *sc, int reg,uint32_t mask,
  371.               uint32_t bits)
  372. {
  373.   CHIPR32(reg) = (CHIPR32(reg) & ~mask) | bits;
  374. }
  375.  
  376. static void newsat_MC1_prog(struct newsat_softc *sc, uint16_t mask,
  377.                 uint16_t bits)
  378. {
  379.   CHIPR32(SAA_MAIN_CONTROL1) = SAA_MC_MASK(mask) | SAA_MC_CONTROL(bits);
  380. }
  381.  
  382. static void newsat_MC2_prog(struct newsat_softc *sc, uint16_t mask,
  383.                 uint16_t bits)
  384. {
  385.   CHIPR32(SAA_MAIN_CONTROL2) = SAA_MC_MASK(mask) | SAA_MC_CONTROL(bits);
  386. }
  387.  
  388. static void newsat_MC1_set(struct newsat_softc *sc, uint16_t bits)
  389. {
  390.   newsat_MC1_prog(sc, bits, bits);
  391. }
  392.  
  393. static void newsat_MC2_set(struct newsat_softc *sc, uint16_t bits)
  394. {
  395.   newsat_MC2_prog(sc, bits, bits);
  396. }
  397.  
  398. static void newsat_MC1_clear(struct newsat_softc *sc, uint16_t bits)
  399. {
  400.   newsat_MC1_prog(sc, bits, 0);
  401. }
  402.  
  403. static void newsat_MC2_clear(struct newsat_softc *sc, uint16_t bits)
  404. {
  405.   newsat_MC2_prog(sc, bits, 0);
  406. }
  407.  
  408. static void newsat_dma_start(struct newsat_softc *sc)
  409. {
  410.   CHIPR32(SAA_ARB_CNTL1) = (5 << 18) | (2 << 16);
  411.   CHIPR32(SAA_DMA3_MMU_CNTL) = SAA_MMU_PAGE_TBL_ADDR(sc->pagetbl_phy_addr) |
  412.     SAA_MMU_PAGE_TBL_EN;
  413.   CHIPR32(SAA_DMA3_BASE_ODD) = CHIPR32(SAA_DMA3_BASE_EVEN) = 0;
  414.   CHIPR32(SAA_DMA3_PROT_ADDR) = sc->ring.psize;
  415.   CHIPR32(SAA_DMA3_PITCH) = 188 * SAA_DMA_ROW_SIZE;
  416.   CHIPR32(SAA_DMA3_NUM_LINES_BYTES) = (188 * SAA_DMA_ROW_SIZE) |
  417.     (SAA_DMA_NUM_ROWS << 16);
  418.   CHIPR32(SAA_D1_CONF) = 0;
  419.   CHIPR32(SAA_D1AB_CONF) = 0;
  420.   CHIPR32(SAA_BRS_CONF) = (1 << 30) | (1 << 29);
  421.  
  422.   newsat_MC2_set(sc, MC2_UPLOAD_DMA3 | MC2_UPLOAD_D1_A | MC2_UPLOAD_D1_B |
  423.          MC2_UPLOAD_BRS);
  424.   newsat_MC1_set(sc, MC1_ENABLE_DMA3 | MC1_ENABLE_VIDEO);
  425.  
  426.   tsleep(sc, PWAIT, "hwinit", hz / 2);
  427.   newsat_dma_sync(sc);
  428.   /*  device_printf(sc->device, "dma enabled\n");*/
  429.   sc->dma_running = 1;
  430. }
  431.  
  432. static void newsat_dma_stop(struct newsat_softc *sc)
  433. {
  434.   newsat_MC1_clear(sc, MC1_ENABLE_VIDEO | MC1_ENABLE_DMA3);
  435.   newsat_dma_sync(sc);
  436.   sc->dma_running = 0;
  437. }
  438.  
  439. static void newsat_dma_sync(struct newsat_softc *sc)
  440. {
  441.   sc->ring.rptr = sc->ring.wptr = sc->ring.wptr_s = CHIPR32(SAA_DMA3_PTR);
  442. }
  443.  
  444. static void newsat_dma_unlock(struct newsat_softc *sc)
  445. {
  446.   device_printf(sc->device, "dma_unlock called, trying to reset "
  447.         "DMA controller (DMA3_PTR=0x%.8x)\n", CHIPR32(SAA_DMA3_PTR));
  448.   newsat_dma_stop(sc);
  449.   newsat_dma_start(sc);
  450. }
  451.  
  452. static int newsat_dma_getpending(struct newsat_softc *sc)
  453. {
  454.   sc->ring.wptr = sc->ring.wptr_s = CHIPR32(SAA_DMA3_PTR); /* FIXME */
  455.  
  456.   if(sc->ring.wptr >= sc->ring.rptr)
  457.     return sc->ring.wptr - sc->ring.rptr;
  458.   else
  459.     return sc->ring.size + sc->ring.wptr - sc->ring.rptr;
  460. }
  461.  
  462. static void newsat_hw_reset(struct newsat_softc *sc)
  463. {
  464.   newsat_MC1_clear(sc, MC1_MASTER_RESET_NOT);
  465.   newsat_dma_stop(sc); /* just to be sure, and to clear the dma_running flag */
  466.  
  467.   /* Set GPIO pins to tristate */
  468.   CHIPR32(SAA_GPIO) =  GPIO0(GPIO_TRISTATE) | GPIO1(GPIO_TRISTATE) |
  469.     GPIO2(GPIO_TRISTATE) | GPIO3(GPIO_TRISTATE);
  470.   printf("Debug hardware reset DMA3 ptr 0x%.8x\n", CHIPR32(SAA_DMA3_PTR));
  471. }
  472.  
  473.  
  474. /* Device handler code *************************************************/
  475.  
  476. static int newsat_open(dev_t dev, int oflags, int devtype, struct proc *p)
  477. {
  478.   struct newsat_softc *sc;
  479.   int unit;
  480.  
  481.   unit = minor(dev);
  482.   if((sc = devclass_get_softc(newsat_devclass, unit)) == NULL)
  483.     return ENXIO;
  484.  
  485.   device_busy(sc->device);
  486.  
  487.   newsat_hw_reset(sc);
  488.   newsat_iic_init(sc);
  489.   tuner_init(sc);
  490.   return 0;
  491. }
  492.  
  493. static int newsat_close(dev_t dev, int fflags, int devtype, struct proc *p)
  494. {
  495.   struct newsat_softc *sc;
  496.   int unit;
  497.  
  498.   unit = minor(dev);
  499.   if((sc = devclass_get_softc(newsat_devclass, unit)) == NULL)
  500.     return ENXIO;
  501.  
  502.   device_unbusy(sc->device);
  503.   return 0;
  504. }
  505.  
  506. /* DMA Transfer */
  507. static int newsat_read(dev_t dev, struct uio *uio, int ioflag)
  508. {
  509.   struct newsat_softc *sc;
  510.   int unit;
  511.   int retry, count, err = 0;
  512.  
  513.   unit = minor(dev);
  514.   if((sc = devclass_get_softc(newsat_devclass, unit)) == NULL)
  515.     return ENXIO;
  516.  
  517. #define MIN(a, b) ((a < b) ? a : b)
  518. #define MAX(a, b) ((a > b) ? a : b)
  519.  
  520.   if(!sc->dma_running) {
  521.     newsat_dma_start(sc);
  522.   }
  523.  
  524.   retry = count = 0;
  525.  
  526.   while(uio->uio_resid > 0) {
  527.     int blk = -1, chunksize;
  528.  
  529.     sc->ring.wptr = sc->ring.wptr_s = CHIPR32(SAA_DMA3_PTR); /* FIXME */
  530.  
  531.     if(sc->ring.wptr < sc->ring.size) {
  532.       chunksize = ((sc->ring.wptr < sc->ring.rptr) ?
  533.            sc->ring.size : sc->ring.wptr) - sc->ring.rptr;
  534.       blk = MIN(uio->uio_resid, chunksize);
  535.     } else {
  536.       device_printf(sc->device, "DMA wptr > buffer size: WPTR=0x%.8lx\n",
  537.             sc->ring.wptr);
  538.       newsat_dma_unlock(sc);
  539.     }
  540.     if(blk > 0) {
  541.       if((err = uiomove((caddr_t) (sc->ring.data + sc->ring.rptr),
  542.             blk, uio)) != 0) goto error;
  543.       if((sc->ring.rptr += blk) >= sc->ring.size)
  544.     sc->ring.rptr = 0;
  545.       retry = count = 0;
  546.     } else {
  547.       int sr;
  548.       if((sr = tsleep(sc, PWAIT | PCATCH, "dmard", 1)) != EWOULDBLOCK)
  549.     return sr;
  550.       count++;
  551.       if(count > 50) {
  552.     retry++;
  553.     device_printf(sc->device, "DMA transfer stall, retry=%d\n", retry);
  554.     newsat_dma_unlock(sc);
  555.       }
  556.       if(retry >= 10) {
  557.     device_printf(sc->device, "DMA timeout, too many retries: "
  558.               "RPTR=0x%.8lx WPTR=0x%.8lx\n",
  559.               sc->ring.rptr, sc->ring.wptr);
  560.     newsat_dma_stop(sc);
  561.     err = EIO;
  562.     goto error;
  563.       }
  564.     }
  565.   }
  566.   return 0;
  567.  error:
  568.   return err;
  569. }
  570.  
  571. /* ioctl */
  572. static int newsat_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag,
  573.             struct proc *pr)
  574. {
  575.   struct newsat_softc *sc;
  576.   struct sat_param *param;
  577.   int unit;
  578.   int err;
  579.  
  580.   unit = minor(dev);
  581.   if((sc = devclass_get_softc(newsat_devclass, unit)) == NULL)
  582.     return ENXIO;
  583.  
  584.   param = (struct sat_param *) arg;
  585.  
  586.   switch(cmd) {
  587.   case SAT_GET_SIGNAL:
  588.     *((int *) arg) = tuner_demod_sigmeter(sc);
  589.     break;
  590.   case SAT_GET_STATUS:
  591.     *((int *) arg) = tuner_demod_status(sc);
  592.     break;
  593.   case SAT_GET_BER:
  594.     *((int *) arg) = tuner_demod_ber(sc);
  595.     break;
  596.   case SAT_GET_AFC:
  597.     *((int *) arg) = tuner_demod_afc(sc);
  598.     break;
  599.   case SAT_ACQUIRE:
  600.     if((param->mod) || (sc->param.mod)) {
  601.       sc->param.pol = sc->param.freq = sc->param.baud = sc->param.fec = -1;
  602.     }
  603.     if((param->pol != sc->param.pol) || (param->freq != sc->param.freq)) {
  604.       if((err = tuner_tuneto(sc, param->pol, param->freq)) < 0)
  605.     return err;
  606.       sc->param.pol = param->pol;
  607.       sc->param.freq = param->freq;
  608.     }
  609.     if((param->baud != sc->param.baud) || (param->fec != sc->param.fec)) {
  610.       if((err = tuner_demod_setbaud(sc, param->baud, param->fec)) < 0)
  611.     return err;
  612.       sc->param.baud = param->baud;
  613.       sc->param.fec = param->fec;
  614.     }
  615.     sc->param.mod = 0;
  616.     break;
  617.   case SAT_FIFO_SYNC:
  618.     newsat_dma_sync(sc);
  619.     break;
  620.   case SAT_FIFO_GETENT:
  621.     *((int *) arg) = newsat_dma_getpending(sc);
  622.     break;
  623.   default:
  624.     return ENXIO;
  625.   }
  626.  
  627.   return 0;
  628. }
  629.  
  630. /* IIC bus code ********************************************************/
  631.  
  632. static void newsat_iic_upload(struct newsat_softc *sc)
  633. {
  634.   newsat_MC2_set(sc, MC2_UPLOAD_IIC);
  635. }
  636.  
  637. static void newsat_iic_reset(struct newsat_softc *sc)
  638. {
  639.   int tries;
  640.  
  641.   for(tries = 0; tries < 1000; tries++) {
  642.     int c;
  643.  
  644.     for(c = 0; c < 4; c++) {
  645.       CHIPR32(SAA_IIC_STA) = (CHIPR32(SAA_IIC_STA) & 0xff) | IIC_ABORT;
  646.       newsat_iic_upload(sc);
  647.     }
  648.     for(c = 0; c < 4; c++) {
  649.       CHIPR32(SAA_IIC_STA) = (CHIPR32(SAA_IIC_STA) & ~0xff);
  650.       newsat_iic_upload(sc);
  651.     }
  652.  
  653.     if((CHIPR32(SAA_IIC_STA) & (IIC_ERR | IIC_BUSY)) == 0) {
  654.       return;
  655.     }
  656.   }
  657.   device_printf(sc->device, "iic reset failed, status 0x%.2x\n",
  658.         CHIPR32(SAA_IIC_STA));
  659. }
  660.  
  661. static int newsat_iic_wait(struct newsat_softc *sc)
  662. {
  663.   int tries;
  664.  
  665.   for(tries = 0; tries < 10000000; tries++) {
  666.     newsat_iic_upload(sc);
  667.     if((CHIPR32(SAA_IIC_STA) & IIC_BUSY) == 0)
  668.       return 0;
  669.     /*    tsleep(sc, PWAIT, "iic_wt", 1); */
  670.   }
  671.  
  672.   device_printf(sc->device, "iic bus timeout (error bit was %s)\n",
  673.         (CHIPR32(SAA_IIC_STA) & IIC_ERR) ? "set" : "clear");
  674.   return -1;
  675. }
  676.  
  677. static void newsat_iic_init(struct newsat_softc *sc)
  678. {
  679.   device_printf(sc->device, "iic init\n");
  680.   newsat_iic_reset(sc);
  681. }
  682.  
  683. static int newsat_iic_address(struct newsat_softc *sc, int dev, int flags)
  684. {
  685.   int rc;
  686.   CHIPR32(SAA_IIC_TRF) = IIC_BYTE2((dev << 1) | flags) | IIC_ATTR2(ATTR_START);
  687.   newsat_iic_upload(sc);
  688.  
  689.   if((rc = newsat_iic_wait(sc)) < 0) {
  690.     device_printf(sc->device, "IIC addressing error (status 0x%.8x)\n",
  691.           CHIPR32(SAA_IIC_STA));
  692.   }
  693.  
  694.   return rc;
  695. }
  696.  
  697. int newsat_iic_writeN(struct newsat_softc *sc, int dev, uint8_t *iic_data,
  698.               int nbytes, int flags)
  699. {
  700.   int ptr;
  701.  
  702.   if(newsat_iic_address(sc, dev, IIC_WRITE) < 0)
  703.     return IIC_ERR_ADDRESS;
  704.  
  705.   for(ptr = 0; ptr < nbytes; ptr++) {
  706.     if((ptr == (nbytes - 1)) && (flags & IIC_SEND_STOP))
  707.       CHIPR32(SAA_IIC_TRF) = IIC_BYTE2(iic_data[ptr]) | IIC_ATTR2(ATTR_STOP);
  708.     else
  709.       CHIPR32(SAA_IIC_TRF) = IIC_BYTE2(iic_data[ptr]) | IIC_ATTR2(ATTR_CONT);
  710.  
  711.     newsat_iic_upload(sc);
  712.     if(newsat_iic_wait(sc) < 0)
  713.       return IIC_ERR_DATA;
  714.   }
  715.   return 0;
  716. }
  717.  
  718. int newsat_iic_readN(struct newsat_softc *sc, int dev, uint8_t *iic_data,
  719.              int nbytes, int flags)
  720. {
  721.   int ptr;
  722.  
  723.   if(newsat_iic_address(sc, dev, IIC_READ) < 0)
  724.     return IIC_ERR_ADDRESS;
  725.  
  726.   for(ptr = 0; ptr < nbytes; ptr++) {
  727.     if((ptr == (nbytes - 1)) && (flags & IIC_SEND_STOP))
  728.       CHIPR32(SAA_IIC_TRF) = IIC_ATTR2(ATTR_STOP);
  729.     else
  730.       CHIPR32(SAA_IIC_TRF) = IIC_ATTR2(ATTR_CONT);
  731.  
  732.     newsat_iic_upload(sc);
  733.     if(newsat_iic_wait(sc) < 0)
  734.       return IIC_ERR_DATA;
  735.  
  736.     iic_data[ptr] = IIC_GET_BYTE2(CHIPR32(SAA_IIC_TRF));
  737.   }
  738.   return 0;
  739. }
  740.  
  741. /* Tuner code **********************************************************/
  742.  
  743. static int tuner_demod_write(struct newsat_softc *sc, int reg, int val)
  744. {
  745.   uint8_t data[3];
  746.   data[0] = 0;
  747.   data[1] = reg;
  748.   data[2] = val;
  749.   return newsat_iic_writeN(sc, VES_I2C_ADDR, (uint8_t *) &data, 3,
  750.                IIC_SEND_STOP);
  751. }
  752.  
  753. static int tuner_demod_read(struct newsat_softc *sc, int reg)
  754. {
  755.   int err;
  756.   uint8_t data[3];
  757.  
  758.   data[0] = 0;
  759.   data[1] = reg;
  760.   if((err = newsat_iic_writeN(sc, VES_I2C_ADDR, (uint8_t *) &data, 2, 0)) < 0)
  761.     return err;
  762.  
  763.   if((err = newsat_iic_readN(sc, VES_I2C_ADDR, (uint8_t *) &data, 1,
  764.                  IIC_SEND_STOP)) < 0)
  765.     return err;
  766.  
  767.   return data[0];
  768. }
  769.  
  770. static void tuner_demod_reset(struct newsat_softc *sc)
  771. {
  772.   newsat_regset(sc, SAA_GPIO, GPIO2_MASK, GPIO2(GPIO_LOW));
  773.   newsat_regset(sc, SAA_GPIO, GPIO2_MASK, GPIO2(GPIO_HIGH));
  774. }
  775.  
  776. static void tuner_demod_init(struct newsat_softc *sc)
  777. {
  778.   int n;
  779.   tuner_demod_reset(sc);
  780.  
  781.   for(n = 0; n < sizeof(VES_Reg); n++) {
  782.     if(VES_Reg_Mask[n])
  783.       tuner_demod_write(sc, n, VES_Reg[n]);
  784.   }
  785.   device_printf(sc->device, "VES1893 initialised\n");
  786. }
  787.  
  788. static int tuner_demod_status(struct newsat_softc *sc)
  789. {
  790.   return tuner_demod_read(sc, VES_SYNC);
  791. }
  792.  
  793. static int tuner_demod_sigmeter(struct newsat_softc *sc)
  794. {
  795.   return tuner_demod_read(sc, VES_NEST);
  796. }
  797.  
  798. static int tuner_demod_ber(struct newsat_softc *sc)
  799. {
  800.   int ber;
  801.   if((ber = tuner_demod_read(sc, VES_VBER_LSB)) < 0)
  802.     return -1;
  803.   ber |= tuner_demod_read(sc, VES_VBER_MID) << 8;
  804.   ber |= tuner_demod_read(sc, VES_VBER_MSB) << 16;
  805.   return ber;
  806. }
  807.  
  808. static int tuner_demod_afc(struct newsat_softc *sc)
  809. {
  810.   return ((64 + tuner_demod_read(sc, VES_VAFC)) % 128) - 64;
  811. }
  812.  
  813. #define REF_FREQ 90100000UL
  814.  
  815. static int tuner_demod_setbaud(struct newsat_softc *sc, int baud, int fec)
  816. {
  817.   uint32_t ves_bdr, ratio, tmp, fin;
  818.   uint8_t ves_adconf, ves_fconf, ves_fnr, ves_bdri;
  819.  
  820.   if((baud > (REF_FREQ / 2)) || (baud < 500000))
  821.     return ENXIO;
  822.  
  823. #define MUL (1UL << 26)
  824.     fin = REF_FREQ >> 4;
  825.     tmp = baud << 6;
  826.     ratio = tmp / fin;
  827.     tmp = (tmp % fin) << 8;
  828.     ratio = (ratio << 8) + tmp / fin;
  829.     tmp = (tmp % fin) << 8;
  830.     ratio = (ratio << 8) + tmp / fin;
  831.  
  832.     ves_fnr = 0xff;
  833.     if(ratio < MUL / 3)
  834.       ves_fnr = 0;
  835.     if(ratio < (MUL * 11) / 50)
  836.       ves_fnr = 1;
  837.     if(ratio < MUL / 6)
  838.       ves_fnr = 2;
  839.     if(ratio < MUL / 9)
  840.       ves_fnr = 3;
  841.     if(ratio < MUL / 12)
  842.       ves_fnr = 4;
  843.     if(ratio < (MUL * 11) / 200)
  844.       ves_fnr = 5;
  845.     if(ratio < MUL / 24)
  846.       ves_fnr = 6;
  847.     if(ratio < (MUL * 27) / 1000)
  848.       ves_fnr = 7;
  849.     if(ratio < MUL / 48)
  850.       ves_fnr = 8;
  851.     if(ratio < (MUL * 137) / 10000)
  852.       ves_fnr = 9;
  853.  
  854.     if(ves_fnr == 0xff) {
  855.       ves_adconf = 0x89; /* bypass filter */
  856.       ves_fconf = 0x80; /* default */
  857.       ves_fnr = 0;
  858.     } else {
  859.       ves_adconf = 0x81;
  860.       ves_fconf = 0x88 | (ves_fnr >> 1) | ((ves_fnr & 1) << 5);
  861.     }
  862.  
  863.     ves_bdr = (((ratio << (ves_fnr >> 1)) >> 4) + 1) >> 1;
  864.     ves_bdri = (((fin << 8) / ((baud << (ves_fnr >> 1)) >> 2)) + 1) >> 1;
  865.  
  866.     ves_bdri = (ves_bdri > 0xff) ? 0xff : ves_bdri;
  867.  
  868.     tuner_demod_write(sc, VES_ADCONF, ves_adconf);
  869.     tuner_demod_write(sc, VES_FCONF, ves_fconf);
  870.  
  871.     tuner_demod_write(sc, VES_BDR_INV, ves_bdri);
  872.     tuner_demod_write(sc, VES_BDR_MSB, ((ves_bdr >> 16) & 0x0f) | 0x00);
  873.     tuner_demod_write(sc, VES_BDR_MID, (ves_bdr >> 8) & 0xff);
  874.     tuner_demod_write(sc, VES_BDR_LSB, ves_bdr & 0xff);
  875.  
  876.     tuner_demod_write(sc, VES_AFC_0, 0x03);
  877.     tuner_demod_write(sc, VES_AFC_1, 0x03);
  878.  
  879. #if 0
  880.     tuner_demod_write(sc, VES_CARINIT, 0x00);
  881.     tsleep(sc, PWAIT, "demod", hz / 2);
  882.     tuner_demod_write(sc, VES_CARINIT, 0x80);
  883. #endif
  884.  
  885.     return 0;
  886. }
  887.  
  888. static void tuner_set_pol(struct newsat_softc *sc, int pol)
  889. {
  890.   tuner_demod_write(sc, VES_TEST, VESR_LNB_POWER_EN |
  891.             VESR_LNB_VOLTAGE_SEL(pol));
  892.   if(sc->tuner.pol != pol)
  893.     tsleep(sc, PWAIT, "polwt", hz / 10);
  894.   sc->tuner.pol = pol;
  895. }
  896.  
  897. static void tuner_set_band(struct newsat_softc *sc, int band)
  898. {
  899.   newsat_regset(sc, SAA_GPIO, GPIO3_MASK, GPIO3(band ? GPIO_HIGH : GPIO_LOW));
  900.   if(sc->tuner.band != band)
  901.     tsleep(sc, PWAIT, "bandwt", hz / 10);
  902.   sc->tuner.band = band;
  903. }
  904.  
  905. #define TUNER_PLL_ADDR 0x61
  906. #define TUNER_LO0 9750000 /* LO for 1st IF frequency sel 1 */
  907. #define TUNER_LO1 10600000 /* LO for 1st IF frequency sel 2 */
  908. #define TUNER_IF 480000 /* 2nd IF frequency */
  909. #define TUNER_MIN_FREQ 950000 /* lowest 1st IF freq. */
  910. #define TUNER_MAX_FREQ 2150000 /* highest 1st IF freq. */
  911. #define TUNER_PRESCL_FREQ 2000000 /* LO prescale switch point */
  912.  
  913. static float comptab[] = {  2000000, 1000000, 500000, 250000, 125000, 62500,
  914.               31250, 15625, 0, 800000, 400000, 200000, 100000,
  915.               50000, 25000, 12500 };
  916.  
  917. static int tuner_tuneto(struct newsat_softc *sc, int pol, int freq)
  918. {
  919.   int band, comp, prescl, prescl_en, count;
  920.   uint8_t iic_data[6];
  921.  
  922.   if(freq > (TUNER_LO0 + TUNER_MAX_FREQ)) {
  923.     band = 1;
  924.     freq -= TUNER_LO1;
  925.   } else {
  926.     band = 0;
  927.     freq -= TUNER_LO0;
  928.   }
  929.  
  930.   printf("band %d\n", band);
  931.   tuner_set_pol(sc, pol);
  932.   tuner_set_band(sc, band);
  933.  
  934.   freq += TUNER_IF;
  935.   prescl_en = freq > TUNER_PRESCL_FREQ;
  936.  
  937.   comp = 3;
  938.   /* FIXME */
  939.   prescl = (int) ((freq * 1000.0F) / comptab[comp]);
  940.  
  941.   printf("frequency %d prescl %d\n", freq, prescl);
  942.  
  943.   if(prescl_en) {
  944.     prescl /= 2;
  945.   }
  946.  
  947.   /* Program the PLL */
  948.   iic_data[0] = (prescl >> 8) & 0x7f;
  949.   iic_data[1] = prescl & 0xff;
  950.   iic_data[2] = (1 << 7) | (((prescl >> 15) & 3) << 5) |
  951.     (prescl_en << 4) | comp;
  952.   iic_data[3] = (1 << 6) | (1 << 5) | (1 << 4) | 0x0;
  953.  
  954.   if(newsat_iic_writeN(sc, TUNER_PLL_ADDR, (uint8_t *) &iic_data, 4,
  955.                IIC_SEND_STOP) < 0) {
  956.     device_printf(sc->device, "tuner PLL write error\n");
  957.     return EIO;
  958.   }
  959.  
  960.   for(count = 0; count < 100; count++) {
  961.     if(newsat_iic_readN(sc, TUNER_PLL_ADDR, (uint8_t *) &iic_data, 1,
  962.             IIC_SEND_STOP) < 0) {
  963.       device_printf(sc->device, "tuner PLL read error\n");
  964.       return EIO;
  965.     }
  966.     if(iic_data[0] & 0x40)
  967.       return 0;
  968.     tsleep(sc, PWAIT, "pllwt", hz / 10);
  969.   }
  970.  
  971.   device_printf(sc->device, "tuner PLL did not lock\n");
  972.   return ENXIO;
  973. }
  974.  
  975. static void tuner_init(struct newsat_softc *sc)
  976. {
  977.   tuner_demod_init(sc);
  978.  
  979.   sc->param.mod = 1;
  980.   /*
  981.   tuner_set_pol(sc, 0);
  982.   tuner_set_band(sc, 0);
  983.   tuner_tuneto(sc, 0, 12051 * 1000);
  984.   tuner_demod_setbaud(sc, 27500 * 1000, 8);
  985.   device_printf(sc->device, "tuner init\n");
  986.   printf("%x\n", tuner_demod_status(sc));
  987.   */
  988. }
  989.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement