diff -ur ../work.orig/dev/cxm/cxm.c dev/cxm/cxm.c --- ../work.orig/dev/cxm/cxm.c Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm.c Wed Aug 23 21:31:44 2006 @@ -87,6 +87,9 @@ #include +#include "v4l2_ioctl_hook.h" + +#include "wm8775.h" /* * Various supported device vendors/types and their names. @@ -353,6 +356,8 @@ &dvd_full_d1_pal_profile }; +int jan_fps; + static unsigned int cxm_queue_firmware_command( struct cxm_softc *sc, @@ -366,7 +371,7 @@ intrmask_t s; if (nparameters > CXM_MBX_MAX_PARAMETERS) { - printf("%s: too many parameters for mailbox\n", sc->name); + log(LOG_DEBUG,"%s: too many parameters for mailbox\n", sc->name); return -1; } @@ -387,7 +392,8 @@ return -1; } - s = spltty(); + if(!sc->inint) + s = spltty(); for (i = 0; i < CXM_MBX_FW_CMD_MAILBOXES; i++) { flags = CSR_READ_4(sc, mailbox @@ -421,7 +427,8 @@ } if (i >= CXM_MBX_FW_CMD_MAILBOXES) { - splx(s); + if(!sc->inint) + splx(s); return -1; } @@ -436,7 +443,8 @@ (void)CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, flags)); - splx(s); + if(!sc->inint) + splx(s); CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, command), cmd); CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, timeout), @@ -448,12 +456,13 @@ + offsetof(struct cxm_mailbox, parameters) + i * sizeof(u_int32_t), *(parameters + i)); - +#ifdef _nuniet_ for ( ; i < CXM_MBX_MAX_PARAMETERS; i++) CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, parameters) + i * sizeof(u_int32_t), 0); +#endif CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), CXM_MBX_FLAG_IN_USE | CXM_MBX_FLAG_DRV_DONE); @@ -495,7 +504,7 @@ mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd, parameters, nparameters); if (mailbox == -1) { - printf("%s: no free mailboxes\n", sc->name); + log(LOG_DEBUG,"%s: no free mailboxes\n", sc->name); return -1; } @@ -514,7 +523,7 @@ } if (i >= 100) { - printf("%s: timeout\n", sc->name); + log(LOG_DEBUG,"%s: timeout\n", sc->name); return -1; } @@ -556,7 +565,7 @@ } if (i >= 100) { - printf("%s: no free mailboxes\n", sc->name); + log(LOG_DEBUG,"%s: no free mailboxes\n", sc->name); return -1; } @@ -575,7 +584,7 @@ } if (i >= 100) { - printf("%s: timeout\n", sc->name); + log(LOG_DEBUG,"%s: timeout\n", sc->name); return -1; } @@ -620,6 +629,7 @@ static void cxm_set_irq_mask( struct cxm_softc *sc, u_int32_t mask ) { +/* userland! */ intrmask_t s; s = spltty(); @@ -661,10 +671,12 @@ { if (sc->cxm_iic) { +#ifdef _nuniet_ if (cxm_saa7115_mute(sc) < 0) return -1; if (cxm_msp_mute(sc) < 0) return -1; +#endif } /* Halt the firmware */ @@ -811,7 +823,7 @@ ¶meter, 1) < 0) return -1; - printf("%s: encoder firmware version %#x\n", + log(LOG_DEBUG,"%s: encoder firmware version %#x\n", sc->name, (unsigned int)parameter); /* Get decoder firmware version */ @@ -822,14 +834,13 @@ ¶meter, 1) < 0) return -1; - printf("%s: decoder firmware version %#x\n", + log(LOG_DEBUG,"%s: decoder firmware version %#x\n", sc->name, (unsigned int)parameter); } return 0; } - static int cxm_configure_encoder( struct cxm_softc *sc ) { @@ -838,7 +849,7 @@ u_int32_t parameters[12]; const struct cxm_codec_profile *cpp; - if (sc->source == cxm_fm_source) + if (1 || sc->source == cxm_fm_source) switch (cxm_tuner_selected_channel_set(sc)) { case CHNLSET_NABCST: case CHNLSET_CABLEIRC: @@ -854,8 +865,12 @@ else fps = cxm_saa7115_detected_fps(sc); + if (fps < 0) - return -1; + { + log(LOG_DEBUG,"Could not detect FPS\n"); + return -1; + } if (sc->profile->fps != fps) { @@ -879,11 +894,12 @@ } cpp = sc->profile; - +/* if (cxm_saa7115_configure(sc, cpp->width, cpp->source_height, fps, cpp->audio_sample_rate) < 0) return -1; +*/ /* assign dma block len */ parameters[0] = 1; /* Transfer block size = 1 */ @@ -1090,17 +1106,26 @@ u_int32_t type; if (sc->encoding) + { + log(LOG_DEBUG,"already encoding\n"); return 0; + } if (cxm_configure_encoder(sc) < 0) + { + log(LOG_DEBUG,"could not config dec\n"); return -1; + } /* Mute the video input if necessary. */ parameters[0] = sc->source == cxm_fm_source ? 1 : 0; if (cxm_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_MUTE_VIDEO_INPUT, parameters, 1) != 0) + { + log(LOG_DEBUG,"could not mute vid inp\n"); return -1; + } /* Clear pending encoder interrupts (which are currently masked) */ cxm_set_irq_status(sc, CXM_IRQ_ENC); @@ -1113,22 +1138,39 @@ if (cxm_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_ENC_EVENT_NOTIFICATION, parameters, 4) != 0) + { + log(LOG_DEBUG,"could not act evt not\n"); return -1; + } +#ifdef _nuniet_ if (cxm_saa7115_mute(sc) < 0) return -1; if (cxm_msp_mute(sc) < 0) return -1; +#endif if (cxm_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_INITIALIZE_VIDEO_INPUT, NULL, 0) < 0) + { + log(LOG_DEBUG,"could not init vid inp\n"); return -1; + } +#ifdef _nuniet_ if (cxm_saa7115_unmute(sc) < 0) return -1; if (cxm_msp_unmute(sc) < 0) return -1; +#endif + + cx25840_command(sc->iicbus, VIDIOC_STREAMOFF, NULL); + +cxm_firmware_command(sc,cxm_enc_mailbox, 0xcd, NULL, 0); + + cx25840_command(sc->iicbus, VIDIOC_STREAMON, NULL); + /* Wait for 100ms */ (void)tsleep(&sc->encoding, PWAIT, "cxmce", hz / 10); @@ -1145,7 +1187,10 @@ parameters[1] = subtype; if (cxm_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_BEGIN_CAPTURE, parameters, 2) != 0) + { + log(LOG_DEBUG,"could not begin capt\n"); return -1; + } sc->enc_pool.offset = 0; sc->enc_pool.read = 0; @@ -1154,6 +1199,7 @@ sc->encoding_eos = 0; sc->encoding = 1; + sc->inint = 0; /* Enable interrupts */ cxm_set_irq_mask(sc, sc->irq_mask & ~CXM_IRQ_ENC); @@ -1165,10 +1211,12 @@ static int cxm_stop_encoder( struct cxm_softc *sc ) { +/* userland! */ u_int32_t parameters[4]; u_int32_t subtype; u_int32_t type; intrmask_t s; + if (! sc->encoding ) return 0; @@ -1191,11 +1239,13 @@ /* Wait for up to 1 second */ s = spltty(); if (! sc->encoding_eos ) + { (void)tsleep(&sc->encoding_eos, PWAIT, "cxmeos", hz); + } splx(s); if (sc->mpeg && ! sc->encoding_eos ) - printf("%s: missing encoder EOS\n", sc->name); + log(LOG_DEBUG,"%s: missing encoder EOS\n", sc->name); /* Disable event notification */ parameters[0] = 0; /* Event = 0 (refresh encoder input) */ @@ -1257,9 +1307,9 @@ unsigned int macroblocks_per_line; unsigned int scratch; unsigned int words_per_line; - u_int32_t *ptr; + u_int32_t *ptr, *ptr_end; u_int32_t *src; - size_t nbytes; + /* size_t nbytes; */ switch (sc->enc_pool.bufs[current].byte_order) { case cxm_device_mpeg_byte_order: @@ -1267,17 +1317,23 @@ /* * Convert each 32 bit word to the proper byte ordering. */ - +#ifdef _nunieT_ for (nbytes = 0, ptr = (u_int32_t *)sc->enc_pool.bufs[current].vaddr; nbytes != sc->enc_pool.bufs[current].size; nbytes += sizeof(*ptr), ptr++) *ptr = bswap32(*ptr); - +#else + ptr = (u_int32_t *)sc->enc_pool.bufs[current].vaddr ; + ptr_end = ptr + ( sc->enc_pool.bufs[current].size / sizeof(u_int32_t) ); + + for(;ptr < ptr_end;ptr++) + *ptr = bswap32(*ptr); +#endif break; case cxm_device_yuv12_byte_order: - +log(LOG_DEBUG,"yuv!\n"); /* * Convert each macro block to planar using * a scratch buffer (the buffer prior to the @@ -1349,12 +1405,12 @@ if (cxm_queue_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_SCHED_DMA_TO_HOST, parameters, 3) == -1) { - printf("%s: failed to discard encoder dma request\n", + log(LOG_DEBUG,"%s: failed to discard encoder dma request\n", sc->name); return; } - sc->encoding_dma = -1; + sc->encoding_dma = 0; /* was -1 ?? */ } @@ -1363,10 +1419,11 @@ { int buffers_pending; u_int32_t status; - intrmask_t s; + /* unsigned int buffers_available; */ + /* intrmask_t s; */ if (! sc->encoding_dma) { - printf("%s: encoder dma not already in progress\n", + log(LOG_DEBUG,"%s: encoder dma not already in progress\n", sc->name); return; } @@ -1382,23 +1439,31 @@ if ((status & (CXM_DMA_ERROR_LIST | CXM_DMA_ERROR_WRITE | CXM_DMA_SUCCESS)) != CXM_DMA_SUCCESS) { - printf("%s: encoder dma status %#x\n", + log(LOG_DEBUG,"%s: encoder dma status %#x\n", sc->name, (unsigned int)status); return; } /* Update the books (spl is used since mutex is not available) */ - s = spltty(); +/* s = spltty(); */ sc->enc_pool.write = (sc->enc_pool.write + buffers_pending) % CXM_SG_BUFFERS; - splx(s); + /* splx(s); */ /* signal anyone requesting notification */ if (sc->enc_proc) psignal (sc->enc_proc, sc->enc_signal); - /* wakeup anyone waiting for data */ - wakeup(&sc->enc_pool.read); + /* wakeup anyone waiting for data +buffers_available = sc->enc_pool.write - sc->enc_pool.read; + if (buffers_available < 0) + buffers_available += CXM_SG_BUFFERS; + + if(buffers_available >= sc->buffers_requested) + { + sc->buffers_requested = 0; */ + wakeup(&sc->enc_pool.read); + /* } */ /* wakeup anyone polling for data */ selwakeup(&sc->enc_sel); @@ -1424,10 +1489,10 @@ size_t offset; size_t size; } requests[2]; - intrmask_t s; + /* intrmask_t s; */ if (sc->encoding_dma) { - printf("%s: encoder dma already in progress\n", + log(LOG_DEBUG,"%s: encoder dma already in progress\n", sc->name); cxm_encoder_dma_discard(sc); return; @@ -1436,12 +1501,11 @@ mailbox = sc->enc_mbx + CXM_MBX_FW_DMA_MAILBOX * sizeof(struct cxm_mailbox); - for (i = 0; i < CXM_MBX_MAX_PARAMETERS; i++) - parameters[i] + parameters[0] = CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, parameters) - + i * sizeof(u_int32_t)); + + 0 * sizeof(u_int32_t)); byte_order = cxm_device_mpeg_byte_order; max_sg_segment = CXM_SG_SEGMENT; @@ -1450,11 +1514,25 @@ switch (type) { case 0: /* MPEG */ + for (i = 1; i < 3/* CXM_MBX_MAX_PARAMETERS */; i++) + parameters[i] + = CSR_READ_4(sc, + mailbox + + offsetof(struct cxm_mailbox, parameters) + + i * sizeof(u_int32_t)); + requests[nrequests].offset = parameters[1]; requests[nrequests++].size = parameters[2]; break; case 1: /* YUV */ + for (i = 1; i < 5/* CXM_MBX_MAX_PARAMETERS */; i++) + parameters[i] + = CSR_READ_4(sc, + mailbox + + offsetof(struct cxm_mailbox, parameters) + + i * sizeof(u_int32_t)); + byte_order = cxm_device_yuv12_byte_order; /* @@ -1482,7 +1560,7 @@ case 2: /* PCM (audio) */ case 3: /* VBI */ default: - printf("%s: encoder dma type %#x unsupported\n", + log(LOG_DEBUG,"%s: encoder dma type %#x unsupported\n", sc->name, (unsigned int)type); cxm_encoder_dma_discard(sc); return; @@ -1492,11 +1570,11 @@ * Determine the number of buffers free at this * instant * * taking into consideration that the ring buffer wraps. */ - s = spltty(); + /* s = spltty(); */ buffers_free = sc->enc_pool.read - sc->enc_pool.write; if (buffers_free <= 0) buffers_free += CXM_SG_BUFFERS; - splx(s); + /* splx(s); */ /* * Build the scatter / gather list taking in @@ -1508,10 +1586,11 @@ buffers_pending = 0; current = sc->enc_pool.write; + /* splx(s); */ for (i = 0; i < nrequests; i++) { if (! requests[i].size ) { - printf("%s: encoder dma size is zero\n", sc->name); + log(LOG_DEBUG,"%s: encoder dma size is zero\n", sc->name); cxm_encoder_dma_discard(sc); return; } @@ -1536,7 +1615,7 @@ current = (current + 1) % CXM_SG_BUFFERS; if (buffers_pending >= buffers_free) { - printf( + log(LOG_DEBUG, "%s: encoder dma not enough buffer space free\n", sc->name); cxm_encoder_dma_discard(sc); @@ -1555,7 +1634,7 @@ if (cxm_queue_firmware_command(sc, cxm_enc_mailbox, CXM_FW_CMD_SCHED_DMA_TO_HOST, parameters, 3) == -1) { - printf("%s: failed to schedule encoder dma request\n", + log(LOG_DEBUG,"%s: failed to schedule encoder dma request\n", sc->name); return; } @@ -1575,7 +1654,7 @@ static int cxm_encoder_wait_for_lock( struct cxm_softc *sc ) { - int muted; + /* int muted; */ int locked; int result; @@ -1590,6 +1669,7 @@ return result; } +#ifdef _nuniet_ /* * Wait for the video decoder to lock. */ @@ -1616,6 +1696,7 @@ if (muted == 0 && cxm_msp_unmute(sc) < 0) return -1; } +#endif return locked; } @@ -1678,6 +1759,8 @@ unit = device_get_unit(dev); sc->type = cxm_iTVC15_type; + sc->inint =0; + switch(pci_get_device(dev)) { case CXM_DEVICEID_CONEXANT_iTVC16: sc->type = cxm_iTVC16_type; @@ -1737,6 +1820,7 @@ goto fail; } + /* * Initialize the tuner. */ @@ -1746,6 +1830,7 @@ goto fail; } +#ifdef _nuniet_ /* * Initialize the SAA7115. */ @@ -1772,6 +1857,33 @@ error = ENXIO; goto fail; } +#endif + + cx25840_initialize(sc->iicbus,1); + tda9887_initialize(sc->iicbus); + wm8775_init(sc->iicbus); + + { int jan = 0; + + /* set the standard */ + if(cxm_eeprom_get_std(sc)) + { + device_printf(dev,"Eeprom NTSC\n"); + jan = V4L2_STD_NTSC_M; + } + else + { + device_printf(dev,"Eeprom PAL\n"); + jan = V4L2_STD_PAL; + } + + tda9887_command(sc->iicbus, VIDIOC_S_STD , &jan); + cx25840_command(sc->iicbus, VIDIOC_S_STD , &jan); + } + + DELAY(100000); + + cx25840_command(sc->iicbus, VIDIOC_LOG_STATUS,NULL); sc->dec_mbx = -1; sc->enc_mbx = -1; @@ -1922,6 +2034,9 @@ goto fail; } +if(cxm_eeprom_get_std(sc)) + sc->profile = &dvd_full_d1_pal_profile; +else sc->profile = &dvd_full_d1_ntsc_profile; sc->source = cxm_tuner_source; @@ -2074,12 +2189,17 @@ /* Get the device data */ sc = (struct cxm_softc *)arg; + sc->inint = 1; + status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS); status &= ~sc->irq_mask; if (! status ) + { + sc->inint = 0; return; + } /* Process DMA done before handling a new DMA request or EOS */ if (status & CXM_IRQ_ENC_DMA_DONE) @@ -2093,6 +2213,8 @@ wakeup(&sc->encoding_eos); } + sc->inint = 0; + cxm_set_irq_status(sc, status); } @@ -2190,6 +2312,7 @@ int unit; struct cxm_softc *sc; + unit = UNIT( minor(dev) ); /* Get the device data */ @@ -2199,15 +2322,17 @@ return ENXIO; } - if (sc->is_opened) - return EBUSY; + /* if (sc->is_opened) + return EBUSY; */ - sc->is_opened = 1; + sc->is_opened++; sc->mpeg = 1; /* Record that the device is now busy */ - device_busy(devclass_get_device(cxm_devclass, unit)); + if(sc->is_opened==1) + device_busy(devclass_get_device(cxm_devclass, unit)); +log(LOG_DEBUG,"device %s opened\n", sc->name); return 0; } @@ -2254,12 +2379,16 @@ int cxm_read( dev_t dev, struct uio *uio, int flag ) { +/* userland! */ int buffers_available; int buffers_read; int error; int unit; unsigned int current; - unsigned int i; +/* unsigned int i; */ + unsigned int encread; +/* unsigned int br; */ + /*unsigned int uior; */ size_t nbytes; size_t offset; struct cxm_softc *sc; @@ -2277,38 +2406,50 @@ /* Only trigger the encoder if the ring buffer is empty */ if (! sc->encoding && sc->enc_pool.read == sc->enc_pool.write) { if (cxm_start_encoder(sc) < 0) + { + log(LOG_DEBUG,"could not start encoder\n"); return ENXIO; + } if (flag & IO_NDELAY) return EWOULDBLOCK; } - +#ifdef _nuniet_ buffers_available = 0; - s = spltty(); - while (sc->enc_pool.read == sc->enc_pool.write) { + s = spltty(); + + buffers_available = sc->enc_pool.write - sc->enc_pool.read; + if (buffers_available < 0) + buffers_available += CXM_SG_BUFFERS; + + uior = uio->uio_resid; + br = sc->buffers_requested = uio->uio_resid / CXM_SG_SEGMENT; + + while (buffers_available < sc->buffers_requested) { /* )sc->enc_pool.read = sc->enc_pool.write) { */ error = tsleep(&sc->enc_pool.read, PZERO | PCATCH, "cmxrd", 0); + + buffers_available = sc->enc_pool.write - sc->enc_pool.read; + if (buffers_available < 0) + buffers_available += CXM_SG_BUFFERS; + if (error) { splx(s); return error; } } - /* - * Determine the number of buffers available at this * instant * - * taking in consideration that the ring buffer wraps. - */ - buffers_available = sc->enc_pool.write - sc->enc_pool.read; - if (buffers_available < 0) - buffers_available += CXM_SG_BUFFERS; + offset = sc->enc_pool.offset; + encread = sc->enc_pool.read; splx(s); - offset = sc->enc_pool.offset; - - for (buffers_read = 0, i = sc->enc_pool.read; + for (buffers_read = 0, i = encread; buffers_read != buffers_available && uio->uio_resid; buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) { - current = cxm_encoder_fixup_byte_order (sc, i, offset); + if(!offset) + current = cxm_encoder_fixup_byte_order (sc, i, offset); + else + current = i; nbytes = sc->enc_pool.bufs[current].size - offset; @@ -2328,20 +2469,85 @@ break; offset = 0; + s = spltty(); + sc->enc_pool.read = ( sc->enc_pool.read + 1 ) % CXM_SG_BUFFERS; + splx(s); } - - sc->enc_pool.offset = offset; +if(offset) + log(LOG_DEBUG,"offset = %d, bufs_req = %d, uio_req = %d\n",offset,br,uior); /* Update the books (spl is used since mutex is not available) */ - s = spltty(); - sc->enc_pool.read = (sc->enc_pool.read + buffers_read) - % CXM_SG_BUFFERS; - splx(s); + /* s = spltty(); */ + sc->enc_pool.offset = offset; + + /* sc->enc_pool.read = (sc->enc_pool.read + buffers_read) + % CXM_SG_BUFFERS; */ + /* splx(s); */ +#else + buffers_read = 0; + do { + s = spltty(); + encread = sc->enc_pool.read = (sc->enc_pool.read + buffers_read) % CXM_SG_BUFFERS; + buffers_read = 0; + buffers_available = sc->enc_pool.write - sc->enc_pool.read; + offset = sc->enc_pool.offset; + splx(s); + if (buffers_available < 0) + buffers_available += CXM_SG_BUFFERS; + + if(!uio->uio_resid) + { + break; + } + + if(buffers_available == 0) + { + error = tsleep(&sc->enc_pool.read, PZERO | PCATCH, "cmxrd", 0); + + if(error) + return error; + else + continue; + } + else + { + current = cxm_encoder_fixup_byte_order (sc, encread, offset); + + nbytes = sc->enc_pool.bufs[current].size - offset; + + /* Don't transfer more than requested */ + if (nbytes > uio->uio_resid) + nbytes = uio->uio_resid; + + error = uiomove(sc->enc_pool.bufs[current].vaddr + offset, + nbytes, uio); + + if (error) + return error; + + offset += nbytes; + + /* Handle a partial read of a buffer */ + if (! uio->uio_resid && offset != sc->enc_pool.bufs[current].size) + { + sc->enc_pool.offset = offset; + /* no need to update the books! */ + break; + } + + sc->enc_pool.offset = offset = 0; + buffers_read = 1; + } + } while(1); +#endif + return 0; } +#include "v4l2_ioctl_hook.c" + /* * */ @@ -2736,11 +2942,22 @@ switch (*(unsigned long *)arg & 0xf000) { case METEOR_INPUT_DEV1: +printf("tuner input\n"); source = cxm_tuner_source; break; case METEOR_INPUT_DEV2: +{ +int arg; source = cxm_line_in_source_composite; +arg=AUDIO_EXTERN_1; +cx25840_command(sc->iicbus, AUDC_SET_INPUT,&arg); +wm8775_command(sc->iicbus, AUDC_SET_INPUT,&arg); + + +arg=CX25840_COMPOSITE0; +cx25840_command(sc->iicbus, VIDIOC_S_INPUT, &arg); +} break; case METEOR_INPUT_DEV_SVIDEO: @@ -2766,11 +2983,12 @@ if (cxm_pause_encoder(sc) < 0) return ENXIO; - +/* if (cxm_saa7115_select_source(sc, source) < 0) return ENXIO; if (cxm_msp_select_source(sc, source) < 0) return ENXIO; +*/ sc->source = source; @@ -2866,9 +3084,10 @@ break; case TVTUNER_SETCHNL: +/* if (sc->source == cxm_tuner_source) if (cxm_pause_encoder(sc) < 0) - return ENXIO; + return ENXIO; */ if (cxm_tuner_select_channel(sc, *(unsigned int *)arg) < 0) return ENXIO; @@ -2881,6 +3100,7 @@ * Explicitly wait for the tuner lock so we * can indicate if there's a station present. */ +/* if (cxm_tuner_wait_for_lock(sc) < 0) return EINVAL; @@ -2888,11 +3108,11 @@ if (result < 0) return ENXIO; else if (result == 0) - return EINVAL; - + return EINVAL; */ +/* if (sc->source == cxm_tuner_source) if (cxm_unpause_encoder(sc) < 0) - return ENXIO; + return ENXIO; */ break; case TVTUNER_GETFREQ: @@ -2930,6 +3150,8 @@ if (sc->source == cxm_tuner_source) if (cxm_unpause_encoder(sc) < 0) return ENXIO; + + cx25840_command(sc->iicbus, VIDIOC_LOG_STATUS,NULL); break; case TVTUNER_GETSTATUS: @@ -2946,7 +3168,7 @@ break; default: - return ENOTTY; + return v4l2_ioctl_hook(sc,cmd,arg); } return 0; diff -ur ../work.orig/dev/cxm/cxm.h dev/cxm/cxm.h --- ../work.orig/dev/cxm/cxm.h Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm.h Wed Aug 23 20:45:59 2006 @@ -33,6 +33,15 @@ * Header file for the Conexant MPEG-2 Codec driver. */ +#ifndef _cxm_h +#define _cxm_h + +#if __FreeBSD_version >= 500014 +# include +#else +# include +#endif + #if __FreeBSD_version >= 503001 # define dev_t struct cdev * #endif @@ -64,7 +73,7 @@ enum cxm_byte_order byte_order; }; -#define CXM_SG_BUFFERS 50 +#define CXM_SG_BUFFERS 16 struct cxm_buffer_pool { bus_dma_tag_t dmat; @@ -183,7 +192,8 @@ * that the size of each piece must be a multiple of * 256 and less than 64k. */ -#define CXM_SG_SEGMENT (0xff00 & ~(PAGE_SIZE - 1)) +#define CXM_SG_SEGMENT 32768 +/* (0xff00 & ~(PAGE_SIZE - 1)) */ struct cxm_sg_entry { u_int32_t src; @@ -243,6 +253,8 @@ unsigned int dec_mbx; unsigned int enc_mbx; + unsigned int inint; + unsigned int buffers_requested; device_t cxm_iic; device_t iicbus; @@ -266,6 +278,7 @@ int encoding; int encoding_dma; int encoding_eos; + int tuner_signal; }; /* @@ -434,7 +447,7 @@ #define CXM_FW_CAPTURE_STREAM_PCM_AUDIO 0x00000002 #define CXM_FW_CAPTURE_STREAM_VBI 0x00000004 -#define CXM_FW_STREAM_TYPE_DVD 0x0000000a +#define CXM_FW_STREAM_TYPE_DVD 0x0000000e #define CXM_FW_STREAM_TYPE_MPEG1 0x00000002 #define CXM_FW_STREAM_TYPE_MPEG2_PROGRAM 0x00000000 #define CXM_FW_STREAM_TYPE_SVCD 0x0000000c @@ -463,6 +476,7 @@ */ int cxm_eeprom_init( struct cxm_softc *sc ); int cxm_eeprom_tuner_type( struct cxm_softc *sc ); +int cxm_eeprom_get_std( struct cxm_softc *sc ); /* * Infrared remote @@ -521,8 +535,9 @@ #define CXM_TUNER_LG_TAPE_H001F 18 #define CXM_TUNER_MICROTUNE_4049_FM5 19 #define CXM_TUNER_TCL_2002N_6A 20 +#define CXM_TUNER_SAMSUNG 21 -#define CXM_TUNER_TYPES 21 +#define CXM_TUNER_TYPES 22 #define CXM_TUNER_AFC_MASK 0x07 @@ -656,3 +671,5 @@ int cxm_saa7115_set_hue( struct cxm_softc *sc, unsigned char hue ); int cxm_saa7115_is_locked( struct cxm_softc *sc ); int cxm_saa7115_wait_for_lock( struct cxm_softc *sc ); + +#endif /* cmx_h */ diff -ur ../work.orig/dev/cxm/cxm_eeprom.c dev/cxm/cxm_eeprom.c --- ../work.orig/dev/cxm/cxm_eeprom.c Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm_eeprom.c Sun Aug 27 15:31:24 2006 @@ -112,6 +112,16 @@ return 0; } +static unsigned int sup_std[4]; + +int cxm_eeprom_get_std( struct cxm_softc *sc ) +{ + int dev_num; + + dev_num = device_get_unit(sc->iicbus); + + return sup_std[dev_num] == 8; /* returns true if ntsc */ +} int cxm_eeprom_tuner_type( struct cxm_softc *sc ) @@ -122,6 +132,11 @@ unsigned int subsystem_vendor_id; unsigned int tuner_code; int tuner_type; +int dev_num; +int beenhere; +beenhere = 0; + +dev_num = device_get_unit(sc->iicbus); if (cxm_eeprom_read(sc->iicbus, CXM_I2C_EEPROM, eeprom, sizeof(eeprom), 0) != sizeof(eeprom)) @@ -154,7 +169,7 @@ } else if ((eeprom[i] & 0xf0) == 0x70) { if (eeprom[i] & 0x08) - break; + break; len = eeprom[i] & 0x07; i++; } @@ -174,11 +189,20 @@ switch (eeprom[i]) { case 0x00: - tuner_code = eeprom[i + 6]; + tuner_code = eeprom[i + 6]; + sup_std[dev_num] = eeprom[i + 5]; break; case 0x0a: - tuner_code = eeprom[i + 2]; +if(beenhere==0) +{ + tuner_code = eeprom[i + 2]; /* + 2 */ + sup_std[dev_num] = eeprom[i + 1]; +beenhere = 1; +} +else +printf("second(radio) tuner %d\n",(int)eeprom[i+2]); + break; default: @@ -186,6 +210,8 @@ } } +printf("tuner code %d\n",tuner_code); + switch (tuner_code) { case 0x03: /* Philips FI1216 */ case 0x08: /* Philips FI1216 MK2 */ @@ -196,6 +222,8 @@ tuner_type = CXM_TUNER_PHILIPS_FQ1216ME; break; +case 0x69: +case 0x5b: case 0x37: /* Philips FQ1216ME MK3 */ tuner_type = CXM_TUNER_PHILIPS_FQ1216ME_MK3; break; @@ -271,6 +299,9 @@ case 0x13: /* Philips FR1246 MK2 */ case 0x18: /* Philips FM1246 */ tuner_type = CXM_TUNER_PHILIPS_FM1246; + break; + case 0x57: + tuner_type = CXM_TUNER_SAMSUNG; break; default: diff -ur ../work.orig/dev/cxm/cxm_extract_fw.c dev/cxm/cxm_extract_fw.c --- ../work.orig/dev/cxm/cxm_extract_fw.c Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm_extract_fw.c Wed Aug 23 18:03:59 2006 @@ -65,11 +65,18 @@ char outfile[MAXPATHLEN]; size_t i; +#ifdef _nuniet_ if (nbytes < (256 * 1024)) { fprintf (stderr, "%s: save_firmware -- firmware image isn't long enough\n", MyName); return -1; } +#endif + + if(nbytes> ( 256*1024)) + { + nbytes=256*1024; + } if (snprintf (outfile, sizeof (outfile), "%s.c", name) >= sizeof (outfile)) { fprintf (stderr, "%s: save_firmware -- firmware name is too long\n", @@ -86,10 +93,10 @@ fprintf (ofp, "#include \n" "\n" - "const u_int8_t %s[] __attribute__ ((aligned(4))) = {", + "u_int8_t %s[] __attribute__ ((aligned(4))) = {", name); - for (i = 0; i < (256 * 1024); i++) { + for (i = 0; i < nbytes; i++) { if (i) fputc (',', ofp); if ((i % 8) == 0) @@ -167,6 +174,9 @@ close (fd); + +if(statbuf.st_size > 100000) +{ decoder_fw_saved = 0; encoder_fw_saved = 0; @@ -199,17 +209,23 @@ exit (1); } } +} +else +{ +/* must be cx25840-file */ +save_firmware ("cx25840_fw", start, statbuf.st_size); +} munmap ((caddr_t)start, (size_t)statbuf.st_size); - +/* if (! decoder_fw_saved) fprintf (stderr, "%s: decoder image not present\n", MyName); if (! encoder_fw_saved) fprintf (stderr, "%s: encoder image not present\n", MyName); - if (! decoder_fw_saved || ! encoder_fw_saved) exit (1); +*/ exit (0); } diff -ur ../work.orig/dev/cxm/cxm_i2c.c dev/cxm/cxm_i2c.c --- ../work.orig/dev/cxm/cxm_i2c.c Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm_i2c.c Wed Aug 23 21:13:52 2006 @@ -375,6 +375,7 @@ */ (void)CSR_READ_4(sc, CXM_REG_I2C_SETSCL); + } @@ -396,6 +397,7 @@ */ (void)CSR_READ_4(sc, CXM_REG_I2C_SETSDA); + } @@ -408,6 +410,6 @@ cxm_iic_setsda(dev, data); /* Wait for 10 usec */ - DELAY(10); + DELAY(5); } #endif diff -ur ../work.orig/dev/cxm/cxm_tuner.c dev/cxm/cxm_tuner.c --- ../work.orig/dev/cxm/cxm_tuner.c Fri Sep 1 23:10:08 2006 +++ dev/cxm/cxm_tuner.c Wed Aug 23 22:56:51 2006 @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2003, 2004, 2005 + /* Copyright (c) 2003, 2004, 2005 * John Wehle . All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -314,6 +313,7 @@ 0, 0, { 0 }, &l_air_channels }, + { "Philips FQ1216ME MK3", { CXM_TUNER_TV_SYSTEM_BG | CXM_TUNER_TV_SYSTEM_DK | CXM_TUNER_TV_SYSTEM_I @@ -507,6 +507,15 @@ { 55250, { 0x8e, 0x01 } } }, 0, 0, { 0 }, + &us_cable_channels }, + { "Samsung TCPN 2121P30A", + { CXM_TUNER_TV_SYSTEM_MN, cxm_none_system_code_style }, + 55250, 801250, + { { 364500, { 0xce, 0x08 } }, + { 130000, { 0xce, 0x02 } }, + { 55250, { 0xce, 0x01 } } }, + 0, 0, + { 0 }, &us_cable_channels } }; @@ -517,7 +526,7 @@ { int received; - if (iicbus_start(iicbus, i2c_addr + 1, CXM_I2C_TIMEOUT) != 0) + if (iicbus_start(iicbus, i2c_addr + 1 , CXM_I2C_TIMEOUT) != 0) return -1; if (iicbus_read(iicbus, buf, len, &received, IIC_LAST_READ, 0) != 0) @@ -562,10 +571,14 @@ int tuner_type; if (cxm_eeprom_init(sc) < 0) +{ +printf("could not init tuner\n"); return -1; +} tuner_type = cxm_eeprom_tuner_type(sc); +printf("tuner_type = %d\n",tuner_type); if (tuner_type < 0 || tuner_type >= NUM_ELEMENTS(cxm_tuners)) return -1; @@ -575,10 +588,16 @@ if (cxm_tuner_read(sc->iicbus, CXM_I2C_TUNER, &status, sizeof(status)) != sizeof(status)) +{ +printf("could not read tuner\n"); return -1; +} - if (cxm_tuner_select_channel(sc, 4) < 0) + if (cxm_tuner_select_channel(sc, 3) < 0) +{ +printf("could not select channel\n"); return -1; +} printf("%s: %s tuner\n", sc->name, sc->tuner->name); @@ -737,18 +756,17 @@ for (band_code = sc->tuner->band_codes; band_code->freq > freq; band_code++) ; - if (freq >= sc->tuner_freq) { - msg[0] = (unsigned char)(N >> 8); - msg[1] = (unsigned char)N; + msg[0] = (unsigned char)(N >> 8) & 0x7f; + msg[1] = (unsigned char)N & 0xff; msg[2] = band_code->codes[0]; msg[3] = band_code->codes[1] | pb; } else { msg[0] = band_code->codes[0]; msg[1] = band_code->codes[1] | pb; - msg[2] = (unsigned char)(N >> 8); - msg[3] = (unsigned char)N; + msg[2] = (unsigned char)(N >> 8) & 0x7f; + msg[3] = (unsigned char)N & 0xff; } msg[4] = aux; break; @@ -758,25 +776,35 @@ } if (N > 32767) +{ +printf("N bigger than int\n"); return -1; +} if (cxm_tuner_write(sc->iicbus, CXM_I2C_TUNER, msg, tuner_msg_len) - != tuner_msg_len) + != (tuner_msg_len)) +{ +printf("write to tuner failed\n"); return -1; +} /* * Program the IF processing after the tuner since some tuners * use the control byte to set the address of the IF. */ - if (system_code) { + if (0 && system_code) { +printf("sending system code\n"); msg[0] = 0x00; msg[1] = system_code->codes[0]; msg[2] = system_code->codes[1]; msg[3] = system_code->codes[2]; if (cxm_tuner_write(sc->iicbus, CXM_I2C_TUNER_IF, msg, 4) != 4) +{ +printf("system code sent failed\n"); return -1; +} } sc->tuner_freq = freq; @@ -797,14 +825,20 @@ if (! channels || channel < channels->min_channel || channel > channels->max_channel) +{ +printf("channel out of range\n"); return -1; +} for (assignments = channels->assignments; assignments->channel > channel; assignments++) ; if (! assignments->freq) +{ +printf("no freq\n"); return -1; +} freq = assignments->freq + (channel - assignments->channel) * assignments->step; @@ -824,6 +858,7 @@ unsigned long prev_freq; unsigned long step_size; +printf("in afc\n"); if (cxm_tuner_wait_for_lock(sc) != 1) return -1; @@ -835,13 +870,20 @@ step_size = 63; for (i = 0; i < (max_offset / step_size); i++) { +printf("afc stepping\n"); status = cxm_tuner_status(sc); if (status == -1) +{ +printf("afc sattus =1\n"); break; +} if (! (status & CXM_TUNER_PHASE_LOCKED) ) +{ +printf("afc pl\n"); break; +} switch (status & CXM_TUNER_AFC_MASK) { case CXM_TUNER_AFC_FREQ_CENTERED: @@ -862,7 +904,11 @@ } if (freq == prev_freq) +{ +printf("afc terug bij af\n"); return 0; +} + prev_freq = sc->tuner_freq; if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type, @@ -963,7 +1009,10 @@ if (cxm_tuner_read(sc->iicbus, CXM_I2C_TUNER, &status, sizeof(status)) != sizeof(status)) +{ +printf("no status read\n"); return -1; +} if (sc->tuner->systems.code_style == cxm_if_system_code_style || sc->tuner->systems.code_style