^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 cx23885 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://sourceforge.net/projects/ivtv/>
^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 "cx23885.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "cx23885-ioctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.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/drv-intf/cx2341x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CX23885_FIRM_IMAGE_SIZE 376836
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static unsigned int mpegbufs = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) module_param(mpegbufs, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static unsigned int mpeglines = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) module_param(mpeglines, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static unsigned int mpeglinesize = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) module_param(mpeglinesize, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE_PARM_DESC(mpeglinesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "number of bytes in each line of an MPEG buffer, range 512-1024");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static unsigned int v4l_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) module_param(v4l_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define dprintk(level, fmt, arg...)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) do { if (v4l_debug >= level) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) printk(KERN_DEBUG pr_fmt("%s: 417:" fmt), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __func__, ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static struct cx23885_tvnorm cx23885_tvnorms[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .name = "NTSC-M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .id = V4L2_STD_NTSC_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .name = "NTSC-JP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .id = V4L2_STD_NTSC_M_JP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .name = "PAL-BG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .id = V4L2_STD_PAL_BG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .name = "PAL-DK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .id = V4L2_STD_PAL_DK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .name = "PAL-I",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .id = V4L2_STD_PAL_I,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .name = "PAL-M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .id = V4L2_STD_PAL_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .name = "PAL-N",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .id = V4L2_STD_PAL_N,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .name = "PAL-Nc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .id = V4L2_STD_PAL_Nc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .name = "PAL-60",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .id = V4L2_STD_PAL_60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .name = "SECAM-L",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .id = V4L2_STD_SECAM_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .name = "SECAM-DK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .id = V4L2_STD_SECAM_DK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) enum cx23885_capture_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) CX23885_MPEG_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) CX23885_RAW_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) CX23885_RAW_PASSTHRU_CAPTURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) enum cx23885_capture_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) CX23885_RAW_BITS_NONE = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) CX23885_RAW_BITS_YUV_CAPTURE = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) CX23885_RAW_BITS_PCM_CAPTURE = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) CX23885_RAW_BITS_VBI_CAPTURE = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) CX23885_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) CX23885_RAW_BITS_TO_HOST_CAPTURE = 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) enum cx23885_capture_end {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) CX23885_END_AT_GOP, /* stop at the end of gop, generate irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) CX23885_END_NOW, /* stop immediately, no irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) enum cx23885_framerate {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) CX23885_FRAMERATE_NTSC_30, /* NTSC: 30fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) CX23885_FRAMERATE_PAL_25 /* PAL: 25fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) enum cx23885_stream_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) CX23885_OUTPUT_PORT_MEMORY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CX23885_OUTPUT_PORT_STREAMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) CX23885_OUTPUT_PORT_SERIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) enum cx23885_data_xfer_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) CX23885_MORE_BUFFERS_FOLLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) CX23885_LAST_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum cx23885_picture_mask {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) CX23885_PICTURE_MASK_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) CX23885_PICTURE_MASK_I_FRAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) CX23885_PICTURE_MASK_I_P_FRAMES = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) CX23885_PICTURE_MASK_ALL_FRAMES = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) enum cx23885_vbi_mode_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) CX23885_VBI_BITS_SLICED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) CX23885_VBI_BITS_RAW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum cx23885_vbi_insertion_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CX23885_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CX23885_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) CX23885_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) CX23885_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) CX23885_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) enum cx23885_dma_unit {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CX23885_DMA_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CX23885_DMA_FRAMES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) enum cx23885_dma_transfer_status_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) CX23885_DMA_TRANSFER_BITS_DONE = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) CX23885_DMA_TRANSFER_BITS_ERROR = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) CX23885_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) enum cx23885_pause {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) CX23885_PAUSE_ENCODING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) CX23885_RESUME_ENCODING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum cx23885_copyright {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) CX23885_COPYRIGHT_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) CX23885_COPYRIGHT_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) enum cx23885_notification_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) CX23885_NOTIFICATION_REFRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) enum cx23885_notification_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CX23885_NOTIFICATION_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) CX23885_NOTIFICATION_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) enum cx23885_notification_mailbox {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) CX23885_NOTIFICATION_NO_MAILBOX = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) enum cx23885_field1_lines {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) CX23885_FIELD1_SAA7114 = 0x00EF, /* 239 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) CX23885_FIELD1_SAA7115 = 0x00F0, /* 240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) CX23885_FIELD1_MICRONAS = 0x0105, /* 261 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) enum cx23885_field2_lines {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) CX23885_FIELD2_SAA7114 = 0x00EF, /* 239 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) CX23885_FIELD2_SAA7115 = 0x00F0, /* 240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) CX23885_FIELD2_MICRONAS = 0x0106, /* 262 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) enum cx23885_custom_data_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) CX23885_CUSTOM_EXTENSION_USR_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) CX23885_CUSTOM_PRIVATE_PACKET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) enum cx23885_mute {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) CX23885_UNMUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) CX23885_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) enum cx23885_mute_video_mask {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) CX23885_MUTE_VIDEO_V_MASK = 0x0000FF00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) CX23885_MUTE_VIDEO_U_MASK = 0x00FF0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) CX23885_MUTE_VIDEO_Y_MASK = 0xFF000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) enum cx23885_mute_video_shift {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) CX23885_MUTE_VIDEO_V_SHIFT = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) CX23885_MUTE_VIDEO_U_SHIFT = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) CX23885_MUTE_VIDEO_Y_SHIFT = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* defines below are from ivtv-driver.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Firmware API commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define IVTV_API_STD_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* IVTV_REG_OFFSET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define IVTV_REG_SPU (0x9050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define IVTV_REG_HW_BLOCKS (0x9054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define IVTV_REG_VPU (0x9058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define IVTV_REG_APU (0xA064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /**** Bit definitions for MC417_RWD and MC417_OEN registers ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) bits 31-16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) | Reserved |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 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 215) +-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) | MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) +-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 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 219) +-------+-------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) |MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0|
^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) #define MC417_MIWR 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define MC417_MIRD 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define MC417_MICS 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define MC417_MIRDY 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define MC417_MIADDR 0x0F00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define MC417_MIDATA 0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* MIADDR* nibble definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define MCI_MEMORY_DATA_BYTE0 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define MCI_MEMORY_DATA_BYTE1 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define MCI_MEMORY_DATA_BYTE2 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define MCI_MEMORY_DATA_BYTE3 0x300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define MCI_MEMORY_ADDRESS_BYTE2 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define MCI_MEMORY_ADDRESS_BYTE1 0x500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define MCI_MEMORY_ADDRESS_BYTE0 0x600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define MCI_REGISTER_DATA_BYTE0 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define MCI_REGISTER_DATA_BYTE1 0x900
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define MCI_REGISTER_DATA_BYTE2 0xA00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define MCI_REGISTER_DATA_BYTE3 0xB00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define MCI_REGISTER_ADDRESS_BYTE0 0xC00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define MCI_REGISTER_ADDRESS_BYTE1 0xD00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define MCI_REGISTER_MODE 0xE00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Read and write modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define MCI_MODE_REGISTER_READ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define MCI_MODE_REGISTER_WRITE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define MCI_MODE_MEMORY_READ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define MCI_MODE_MEMORY_WRITE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*** Bit definitions for MC417_CTL register ****
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) +--------+-------------+--------+--------------+------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) |Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) +--------+-------------+--------+--------------+------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define MC417_UART_GPIO_EN 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Values for speed control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define MC417_SPD_CTL_SLOW 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define MC417_SPD_CTL_MEDIUM 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Values for GPIO select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define MC417_GPIO_SEL_GPIO3 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define MC417_GPIO_SEL_GPIO2 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define MC417_GPIO_SEL_GPIO1 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define MC417_GPIO_SEL_GPIO0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) void cx23885_mc417_init(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Configure MC417_CTL register to defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) regval = MC417_SPD_CTL(MC417_SPD_CTL_FAST) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) MC417_GPIO_SEL(MC417_GPIO_SEL_GPIO3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) MC417_UART_GPIO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cx_write(MC417_CTL, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Configure MC417_OEN to defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) regval = MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) cx_write(MC417_OEN, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Configure MC417_RWD to defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) regval = MC417_MIWR | MC417_MIRD | MC417_MICS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int mc417_wait_ready(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u32 mi_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned long timeout = jiffies + msecs_to_jiffies(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mi_ready = cx_read(MC417_RWD) & MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (mi_ready != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (time_after(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Enable MC417 GPIO outputs except for MC417_MIRDY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * which is an input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) cx_write(MC417_OEN, MC417_MIRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Write data byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) (value & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* Transition CS/WR to effect write transaction across bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* Write data byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ((value >> 8) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Write data byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ((value >> 16) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Write data byte 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ((value >> 24) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* Write address byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) (address & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Write address byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ((address >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Indicate that this is a write. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) MCI_MODE_REGISTER_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Wait for the trans to complete (MC417_MIRDY asserted). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return mc417_wait_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 tempval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u32 dataval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Enable MC417 GPIO outputs except for MC417_MIRDY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * which is an input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) cx_write(MC417_OEN, MC417_MIRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Write address byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ((address & 0x00FF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Write address byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ((address >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Indicate that this is a register read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MCI_MODE_REGISTER_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* Wait for the trans to complete (MC417_MIRDY asserted). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) retval = mc417_wait_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* switch the DAT0-7 GPIO[10:3] to input mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Read data byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Transition RD to effect read transaction across bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Transition 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * input only...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Collect byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dataval = tempval & 0x000000FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Bring CS and RD high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Read data byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dataval |= ((tempval & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* Read data byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dataval |= ((tempval & 0x000000FF) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* Read data byte 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dataval |= ((tempval & 0x000000FF) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *value = dataval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* Enable MC417 GPIO outputs except for MC417_MIRDY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * which is an input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) cx_write(MC417_OEN, MC417_MIRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Write data byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) (value & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Transition CS/WR to effect write transaction across bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Write data byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ((value >> 8) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Write data byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ((value >> 16) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Write data byte 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ((value >> 24) & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Write address byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) MCI_MODE_MEMORY_WRITE | ((address >> 16) & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Write address byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ((address >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Write address byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) (address & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Wait for the trans to complete (MC417_MIRDY asserted). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return mc417_wait_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) u32 tempval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) u32 dataval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Enable MC417 GPIO outputs except for MC417_MIRDY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * which is an input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) cx_write(MC417_OEN, MC417_MIRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Write address byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) MCI_MODE_MEMORY_READ | ((address >> 16) & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Write address byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ((address >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* Write address byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) (address & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) regval |= MC417_MICS | MC417_MIWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Wait for the trans to complete (MC417_MIRDY asserted). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) retval = mc417_wait_ready(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* switch the DAT0-7 GPIO[10:3] to input mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* Read data byte 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Transition RD to effect read transaction across bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* Collect byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dataval = ((tempval & 0x000000FF) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* Bring CS and RD high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* Read data byte 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) dataval |= ((tempval & 0x000000FF) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Read data byte 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dataval |= ((tempval & 0x000000FF) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* Read data byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) tempval = cx_read(MC417_RWD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) dataval |= (tempval & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) cx_write(MC417_RWD, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *value = dataval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) void mc417_gpio_set(struct cx23885_dev *dev, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Set the gpio value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) mc417_register_read(dev, 0x900C, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) val |= (mask & 0x000ffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) mc417_register_write(dev, 0x900C, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Clear the gpio value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mc417_register_read(dev, 0x900C, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) val &= ~(mask & 0x0000ffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) mc417_register_write(dev, 0x900C, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Enable GPIO direction bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) mc417_register_read(dev, 0x9020, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (asoutput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) val |= (mask & 0x0000ffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) val &= ~(mask & 0x0000ffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) mc417_register_write(dev, 0x9020, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* MPEG encoder API */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static char *cmd_to_str(int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case CX2341X_ENC_PING_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return "PING_FW";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case CX2341X_ENC_START_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return "START_CAPTURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case CX2341X_ENC_STOP_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return "STOP_CAPTURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) case CX2341X_ENC_SET_AUDIO_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return "SET_AUDIO_ID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case CX2341X_ENC_SET_VIDEO_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return "SET_VIDEO_ID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case CX2341X_ENC_SET_PCR_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return "SET_PCR_ID";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case CX2341X_ENC_SET_FRAME_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return "SET_FRAME_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case CX2341X_ENC_SET_FRAME_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return "SET_FRAME_SIZE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case CX2341X_ENC_SET_BIT_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return "SET_BIT_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case CX2341X_ENC_SET_GOP_PROPERTIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return "SET_GOP_PROPERTIES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) case CX2341X_ENC_SET_ASPECT_RATIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return "SET_ASPECT_RATIO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case CX2341X_ENC_SET_DNR_FILTER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return "SET_DNR_FILTER_MODE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case CX2341X_ENC_SET_DNR_FILTER_PROPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return "SET_DNR_FILTER_PROPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) case CX2341X_ENC_SET_CORING_LEVELS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return "SET_CORING_LEVELS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return "SET_SPATIAL_FILTER_TYPE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) case CX2341X_ENC_SET_VBI_LINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return "SET_VBI_LINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case CX2341X_ENC_SET_STREAM_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return "SET_STREAM_TYPE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case CX2341X_ENC_SET_OUTPUT_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return "SET_OUTPUT_PORT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case CX2341X_ENC_SET_AUDIO_PROPERTIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return "SET_AUDIO_PROPERTIES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case CX2341X_ENC_HALT_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return "HALT_FW";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case CX2341X_ENC_GET_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return "GET_VERSION";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case CX2341X_ENC_SET_GOP_CLOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return "SET_GOP_CLOSURE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case CX2341X_ENC_GET_SEQ_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return "GET_SEQ_END";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case CX2341X_ENC_SET_PGM_INDEX_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return "SET_PGM_INDEX_INFO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) case CX2341X_ENC_SET_VBI_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return "SET_VBI_CONFIG";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) case CX2341X_ENC_SET_DMA_BLOCK_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return "SET_DMA_BLOCK_SIZE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return "GET_PREV_DMA_INFO_MB_10";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return "GET_PREV_DMA_INFO_MB_9";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) case CX2341X_ENC_SCHED_DMA_TO_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return "SCHED_DMA_TO_HOST";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case CX2341X_ENC_INITIALIZE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return "INITIALIZE_INPUT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case CX2341X_ENC_SET_FRAME_DROP_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return "SET_FRAME_DROP_RATE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case CX2341X_ENC_PAUSE_ENCODER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return "PAUSE_ENCODER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case CX2341X_ENC_REFRESH_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return "REFRESH_INPUT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) case CX2341X_ENC_SET_COPYRIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return "SET_COPYRIGHT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case CX2341X_ENC_SET_EVENT_NOTIFICATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return "SET_EVENT_NOTIFICATION";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case CX2341X_ENC_SET_NUM_VSYNC_LINES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return "SET_NUM_VSYNC_LINES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case CX2341X_ENC_SET_PLACEHOLDER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return "SET_PLACEHOLDER";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) case CX2341X_ENC_MUTE_VIDEO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return "MUTE_VIDEO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case CX2341X_ENC_MUTE_AUDIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return "MUTE_AUDIO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case CX2341X_ENC_MISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return "MISC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return "UNKNOWN";
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int cx23885_mbox_func(void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) u32 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) u32 data[CX2341X_MBOX_MAX_DATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct cx23885_dev *dev = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) u32 value, flag, retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) dprintk(3, "%s: command(0x%X) = %s\n", __func__, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* this may not be 100% safe if we can't read any memory location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) without side effects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (value != 0x12345678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) pr_err("Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) value, cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* This read looks at 32 bits, but flag is only 8 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * Seems we also bail if CMD or TIMEOUT bytes are set???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pr_err("ERROR: Mailbox appears to be in use (%x), cmd = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) flag, cmd_to_str(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) flag |= 1; /* tell 'em we're working on it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* write command + args + fill remaining with zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /* command code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) mc417_memory_write(dev, dev->cx23417_mailbox + 1, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) mc417_memory_write(dev, dev->cx23417_mailbox + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) IVTV_API_STD_TIMEOUT); /* timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) for (i = 0; i < in; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) dprintk(3, "API Input %d = %d\n", i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) for (; i < CX2341X_MBOX_MAX_DATA; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) flag |= 3; /* tell 'em we're done writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* wait for firmware to handle the API command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) timeout = jiffies + msecs_to_jiffies(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mc417_memory_read(dev, dev->cx23417_mailbox, &flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (0 != (flag & 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) pr_err("ERROR: API Mailbox timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* read output values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) for (i = 0; i < out; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dprintk(3, "API Output %d = %d\n", i, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dprintk(3, "API result = %d\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) mc417_memory_write(dev, dev->cx23417_mailbox, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* We don't need to call the API often, so using just one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * mailbox will probably suffice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int cx23885_api_cmd(struct cx23885_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) u32 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) u32 inputcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) u32 outputcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) u32 data[CX2341X_MBOX_MAX_DATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) va_list vargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dprintk(3, "%s() cmds = 0x%08x\n", __func__, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) va_start(vargs, outputcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) for (i = 0; i < inputcnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) data[i] = va_arg(vargs, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) err = cx23885_mbox_func(dev, command, inputcnt, outputcnt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) for (i = 0; i < outputcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int *vptr = va_arg(vargs, int *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) *vptr = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) va_end(vargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static int cx23885_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return cx23885_mbox_func(priv, cmd, in, out, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int cx23885_find_mailbox(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u32 signature[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 0x12345678, 0x34567812, 0x56781234, 0x78123456
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int signaturecnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) for (i = 0; i < CX23885_FIRM_IMAGE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) mc417_memory_read(dev, i, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (value == signature[signaturecnt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) signaturecnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) signaturecnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (4 == signaturecnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) dprintk(1, "Mailbox signature found at 0x%x\n", i+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return i+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pr_err("Mailbox signature values not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int cx23885_load_firmware(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static const unsigned char magic[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int i, retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) u32 gpio_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) u32 gpio_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) u32 checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) u32 *dataptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* Save GPIO settings before reset of APU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) retval |= mc417_memory_read(dev, 0x9020, &gpio_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) retval |= mc417_memory_read(dev, 0x900C, &gpio_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) retval = mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) IVTV_REG_VPU, 0xFFFFFFED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) retval |= mc417_register_write(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) IVTV_REG_APU, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) pr_err("%s: Error with mc417_register_write\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -1;
^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) retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) &dev->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) pr_err("ERROR: Hotplug firmware request failed (%s).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) CX23885_FIRM_IMAGE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) pr_err("ERROR: Firmware size mismatch (have %zu, expected %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) firmware->size, CX23885_FIRM_IMAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (0 != memcmp(firmware->data, magic, 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pr_err("ERROR: Firmware magic mismatch, wrong file?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* transfer to the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) dprintk(2, "Loading firmware ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) dataptr = (u32 *)firmware->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) for (i = 0; i < (firmware->size >> 2); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) value = *dataptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) checksum += ~value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (mc417_memory_write(dev, i, value) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) pr_err("ERROR: Loading firmware failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dataptr++;
^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) /* read back to verify with the checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dprintk(1, "Verifying firmware ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) for (i--; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (mc417_memory_read(dev, i, &value) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pr_err("ERROR: Reading firmware failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) checksum -= ~value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) pr_err("ERROR: Firmware load failed (checksum mismatch).\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) dprintk(1, "Firmware upload successful.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) IVTV_CMD_HW_BLOCKS_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* F/W power up disturbs the GPIOs, restore state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) retval |= mc417_register_write(dev, 0x9020, gpio_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) retval |= mc417_register_write(dev, 0x900C, gpio_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* Hardcoded GPIO's here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) retval |= mc417_register_write(dev, 0x9020, 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) retval |= mc417_register_write(dev, 0x900C, 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) mc417_register_read(dev, 0x9020, &gpio_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) mc417_register_read(dev, 0x900C, &gpio_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) pr_err("%s: Error with mc417_register_write\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) void cx23885_417_check_encoder(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) u32 status, seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) status = seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static void cx23885_codec_settings(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* Dynamically change the height based on video standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (dev->encodernorm.id & V4L2_STD_525_60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) dev->ts1.height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dev->ts1.height = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* assign frame size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dev->ts1.height, dev->ts1.width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dev->cxhdl.width = dev->ts1.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) dev->cxhdl.height = dev->ts1.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev->cxhdl.is_50hz =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) (dev->encodernorm.id & V4L2_STD_625_50) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) cx2341x_handler_setup(&dev->cxhdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) int version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) u32 i, data[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dprintk(2, "%s() PING OK\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) retval = cx23885_load_firmware(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pr_err("%s() f/w load failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) retval = cx23885_find_mailbox(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) pr_err("%s() mailbox < 0, error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) dev->cx23417_mailbox = retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) pr_err("ERROR: cx23417 firmware ping failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) &version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) pr_err("ERROR: cx23417 firmware get encoder :version failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) dprintk(1, "cx23417 firmware version is 0x%08x\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) cx23885_codec_settings(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* Setup to capture VBI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) data[0] = 0x0001BD00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) data[1] = 1; /* frames per interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) data[2] = 4; /* total bufs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) data[3] = 0x91559155; /* start codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) data[4] = 0x206080C0; /* stop codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) data[5] = 6; /* lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) data[6] = 64; /* BPL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) data[2], data[3], data[4], data[5], data[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) for (i = 2; i <= 24; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) valid = ((i >= 19) && (i <= 21));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) valid, 0 , 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) i | 0x80000000, valid, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) /* initialize the video input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* Enable VIP style pixel invalidation so we work with scaled mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) mc417_memory_write(dev, 2120, 0x00000080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /* start capturing to the host interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (startencoder) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static int queue_setup(struct vb2_queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) unsigned int *num_buffers, unsigned int *num_planes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) struct cx23885_dev *dev = q->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dev->ts1.ts_packet_size = mpeglinesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) dev->ts1.ts_packet_count = mpeglines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) *num_planes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) sizes[0] = mpeglinesize * mpeglines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) *num_buffers = mpegbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int buffer_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct cx23885_buffer *buf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) container_of(vbuf, struct cx23885_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return cx23885_buf_prepare(buf, &dev->ts1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static void buffer_finish(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct cx23885_buffer *buf = container_of(vbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct cx23885_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) cx23885_free_buffer(dev, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static void buffer_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct cx23885_buffer *buf = container_of(vbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct cx23885_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) cx23885_buf_queue(&dev->ts1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct cx23885_dev *dev = q->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) ret = cx23885_initialize_codec(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct cx23885_buffer *buf = list_entry(dmaq->active.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct cx23885_buffer, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) cx23885_start_dma(&dev->ts1, dmaq, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) while (!list_empty(&dmaq->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct cx23885_buffer *buf = list_entry(dmaq->active.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct cx23885_buffer, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) list_del(&buf->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static void cx23885_stop_streaming(struct vb2_queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct cx23885_dev *dev = q->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /* stop mpeg capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) CX23885_END_NOW, CX23885_MPEG_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) CX23885_RAW_BITS_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) cx23885_417_check_encoder(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) cx23885_cancel_buffers(&dev->ts1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static const struct vb2_ops cx23885_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .queue_setup = queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .buf_prepare = buffer_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .buf_finish = buffer_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .start_streaming = cx23885_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .stop_streaming = cx23885_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* ------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) *id = dev->tvnorm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (id & cx23885_tvnorms[i].id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (i == ARRAY_SIZE(cx23885_tvnorms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ret = cx23885_set_tvnorm(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) dev->encodernorm = cx23885_tvnorms[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct v4l2_input *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return cx23885_enum_input(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return cx23885_get_input(file, priv, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return cx23885_set_input(file, priv, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int vidioc_g_tuner(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (dev->tuner_type == TUNER_ABSENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (0 != t->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) strscpy(t->name, "Television", sizeof(t->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) call_all(dev, tuner, g_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static int vidioc_s_tuner(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) const struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (dev->tuner_type == TUNER_ABSENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* Update the A/V core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) call_all(dev, tuner, s_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static int vidioc_g_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (dev->tuner_type == TUNER_ABSENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) f->type = V4L2_TUNER_ANALOG_TV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) f->frequency = dev->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) call_all(dev, tuner, g_frequency, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) static int vidioc_s_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) const struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return cx23885_set_frequency(file, priv, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static int vidioc_querycap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct cx23885_tsport *tsport = &dev->ts1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) strscpy(cap->driver, dev->name, sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) strscpy(cap->card, cx23885_boards[tsport->dev->board].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) V4L2_CAP_STREAMING | V4L2_CAP_VBI_CAPTURE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) V4L2_CAP_AUDIO | V4L2_CAP_DEVICE_CAPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (dev->tuner_type != TUNER_ABSENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) cap->capabilities |= V4L2_CAP_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (f->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) f->pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) f->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) f->fmt.pix.sizeimage =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) f->fmt.pix.colorspace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) f->fmt.pix.width = dev->ts1.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) f->fmt.pix.height = dev->ts1.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) dev->ts1.width, dev->ts1.height);
^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 int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) f->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) f->fmt.pix.sizeimage =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) f->fmt.pix.colorspace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) dev->ts1.width, dev->ts1.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) f->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) f->fmt.pix.sizeimage =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) f->fmt.pix.colorspace = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static int vidioc_log_status(struct file *file, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct cx23885_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) char name[32 + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) snprintf(name, sizeof(name), "%s/2", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) call_all(dev, core, log_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static const struct v4l2_file_operations mpeg_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .open = v4l2_fh_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .release = vb2_fop_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .vidioc_enum_input = vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .vidioc_g_input = vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .vidioc_s_input = vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .vidioc_g_tuner = vidioc_g_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .vidioc_s_tuner = vidioc_s_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .vidioc_g_frequency = vidioc_g_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .vidioc_s_frequency = vidioc_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) .vidioc_querycap = vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .vidioc_log_status = vidioc_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .vidioc_g_chip_info = cx23885_g_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .vidioc_g_register = cx23885_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .vidioc_s_register = cx23885_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) static struct video_device cx23885_mpeg_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .name = "cx23885",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .fops = &mpeg_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .ioctl_ops = &mpeg_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) .tvnorms = CX23885_NORMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) void cx23885_417_unregister(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (dev->v4l_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (video_is_registered(dev->v4l_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) video_unregister_device(dev->v4l_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) video_device_release(dev->v4l_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) dev->v4l_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static struct video_device *cx23885_video_dev_alloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct cx23885_tsport *tsport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) struct video_device *template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) struct video_device *vfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) struct cx23885_dev *dev = tsport->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) vfd = video_device_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (NULL == vfd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) *vfd = *template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) cx23885_boards[tsport->dev->board].name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) vfd->v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) vfd->release = video_device_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return vfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) int cx23885_417_register(struct cx23885_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* FIXME: Port1 hardcoded here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) int err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct cx23885_tsport *tsport = &dev->ts1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct vb2_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (cx23885_boards[dev->board].portb != CX23885_MPEG_ENCODER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /* Set default TV standard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) dev->encodernorm = cx23885_tvnorms[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (dev->encodernorm.id & V4L2_STD_525_60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) tsport->height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) tsport->height = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) tsport->width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) dev->cxhdl.port = CX2341X_PORT_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) err = cx2341x_handler_init(&dev->cxhdl, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) dev->cxhdl.priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) dev->cxhdl.func = cx23885_api_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /* Allocate and initialize V4L video device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) dev->v4l_device = cx23885_video_dev_alloc(tsport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) dev->pci, &cx23885_mpeg_template, "mpeg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) q = &dev->vb2_mpegq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) q->gfp_flags = GFP_DMA32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) q->min_buffers_needed = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) q->drv_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) q->buf_struct_size = sizeof(struct cx23885_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) q->ops = &cx23885_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) q->mem_ops = &vb2_dma_sg_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) q->lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) q->dev = &dev->pci->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) err = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) video_set_drvdata(dev->v4l_device, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dev->v4l_device->lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) dev->v4l_device->queue = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) dev->v4l_device->device_caps = V4L2_CAP_VIDEO_CAPTURE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (dev->tuner_type != TUNER_ABSENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) dev->v4l_device->device_caps |= V4L2_CAP_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) err = video_register_device(dev->v4l_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) pr_info("%s: can't register mpeg device\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) pr_info("%s: registered device %s [mpeg]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) dev->name, video_device_node_name(dev->v4l_device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /* ST: Configure the encoder parameters, but don't begin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) * encoding, this resolves an issue where the first time the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) * encoder is started video can be choppy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) cx23885_initialize_codec(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) MODULE_FIRMWARE(CX23885_FIRM_IMAGE_NAME);