^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Support for a cx23417 mpeg encoder via cx231xx host port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (c) 2004 Jelle Foks <jelle@foks.us>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (c) 2008 Steven Toth <stoth@linuxtv.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * - CX23885/7/8 support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "cx231xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <media/drv-intf/cx2341x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <media/tuner.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CX231xx_FIRM_IMAGE_SIZE 376836
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* for polaris ITVC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ITVC_WRITE_DIR 0x03FDFC00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ITVC_READ_DIR 0x0001FC00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MCI_MEMORY_DATA_BYTE0 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MCI_MEMORY_DATA_BYTE1 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MCI_MEMORY_DATA_BYTE2 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MCI_MEMORY_DATA_BYTE3 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MCI_MEMORY_ADDRESS_BYTE2 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MCI_MEMORY_ADDRESS_BYTE1 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MCI_MEMORY_ADDRESS_BYTE0 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MCI_REGISTER_DATA_BYTE0 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MCI_REGISTER_DATA_BYTE1 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MCI_REGISTER_DATA_BYTE2 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MCI_REGISTER_DATA_BYTE3 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MCI_REGISTER_ADDRESS_BYTE0 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MCI_REGISTER_ADDRESS_BYTE1 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MCI_REGISTER_MODE 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Read and write modes for polaris ITVC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MCI_MODE_REGISTER_READ 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MCI_MODE_REGISTER_WRITE 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MCI_MODE_MEMORY_READ 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MCI_MODE_MEMORY_WRITE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static unsigned int mpeglines = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) module_param(mpeglines, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static unsigned int mpeglinesize = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) module_param(mpeglinesize, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MODULE_PARM_DESC(mpeglinesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "number of bytes in each line of an MPEG buffer, range 512-1024");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static unsigned int v4l_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) module_param(v4l_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define dprintk(level, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (v4l_debug >= level) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) printk(KERN_DEBUG pr_fmt(fmt), ## arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static struct cx231xx_tvnorm cx231xx_tvnorms[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .name = "NTSC-M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .id = V4L2_STD_NTSC_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .name = "NTSC-JP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .id = V4L2_STD_NTSC_M_JP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .name = "PAL-BG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .id = V4L2_STD_PAL_BG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .name = "PAL-DK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .id = V4L2_STD_PAL_DK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .name = "PAL-I",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .id = V4L2_STD_PAL_I,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .name = "PAL-M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .id = V4L2_STD_PAL_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .name = "PAL-N",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .id = V4L2_STD_PAL_N,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .name = "PAL-Nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .id = V4L2_STD_PAL_Nc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .name = "PAL-60",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .id = V4L2_STD_PAL_60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .name = "SECAM-L",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .id = V4L2_STD_SECAM_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .name = "SECAM-DK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .id = V4L2_STD_SECAM_DK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum cx231xx_capture_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) CX231xx_MPEG_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) CX231xx_RAW_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) CX231xx_RAW_PASSTHRU_CAPTURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum cx231xx_capture_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) CX231xx_RAW_BITS_NONE = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) CX231xx_RAW_BITS_YUV_CAPTURE = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) CX231xx_RAW_BITS_PCM_CAPTURE = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) CX231xx_RAW_BITS_VBI_CAPTURE = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CX231xx_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CX231xx_RAW_BITS_TO_HOST_CAPTURE = 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) enum cx231xx_capture_end {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) CX231xx_END_AT_GOP, /* stop at the end of gop, generate irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CX231xx_END_NOW, /* stop immediately, no irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) enum cx231xx_framerate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CX231xx_FRAMERATE_NTSC_30, /* NTSC: 30fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) CX231xx_FRAMERATE_PAL_25 /* PAL: 25fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) enum cx231xx_stream_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) CX231xx_OUTPUT_PORT_MEMORY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) CX231xx_OUTPUT_PORT_STREAMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) CX231xx_OUTPUT_PORT_SERIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) enum cx231xx_data_xfer_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) CX231xx_MORE_BUFFERS_FOLLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) CX231xx_LAST_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) enum cx231xx_picture_mask {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) CX231xx_PICTURE_MASK_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CX231xx_PICTURE_MASK_I_FRAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) CX231xx_PICTURE_MASK_I_P_FRAMES = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) CX231xx_PICTURE_MASK_ALL_FRAMES = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) enum cx231xx_vbi_mode_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) CX231xx_VBI_BITS_SLICED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) CX231xx_VBI_BITS_RAW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) enum cx231xx_vbi_insertion_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) CX231xx_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) CX231xx_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) CX231xx_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) CX231xx_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) CX231xx_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) enum cx231xx_dma_unit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) CX231xx_DMA_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) CX231xx_DMA_FRAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) enum cx231xx_dma_transfer_status_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) CX231xx_DMA_TRANSFER_BITS_DONE = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) CX231xx_DMA_TRANSFER_BITS_ERROR = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) CX231xx_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) enum cx231xx_pause {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) CX231xx_PAUSE_ENCODING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) CX231xx_RESUME_ENCODING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) enum cx231xx_copyright {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) CX231xx_COPYRIGHT_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) CX231xx_COPYRIGHT_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) enum cx231xx_notification_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) CX231xx_NOTIFICATION_REFRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) enum cx231xx_notification_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) CX231xx_NOTIFICATION_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) CX231xx_NOTIFICATION_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) enum cx231xx_notification_mailbox {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) CX231xx_NOTIFICATION_NO_MAILBOX = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) enum cx231xx_field1_lines {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) CX231xx_FIELD1_SAA7114 = 0x00EF, /* 239 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) CX231xx_FIELD1_SAA7115 = 0x00F0, /* 240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) CX231xx_FIELD1_MICRONAS = 0x0105, /* 261 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) enum cx231xx_field2_lines {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) CX231xx_FIELD2_SAA7114 = 0x00EF, /* 239 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) CX231xx_FIELD2_SAA7115 = 0x00F0, /* 240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) CX231xx_FIELD2_MICRONAS = 0x0106, /* 262 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) enum cx231xx_custom_data_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) CX231xx_CUSTOM_EXTENSION_USR_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) CX231xx_CUSTOM_PRIVATE_PACKET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) enum cx231xx_mute {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) CX231xx_UNMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) CX231xx_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) enum cx231xx_mute_video_mask {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) CX231xx_MUTE_VIDEO_V_MASK = 0x0000FF00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) CX231xx_MUTE_VIDEO_U_MASK = 0x00FF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) CX231xx_MUTE_VIDEO_Y_MASK = 0xFF000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) enum cx231xx_mute_video_shift {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) CX231xx_MUTE_VIDEO_V_SHIFT = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) CX231xx_MUTE_VIDEO_U_SHIFT = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) CX231xx_MUTE_VIDEO_Y_SHIFT = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* defines below are from ivtv-driver.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Firmware API commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define IVTV_API_STD_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* IVTV_REG_OFFSET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define IVTV_REG_SPU (0x9050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define IVTV_REG_HW_BLOCKS (0x9054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #define IVTV_REG_VPU (0x9058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define IVTV_REG_APU (0xA064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * Bit definitions for MC417_RWD and MC417_OEN registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * bits 31-16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *| Reserved |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *|+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *| bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *|+-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *|| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *|+-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *| bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *|+-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *||MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *|+-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define MC417_MIWR 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define MC417_MIRD 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define MC417_MICS 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define MC417_MIRDY 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define MC417_MIADDR 0x0F00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define MC417_MIDATA 0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Bit definitions for MC417_CTL register ****
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *+--------+-------------+--------+--------------+------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *+--------+-------------+--------+--------------+------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #define MC417_UART_GPIO_EN 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* Values for speed control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define MC417_SPD_CTL_SLOW 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define MC417_SPD_CTL_MEDIUM 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Values for GPIO select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define MC417_GPIO_SEL_GPIO3 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define MC417_GPIO_SEL_GPIO2 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define MC417_GPIO_SEL_GPIO1 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define MC417_GPIO_SEL_GPIO0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #define CX23417_GPIO_MASK 0xFC0003FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int set_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 _gpio_direction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) _gpio_direction = _gpio_direction & CX23417_GPIO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) _gpio_direction = _gpio_direction | gpio_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) status = cx231xx_send_gpio_cmd(dev, _gpio_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) (u8 *)&value, 4, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int get_itvc_reg(struct cx231xx *dev, u32 gpio_direction, u32 *val_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) u32 _gpio_direction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) _gpio_direction = _gpio_direction & CX23417_GPIO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) _gpio_direction = _gpio_direction | gpio_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) status = cx231xx_send_gpio_cmd(dev, _gpio_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) (u8 *)val_ptr, 4, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int wait_for_mci_complete(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u32 gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u32 gpio_direction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u8 count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) get_itvc_reg(dev, gpio_direction, &gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) while (!(gpio&0x020000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) get_itvc_reg(dev, gpio_direction, &gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (count++ > 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dprintk(3, "ERROR: Timeout - gpio=%x\n", gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int mc417_register_write(struct cx231xx *dev, u16 address, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) temp = 0x82 | MCI_REGISTER_DATA_BYTE0 | ((value & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) status = set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /*write data byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) temp = 0x82 | MCI_REGISTER_DATA_BYTE1 | (value & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*write data byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) temp = 0x82 | MCI_REGISTER_DATA_BYTE2 | ((value & 0x00FF0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*write data byte 3;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) temp = 0x82 | MCI_REGISTER_DATA_BYTE3 | ((value & 0xFF000000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*write address byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*write address byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*Write that the mode is write.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return wait_for_mci_complete(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int mc417_register_read(struct cx231xx *dev, u16 address, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*write address byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u32 return_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE0 | ((address & 0x00FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) temp = temp | ((0x05) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*write address byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) temp = 0x82 | MCI_REGISTER_ADDRESS_BYTE1 | (address & 0xFF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) temp = temp | ((0x05) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*write that the mode is read;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) temp = 0x82 | MCI_REGISTER_MODE | MCI_MODE_REGISTER_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) temp = temp | ((0x05) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*wait for the MIRDY line to be asserted ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) signalling that the read is done;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = wait_for_mci_complete(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*switch the DATA- GPIO to input mode;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*Read data byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) temp = (0x82 | MCI_REGISTER_DATA_BYTE0) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) temp = ((0x81 | MCI_REGISTER_DATA_BYTE0) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return_value |= ((temp & 0x03FC0000) >> 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* Read data byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) temp = (0x82 | MCI_REGISTER_DATA_BYTE1) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) temp = ((0x81 | MCI_REGISTER_DATA_BYTE1) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return_value |= ((temp & 0x03FC0000) >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*Read data byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) temp = (0x82 | MCI_REGISTER_DATA_BYTE2) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) temp = ((0x81 | MCI_REGISTER_DATA_BYTE2) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return_value |= ((temp & 0x03FC0000) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*Read data byte 3;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) temp = (0x82 | MCI_REGISTER_DATA_BYTE3) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) temp = ((0x81 | MCI_REGISTER_DATA_BYTE3) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return_value |= ((temp & 0x03FC0000) << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *value = return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int mc417_memory_write(struct cx231xx *dev, u32 address, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /*write data byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /*write data byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /*write data byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /*write data byte 3;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* write address byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ((address & 0x003F0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* write address byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* write address byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*wait for MIRDY line;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) wait_for_mci_complete(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static int mc417_memory_read(struct cx231xx *dev, u32 address, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) u32 temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) u32 return_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*write address byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ((address & 0x003F0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ret = set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /*write address byte 1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /*write address byte 0*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) set_itvc_reg(dev, ITVC_WRITE_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /*Wait for MIRDY line*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ret = wait_for_mci_complete(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*Read data byte 3;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) temp = (0x82 | MCI_MEMORY_DATA_BYTE3) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) temp = ((0x81 | MCI_MEMORY_DATA_BYTE3) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return_value |= ((temp & 0x03FC0000) << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /*Read data byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) temp = (0x82 | MCI_MEMORY_DATA_BYTE2) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) temp = ((0x81 | MCI_MEMORY_DATA_BYTE2) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return_value |= ((temp & 0x03FC0000) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Read data byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) temp = (0x82 | MCI_MEMORY_DATA_BYTE1) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) temp = ((0x81 | MCI_MEMORY_DATA_BYTE1) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return_value |= ((temp & 0x03FC0000) >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*Read data byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) temp = (0x82 | MCI_MEMORY_DATA_BYTE0) << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) temp = ((0x81 | MCI_MEMORY_DATA_BYTE0) << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) set_itvc_reg(dev, ITVC_READ_DIR, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) get_itvc_reg(dev, ITVC_READ_DIR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return_value |= ((temp & 0x03FC0000) >> 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) set_itvc_reg(dev, ITVC_READ_DIR, (0x87 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *value = return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* MPEG encoder API */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static char *cmd_to_str(int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) case CX2341X_ENC_PING_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return "PING_FW";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case CX2341X_ENC_START_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return "START_CAPTURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) case CX2341X_ENC_STOP_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return "STOP_CAPTURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case CX2341X_ENC_SET_AUDIO_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return "SET_AUDIO_ID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case CX2341X_ENC_SET_VIDEO_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return "SET_VIDEO_ID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case CX2341X_ENC_SET_PCR_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return "SET_PCR_PID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case CX2341X_ENC_SET_FRAME_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return "SET_FRAME_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) case CX2341X_ENC_SET_FRAME_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return "SET_FRAME_SIZE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case CX2341X_ENC_SET_BIT_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return "SET_BIT_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case CX2341X_ENC_SET_GOP_PROPERTIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return "SET_GOP_PROPERTIES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case CX2341X_ENC_SET_ASPECT_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return "SET_ASPECT_RATIO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case CX2341X_ENC_SET_DNR_FILTER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return "SET_DNR_FILTER_PROPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case CX2341X_ENC_SET_DNR_FILTER_PROPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return "SET_DNR_FILTER_PROPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case CX2341X_ENC_SET_CORING_LEVELS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return "SET_CORING_LEVELS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return "SET_SPATIAL_FILTER_TYPE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case CX2341X_ENC_SET_VBI_LINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return "SET_VBI_LINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) case CX2341X_ENC_SET_STREAM_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return "SET_STREAM_TYPE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case CX2341X_ENC_SET_OUTPUT_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return "SET_OUTPUT_PORT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case CX2341X_ENC_SET_AUDIO_PROPERTIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return "SET_AUDIO_PROPERTIES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) case CX2341X_ENC_HALT_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return "HALT_FW";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case CX2341X_ENC_GET_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return "GET_VERSION";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case CX2341X_ENC_SET_GOP_CLOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return "SET_GOP_CLOSURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case CX2341X_ENC_GET_SEQ_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return "GET_SEQ_END";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case CX2341X_ENC_SET_PGM_INDEX_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return "SET_PGM_INDEX_INFO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case CX2341X_ENC_SET_VBI_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return "SET_VBI_CONFIG";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) case CX2341X_ENC_SET_DMA_BLOCK_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return "SET_DMA_BLOCK_SIZE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return "GET_PREV_DMA_INFO_MB_10";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return "GET_PREV_DMA_INFO_MB_9";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case CX2341X_ENC_SCHED_DMA_TO_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return "SCHED_DMA_TO_HOST";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case CX2341X_ENC_INITIALIZE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return "INITIALIZE_INPUT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case CX2341X_ENC_SET_FRAME_DROP_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return "SET_FRAME_DROP_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case CX2341X_ENC_PAUSE_ENCODER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return "PAUSE_ENCODER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case CX2341X_ENC_REFRESH_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return "REFRESH_INPUT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case CX2341X_ENC_SET_COPYRIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return "SET_COPYRIGHT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case CX2341X_ENC_SET_EVENT_NOTIFICATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return "SET_EVENT_NOTIFICATION";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case CX2341X_ENC_SET_NUM_VSYNC_LINES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return "SET_NUM_VSYNC_LINES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case CX2341X_ENC_SET_PLACEHOLDER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return "SET_PLACEHOLDER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case CX2341X_ENC_MUTE_VIDEO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return "MUTE_VIDEO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) case CX2341X_ENC_MUTE_AUDIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return "MUTE_AUDIO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) case CX2341X_ENC_MISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return "MISC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int cx231xx_mbox_func(void *priv, u32 command, int in, int out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) u32 data[CX2341X_MBOX_MAX_DATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct cx231xx *dev = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) u32 value, flag, retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dprintk(3, "%s: command(0x%X) = %s\n", __func__, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /* this may not be 100% safe if we can't read any memory location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) without side effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (value != 0x12345678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dprintk(3, "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) value, cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* This read looks at 32 bits, but flag is only 8 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * Seems we also bail if CMD or TIMEOUT bytes are set???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dprintk(3, "ERROR: Mailbox appears to be in use (%x), cmd = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) flag, cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) flag |= 1; /* tell 'em we're working on it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* write command + args + fill remaining with zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* command code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) mc417_memory_write(dev, dev->cx23417_mailbox + 1, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mc417_memory_write(dev, dev->cx23417_mailbox + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) IVTV_API_STD_TIMEOUT); /* timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) for (i = 0; i < in; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dprintk(3, "API Input %d = %d\n", i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) for (; i < CX2341X_MBOX_MAX_DATA; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) flag |= 3; /* tell 'em we're done writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* wait for firmware to handle the API command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) timeout = jiffies + msecs_to_jiffies(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (0 != (flag & 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dprintk(3, "ERROR: API Mailbox timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* read output values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) for (i = 0; i < out; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dprintk(3, "API Output %d = %d\n", i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dprintk(3, "API result = %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* We don't need to call the API often, so using just one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * mailbox will probably suffice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int cx231xx_api_cmd(struct cx231xx *dev, u32 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u32 inputcnt, u32 outputcnt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) u32 data[CX2341X_MBOX_MAX_DATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) va_list vargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dprintk(3, "%s() cmds = 0x%08x\n", __func__, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) va_start(vargs, outputcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) for (i = 0; i < inputcnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) data[i] = va_arg(vargs, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) err = cx231xx_mbox_func(dev, command, inputcnt, outputcnt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) for (i = 0; i < outputcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int *vptr = va_arg(vargs, int *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) *vptr = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) va_end(vargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int cx231xx_find_mailbox(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) u32 signature[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 0x12345678, 0x34567812, 0x56781234, 0x78123456
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) int signaturecnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) for (i = 0; i < 0x100; i++) {/*CX231xx_FIRM_IMAGE_SIZE*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = mc417_memory_read(dev, i, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (value == signature[signaturecnt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) signaturecnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) signaturecnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (4 == signaturecnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dprintk(1, "Mailbox signature found at 0x%x\n", i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dprintk(3, "Mailbox signature values not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static void mci_write_memory_to_gpio(struct cx231xx *dev, u32 address, u32 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) u32 *p_fw_image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) u32 temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) temp = 0x82 | MCI_MEMORY_DATA_BYTE0 | ((value & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /*write data byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) temp = 0x82 | MCI_MEMORY_DATA_BYTE1 | (value & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /*write data byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) temp = 0x82 | MCI_MEMORY_DATA_BYTE2 | ((value & 0x00FF0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /*write data byte 3;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) temp = 0x82 | MCI_MEMORY_DATA_BYTE3 | ((value & 0xFF000000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* write address byte 2;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE2 | MCI_MODE_MEMORY_WRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ((address & 0x003F0000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* write address byte 1;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE1 | (address & 0xFF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* write address byte 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) temp = 0x82 | MCI_MEMORY_ADDRESS_BYTE0 | ((address & 0x00FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) temp = temp << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) temp = temp | (0x05 << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) *p_fw_image = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) for (i = 0; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) *p_fw_image = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) p_fw_image++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static int cx231xx_load_firmware(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static const unsigned char magic[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int i, retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) u32 gpio_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /*u32 checksum = 0;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /*u32 *dataptr;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) u32 transfer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) u32 fw_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) u32 address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /*u32 current_fw[800];*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) u32 *p_current_fw, *p_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u32 *p_fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) u16 _buffer_size = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) u8 *p_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) p_current_fw = vmalloc(1884180 * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) p_fw = p_current_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (p_current_fw == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) dprintk(2, "FAIL!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) p_buffer = vmalloc(4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (p_buffer == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dprintk(2, "FAIL!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* Save GPIO settings before reset of APU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) retval |= mc417_memory_read(dev, 0x9020, &gpio_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) retval |= mc417_memory_read(dev, 0x900C, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) retval = mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) IVTV_REG_VPU, 0xFFFFFFED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) IVTV_REG_APU, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) "%s: Error with mc417_register_write\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) vfree(p_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) "ERROR: Hotplug firmware request failed (%s).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) CX231xx_FIRM_IMAGE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) "Please fix your hotplug setup, the board will not work without firmware loaded!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) vfree(p_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) firmware->size, CX231xx_FIRM_IMAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) vfree(p_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (0 != memcmp(firmware->data, magic, 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) "ERROR: Firmware magic mismatch, wrong file?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) vfree(p_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) initGPIO(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* transfer to the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) dprintk(2, "Loading firmware to GPIO...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) p_fw_data = (u32 *)firmware->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dprintk(2, "firmware->size=%zd\n", firmware->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) for (transfer_size = 0; transfer_size < firmware->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) transfer_size += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) fw_data = *p_fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) mci_write_memory_to_gpio(dev, address, fw_data, p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) address = address + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) p_current_fw += 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) p_fw_data += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /*download the firmware by ep5-out*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) for (frame = 0; frame < (int)(CX231xx_FIRM_IMAGE_SIZE*20/_buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) frame++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) for (i = 0; i < _buffer_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) *(p_buffer + i) = (u8)(*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x0000FF00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0x00FF0000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *(p_buffer + i) = (u8)((*(p_fw + (frame * 128 * 8 + (i / 4))) & 0xFF000000) >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) cx231xx_ep5_bulkout(dev, p_buffer, _buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) p_current_fw = p_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) vfree(p_current_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) p_current_fw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) vfree(p_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) uninitGPIO(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dprintk(1, "Firmware upload successful.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) IVTV_CMD_HW_BLOCKS_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) "%s: Error with mc417_register_write\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* F/W power up disturbs the GPIOs, restore state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) retval |= mc417_register_write(dev, 0x9020, gpio_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) retval |= mc417_register_write(dev, 0x900C, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) "%s: Error with mc417_register_write\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static void cx231xx_codec_settings(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) /* assign frame size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dev->ts1.height, dev->ts1.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) dev->mpeg_ctrl_handler.width = dev->ts1.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) dev->mpeg_ctrl_handler.height = dev->ts1.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) cx2341x_handler_setup(&dev->mpeg_ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int cx231xx_initialize_codec(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) cx231xx_disable656(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dprintk(2, "%s: PING OK\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) retval = cx231xx_load_firmware(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) "%s: f/w load failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) retval = cx231xx_find_mailbox(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev_err(dev->dev, "%s: mailbox < 0, error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dev->cx23417_mailbox = retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) "ERROR: cx23417 firmware ping failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) &version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) dev_err(dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) "ERROR: cx23417 firmware get encoder: version failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dprintk(1, "cx23417 firmware version is 0x%08x\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) for (i = 0; i < 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) retval = mc417_register_read(dev, 0x20f8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dprintk(3, "***before enable656() VIM Capture Lines = %d ***\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) cx231xx_enable656(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /* stop mpeg capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, 1, 3, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) cx231xx_codec_settings(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* cx231xx_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) CX231xx_FIELD1_SAA7115, CX231xx_FIELD2_SAA7115);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) cx231xx_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) CX231xx_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u32 data[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* Setup to capture VBI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) data[0] = 0x0001BD00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) data[1] = 1; /* frames per interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) data[2] = 4; /* total bufs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) data[3] = 0x91559155; /* start codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) data[4] = 0x206080C0; /* stop codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) data[5] = 6; /* lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) data[6] = 64; /* BPL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) data[2], data[3], data[4], data[5], data[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) for (i = 2; i <= 24; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) int valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) valid = ((i >= 19) && (i <= 21));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) valid, 0 , 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) cx231xx_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) i | 0x80000000, valid, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* cx231xx_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX231xx_UNMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* initialize the video input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) retval = cx231xx_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* Enable VIP style pixel invalidation so we work with scaled mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) mc417_memory_write(dev, 2120, 0x00000080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* start capturing to the host interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) retval = cx231xx_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) CX231xx_MPEG_CAPTURE, CX231xx_RAW_BITS_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) for (i = 0; i < 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) mc417_register_read(dev, 0x20f8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) dprintk(3, "***VIM Capture Lines =%d ***\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) unsigned int *nbuffers, unsigned int *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct cx231xx *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) unsigned int size = mpeglinesize * mpeglines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) dev->ts1.ts_packet_size = mpeglinesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) dev->ts1.ts_packet_count = mpeglines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (vq->num_buffers + *nbuffers < CX231XX_MIN_BUF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) *nbuffers = CX231XX_MIN_BUF - vq->num_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (*nplanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return sizes[0] < size ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) sizes[0] = mpeglinesize * mpeglines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct cx231xx_dmaqueue *dma_q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) void *vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct cx231xx_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) u32 tail_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) char *p_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (dma_q->mpeg_buffer_done == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (list_empty(&dma_q->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) buf = list_entry(dma_q->active.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct cx231xx_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) dev->video_mode.isoc_ctl.buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dma_q->mpeg_buffer_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* Fill buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) buf = dev->video_mode.isoc_ctl.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if ((dma_q->mpeg_buffer_completed+len) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) mpeglines*mpeglinesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (dma_q->add_ps_package_head ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) CX231XX_NEED_ADD_PS_PACKAGE_HEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) memcpy(vbuf+dma_q->mpeg_buffer_completed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) dma_q->ps_head, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) dma_q->mpeg_buffer_completed =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) dma_q->mpeg_buffer_completed + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dma_q->add_ps_package_head =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) CX231XX_NONEED_PS_PACKAGE_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) memcpy(vbuf+dma_q->mpeg_buffer_completed, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) dma_q->mpeg_buffer_completed =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) dma_q->mpeg_buffer_completed + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) dma_q->mpeg_buffer_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) tail_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) mpeglines*mpeglinesize - dma_q->mpeg_buffer_completed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) memcpy(vbuf+dma_q->mpeg_buffer_completed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) data, tail_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) buf->vb.vb2_buf.timestamp = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) buf->vb.sequence = dma_q->sequence++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) dma_q->mpeg_buffer_completed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (len - tail_data > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) p_data = data + tail_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) dma_q->left_data_count = len - tail_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) memcpy(dma_q->p_left_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) p_data, len - tail_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static void buffer_filled(char *data, int len, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct cx231xx_dmaqueue *dma_q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) void *vbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct cx231xx_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (list_empty(&dma_q->active))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* Fill buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) memcpy(vbuf, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) buf->vb.sequence = dma_q->sequence++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) buf->vb.vb2_buf.timestamp = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct cx231xx_dmaqueue *dma_q = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) unsigned char *p_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) u32 buffer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) u32 i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) for (i = 0; i < urb->number_of_packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (dma_q->left_data_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) buffer_copy(dev, dma_q->p_left_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) dma_q->left_data_count, urb, dma_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) dma_q->mpeg_buffer_completed = dma_q->left_data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dma_q->left_data_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) p_buffer = urb->transfer_buffer +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) urb->iso_frame_desc[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) buffer_size = urb->iso_frame_desc[i].actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (buffer_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) buffer_copy(dev, p_buffer, buffer_size, urb, dma_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct cx231xx_dmaqueue *dma_q = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) unsigned char *p_buffer, *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) u32 buffer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) p_buffer = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) buffer_size = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) buffer = kmalloc(buffer_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) memcpy(buffer, dma_q->ps_head, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) memcpy(buffer+3, p_buffer, buffer_size-3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) memcpy(dma_q->ps_head, p_buffer+buffer_size-3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) p_buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) buffer_filled(p_buffer, buffer_size, urb, dma_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static void buffer_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct cx231xx_buffer *buf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) container_of(vb, struct cx231xx_buffer, vb.vb2_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) spin_lock_irqsave(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) list_add_tail(&buf->list, &vidq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) spin_unlock_irqrestore(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static void return_all_buffers(struct cx231xx *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) enum vb2_buffer_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct cx231xx_buffer *buf, *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) spin_lock_irqsave(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) list_for_each_entry_safe(buf, node, &vidq->active, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) vb2_buffer_done(&buf->vb.vb2_buf, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) spin_unlock_irqrestore(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) static int start_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct cx231xx *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) vidq->sequence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) dev->mode_tv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) cx231xx_set_alt_setting(dev, INDEX_VANC, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) cx231xx_set_gpio_value(dev, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) cx231xx_initialize_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) cx231xx_start_TS1(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (dev->USE_ISO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ret = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) CX231XX_NUM_BUFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) dev->ts1_mode.max_pkt_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) cx231xx_isoc_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) ret = cx231xx_init_bulk(dev, 320, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) dev->ts1_mode.max_pkt_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) cx231xx_bulk_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return_all_buffers(dev, VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) call_all(dev, video, s_stream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static void stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct cx231xx *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) call_all(dev, video, s_stream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) cx231xx_stop_TS1(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) /* do this before setting alternate! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (dev->USE_ISO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) cx231xx_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) cx231xx_uninit_bulk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) cx231xx_set_mode(dev, CX231XX_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) CX231xx_END_NOW, CX231xx_MPEG_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) CX231xx_RAW_BITS_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) spin_lock_irqsave(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (dev->USE_ISO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) dev->video_mode.isoc_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) dev->video_mode.bulk_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) spin_unlock_irqrestore(&dev->video_mode.slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return_all_buffers(dev, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static struct vb2_ops cx231xx_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) .queue_setup = queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) .start_streaming = start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .stop_streaming = stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) static int vidioc_g_pixelaspect(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) int type, struct v4l2_fract *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) bool is_50hz = dev->encodernorm.id & V4L2_STD_625_50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) f->numerator = is_50hz ? 54 : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) f->denominator = is_50hz ? 59 : 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int vidioc_g_selection(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct v4l2_selection *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) switch (s->target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) case V4L2_SEL_TGT_CROP_BOUNDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) case V4L2_SEL_TGT_CROP_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) s->r.left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) s->r.top = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) s->r.width = dev->ts1.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) s->r.height = dev->ts1.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) *norm = dev->encodernorm.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (id & cx231xx_tvnorms[i].id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (i == ARRAY_SIZE(cx231xx_tvnorms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) dev->encodernorm = cx231xx_tvnorms[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (dev->encodernorm.id & 0xb000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) dprintk(3, "encodernorm set to NTSC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dev->norm = V4L2_STD_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) dev->ts1.height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) dprintk(3, "encodernorm set to PAL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) dev->norm = V4L2_STD_PAL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) dev->ts1.height = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) call_all(dev, video, s_std, dev->norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) /* do mode control overrides */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) cx231xx_do_mode_ctrl_overrides(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) dprintk(3, "exit vidioc_s_std() i=0x%x\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) static int vidioc_s_ctrl(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) struct v4l2_control *ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) dprintk(3, "enter vidioc_s_ctrl()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* Update the A/V core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) v4l2_device_for_each_subdev(sd, &dev->v4l2_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) v4l2_s_ctrl(NULL, sd->ctrl_handler, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) dprintk(3, "exit vidioc_s_ctrl()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (f->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) f->pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) dprintk(3, "enter vidioc_g_fmt_vid_cap()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) f->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) f->fmt.pix.sizeimage = mpeglines * mpeglinesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) f->fmt.pix.width = dev->ts1.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) f->fmt.pix.height = dev->ts1.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) dev->ts1.width, dev->ts1.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) dprintk(3, "exit vidioc_g_fmt_vid_cap()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) dprintk(3, "enter vidioc_try_fmt_vid_cap()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) f->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) f->fmt.pix.sizeimage = mpeglines * mpeglinesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) dev->ts1.width, dev->ts1.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) dprintk(3, "exit vidioc_try_fmt_vid_cap()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) static int vidioc_log_status(struct file *file, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct cx231xx *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) call_all(dev, core, log_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return v4l2_ctrl_log_status(file, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) static const struct v4l2_file_operations mpeg_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .open = v4l2_fh_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .release = vb2_fop_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .vidioc_g_tuner = cx231xx_g_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .vidioc_s_tuner = cx231xx_s_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .vidioc_g_frequency = cx231xx_g_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .vidioc_s_frequency = cx231xx_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .vidioc_enum_input = cx231xx_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) .vidioc_g_input = cx231xx_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) .vidioc_s_input = cx231xx_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) .vidioc_s_ctrl = vidioc_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .vidioc_g_pixelaspect = vidioc_g_pixelaspect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) .vidioc_g_selection = vidioc_g_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) .vidioc_querycap = cx231xx_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) .vidioc_s_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .vidioc_log_status = vidioc_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .vidioc_g_register = cx231xx_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .vidioc_s_register = cx231xx_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) static struct video_device cx231xx_mpeg_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) .name = "cx231xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) .fops = &mpeg_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) .ioctl_ops = &mpeg_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) .minor = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .tvnorms = V4L2_STD_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) void cx231xx_417_unregister(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) dprintk(3, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (video_is_registered(&dev->v4l_device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) video_unregister_device(&dev->v4l_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) struct v4l2_subdev_format format = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .which = V4L2_SUBDEV_FORMAT_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) /* fix videodecoder resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) format.format.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) format.format.height = cxhdl->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) format.format.code = MEDIA_BUS_FMT_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) v4l2_subdev_call(dev->sd_cx25840, pad, set_fmt, NULL, &format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) static int cx231xx_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) static const u32 freqs[3] = { 44100, 48000, 32000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) /* The audio clock of the digitizer must match the codec sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) rate otherwise you get some very strange effects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (idx < ARRAY_SIZE(freqs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) call_all(dev, audio, s_clock_freq, freqs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) static const struct cx2341x_handler_ops cx231xx_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) /* needed for the video clock freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) .s_audio_sampling_freq = cx231xx_s_audio_sampling_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) /* needed for setting up the video resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .s_video_encoding = cx231xx_s_video_encoding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) static void cx231xx_video_dev_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct cx231xx *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) struct usb_device *usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) struct video_device *vfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) const struct video_device *template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) *vfd = *template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) type, cx231xx_boards[dev->model].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) vfd->v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) vfd->lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) vfd->release = video_device_release_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) video_set_drvdata(vfd, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (dev->tuner_type == TUNER_ABSENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) int cx231xx_417_register(struct cx231xx *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) /* FIXME: Port1 hardcoded here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct cx231xx_tsport *tsport = &dev->ts1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct vb2_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /* Set default TV standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) dev->encodernorm = cx231xx_tvnorms[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if (dev->encodernorm.id & V4L2_STD_525_60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) tsport->height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) tsport->height = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) tsport->width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) err = cx2341x_handler_init(&dev->mpeg_ctrl_handler, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) dprintk(3, "%s: can't init cx2341x controls\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) dev->mpeg_ctrl_handler.func = cx231xx_mbox_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) dev->mpeg_ctrl_handler.priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) dev->mpeg_ctrl_handler.ops = &cx231xx_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (dev->sd_cx25840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) dev->sd_cx25840->ctrl_handler, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) if (dev->mpeg_ctrl_handler.hdl.error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) err = dev->mpeg_ctrl_handler.hdl.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) dprintk(3, "%s: can't add cx25840 controls\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) dev->norm = V4L2_STD_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) dev->mpeg_ctrl_handler.port = CX2341X_PORT_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) /* Allocate and initialize V4L video device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) cx231xx_video_dev_init(dev, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) &dev->v4l_device, &cx231xx_mpeg_template, "mpeg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) q = &dev->mpegq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) q->drv_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) q->buf_struct_size = sizeof(struct cx231xx_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) q->ops = &cx231xx_video_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) q->mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) q->min_buffers_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) q->lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) err = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) dev->v4l_device.queue = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) err = video_register_device(&dev->v4l_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) dprintk(3, "%s: can't register mpeg device\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) dprintk(3, "%s: registered device video%d [mpeg]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) dev->name, dev->v4l_device.num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) MODULE_FIRMWARE(CX231xx_FIRM_IMAGE_NAME);