2 * VIDIX driver for VIA CLE266/Unichrome chipsets.
4 * Copyright (C) 2004 Timothy Lee
5 * Thanks to Gilles Frattini for bugfixes
6 * Doxygen documentation by Benjamin Zores <ben@geexbox.org>
7 * h/w revision detection by Timothy Lee <timothy.lee@siriushk.com>
9 * This file is part of MPlayer.
11 * MPlayer is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * MPlayer is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #include "pci_names.h"
40 #include "unichrome_regs.h"
43 * @brief Information on PCI device.
45 static pciinfo_t pci_info
;
48 * @brief Unichrome driver colorkey settings.
50 static vidix_grkey_t uc_grkey
;
52 static int frames
[VID_PLAY_MAXFRAMES
];
54 static uint8_t *uc_mem
;
55 static uint8_t mclk_save
[3];
58 #define VIA_OUT(hwregs, reg, val) *(volatile uint32_t *)((hwregs) + (reg)) = (val)
59 #define VIA_IN(hwregs, reg) *(volatile uint32_t *)((hwregs) + (reg))
60 #define VGA_OUT8(hwregs, reg, val) *(volatile uint8_t *)((hwregs) + (reg) + 0x8000) = (val)
61 #define VGA_IN8(hwregs, reg) *(volatile uint8_t *)((hwregs) + (reg) + 0x8000)
62 #define VIDEO_OUT(hwregs, reg, val) VIA_OUT((hwregs)+0x200, reg, val)
63 #define VIDEO_IN(hwregs, reg) VIA_IN((hwregs)+0x200, reg)
65 #define outb(val,reg) OUTPORT8(reg,val)
66 #define inb(reg) INPORT8(reg)
68 #define ALIGN_TO(v, n) (((v) + (n-1)) & ~(n-1))
69 #define UC_MAP_V1_FIFO_CONTROL(depth, pre_thr, thr) \
70 (((depth)-1) | ((thr) << 8) | ((pre_thr) << 24))
72 #define VIDEOMEMORY_SIZE (8 * 1024 * 1024)
73 #define FRAMEBUFFER_SIZE 0x200000
74 #define FRAMEBUFFER_START (VIDEOMEMORY_SIZE - FRAMEBUFFER_SIZE)
77 static FILE *logfile
= 0;
78 #define LOGWRITE(x) {if(logfile) fprintf(logfile,x);}
84 * @brief Unichrome driver vidix capabilities.
86 static vidix_capability_t uc_cap
= {
87 "VIA CLE266 Unichrome driver",
88 "Timothy Lee <timothy@siriushk.com>",
96 FLAG_UPSCALER
| FLAG_DOWNSCALER
,
103 * @brief list of card IDs compliant with the Unichrome driver .
105 static unsigned short uc_card_ids
[] = {
106 DEVICE_VIA2_VT8623_APOLLO_CLE266
,
107 DEVICE_VIA2_VT8378_S3_UNICHROME
111 * @brief Find chip index in Unichrome compliant devices list.
113 * @param chip_id PCI device ID.
115 * @returns index position in uc_card_ids if successful.
116 * -1 if chip_id is not a compliant chipset ID.
119 find_chip (unsigned chip_id
)
122 for (i
= 0; i
< sizeof (uc_card_ids
) / sizeof (unsigned short); i
++)
124 if (chip_id
== uc_card_ids
[i
])
131 * @brief Map hardware settings for vertical scaling.
133 * @param sh source height.
134 * @param dh destination height.
135 * @param zoom will hold vertical setting of zoom register.
136 * @param mini will hold vertical setting of mini register.
138 * @returns 1 if successful.
139 * 0 if the zooming factor is too large or small.
141 * @note Derived from VIA's V4L driver.
142 * See ddover.c, DDOVER_HQVCalcZoomHeight()
145 uc_ovl_map_vzoom (uint32_t sh
, uint32_t dh
, uint32_t * zoom
, uint32_t * mini
)
147 uint32_t sh1
, tmp
, d
;
150 if (sh
== dh
) /* No zoom */
154 else if (sh
< dh
) /* Zoom in */
156 tmp
= (sh
* 0x0400) / dh
;
157 zoom_ok
= !(tmp
> 0x3ff);
159 *zoom
|= (tmp
& 0x3ff) | V1_Y_ZOOM_ENABLE
;
160 *mini
|= V1_Y_INTERPOLY
| V1_YCBCR_INTERPOLY
;
162 else /* sw > dh - Zoom out */
164 /* Find a suitable divider (1 << d) = {2, 4, 8 or 16} */
166 for (d
= 1; d
< 5; d
++)
172 if (d
== 5) /* too small */
178 *mini
|= ((d
<< 1) - 1) << 16; /* <= {1,3,5,7} << 16 */
183 tmp
= (sh1
* 0x400) / dh
;
184 *zoom
|= ((tmp
& 0x3ff) | V1_Y_ZOOM_ENABLE
);
185 *mini
|= V1_Y_INTERPOLY
| V1_YCBCR_INTERPOLY
;
193 * @brief Map hardware settings for horizontal scaling.
195 * @param sw source width.
196 * @param dw destination width.
197 * @param zoom will hold horizontal setting of zoom register.
198 * @param mini will hold horizontal setting of mini register.
199 * @param falign will hold fetch aligment.
200 * @param dcount will hold display count.
202 * @returns 1 if successful.
203 * 0 if the zooming factor is too large or small.
205 * @note Derived from VIA's V4L driver.
206 * See ddover.c, DDOVER_HQVCalcZoomWidth() and DDOver_GetDisplayCount()
209 uc_ovl_map_hzoom (uint32_t sw
, uint32_t dw
, uint32_t * zoom
, uint32_t * mini
,
210 int *falign
, int *dcount
)
212 uint32_t tmp
, sw1
, d
;
213 int md
; /* Minify-divider */
219 if (sw
== dw
) /* no zoom */
223 else if (sw
< dw
) /* zoom in */
225 tmp
= (sw
* 0x0800) / dw
;
226 zoom_ok
= !(tmp
> 0x7ff);
228 *zoom
|= ((tmp
& 0x7ff) << 16) | V1_X_ZOOM_ENABLE
;
229 *mini
|= V1_X_INTERPOLY
;
231 else /* sw > dw - Zoom out */
233 /* Find a suitable divider (1 << d) = {2, 4, 8 or 16} */
235 for (d
= 1; d
< 5; d
++)
241 if (d
== 5) /* too small */
247 md
= 1 << d
; /* <= {2,4,8,16} */
248 *falign
= ((md
<< 1) - 1) & 0xf; /* <= {3,7,15,15} */
249 *mini
|= V1_X_INTERPOLY
;
250 *mini
|= ((d
<< 1) - 1) << 24; /* <= {1,3,5,7} << 24 */
256 /* tmp = sw1*0x0800 / dw; */
257 tmp
= (sw1
- 2) * 0x0800 / dw
;
258 *zoom
|= ((tmp
& 0x7ff) << 16) | V1_X_ZOOM_ENABLE
;
267 * @brief qword fetch register setting.
269 * @param format overlay pixel format.
270 * @param sw source width.
272 * @return qword fetch register setting
274 * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetFetch()
275 * @note Only call after uc_ovl_map_hzoom()
278 uc_ovl_map_qwfetch (uint32_t format
, int sw
)
286 fetch
= ALIGN_TO (sw
, 32) >> 4;
291 fetch
= (ALIGN_TO (sw
<< 1, 16) >> 4) + 1;
295 fetch
= (ALIGN_TO (sw
<< 1, 16) >> 4) + 1;
298 fetch
= (ALIGN_TO (sw
<< 2, 16) >> 4) + 1;
301 printf ("[unichrome] Unexpected pixelformat!");
312 * @brief Map pixel format.
314 * @param format pixel format.
316 * @return the mapped pixel format.
318 * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetV1Format()
321 uc_ovl_map_format (uint32_t format
)
328 return V1_COLORSPACE_SIGN
| V1_YUV422
;
330 return V1_COLORSPACE_SIGN
| V1_YCbCr420
| V1_SWAP_SW
;
333 return V1_COLORSPACE_SIGN
| V1_YCbCr420
;
341 printf ("[unichrome] Unexpected pixelformat!");
347 * @brief Calculate V1 control and fifo-control register values.
349 * @param format pixel format.
350 * @param sw source width.
351 * @param hwrev CLE266 hardware revision.
352 * @param extfifo_on set this 1 if the extended FIFO is enabled.
353 * @param control will hold value for V1_CONTROL.
354 * @param fifo will hold value for V1_FIFO_CONTROL.
357 uc_ovl_map_v1_control (uint32_t format
, int sw
,
358 int hwrev
, int extfifo_on
,
359 uint32_t * control
, uint32_t * fifo
)
361 *control
= V1_BOB_ENABLE
| uc_ovl_map_format (format
);
365 *control
|= V1_EXPIRE_NUM_F
;
371 *control
|= V1_EXPIRE_NUM_A
| V1_FIFO_EXTENDED
;
375 *control
|= V1_EXPIRE_NUM
;
379 if ((format
== IMGFMT_YV12
) || (format
== IMGFMT_I420
))
381 /* Minified video will be skewed without this workaround. */
382 if (sw
<= 80) /* Fetch count <= 5 */
384 *fifo
= UC_MAP_V1_FIFO_CONTROL (16, 0, 0);
389 *fifo
= UC_MAP_V1_FIFO_CONTROL (64, 56, 56);
391 *fifo
= UC_MAP_V1_FIFO_CONTROL (16, 12, 8);
398 *fifo
= UC_MAP_V1_FIFO_CONTROL (64, 56, 56); /* Default rev 0x10 */
403 *fifo
= UC_MAP_V1_FIFO_CONTROL (48, 40, 40);
405 *fifo
= UC_MAP_V1_FIFO_CONTROL (32, 29, 16); /* Default */
411 * @brief Setup extended FIFO.
413 * @param extfifo_on pointer determining if extended fifo is enable or not.
414 * @param dst_w destination width.
417 uc_ovl_setup_fifo (int *extfifo_on
, int dst_w
)
419 if (dst_w
<= 1024) /* Disable extended FIFO */
422 outb (mclk_save
[0], 0x3c5);
424 outb (mclk_save
[1], 0x3c5);
426 outb (mclk_save
[2], 0x3c5);
429 else /* Enable extended FIFO */
434 outb ((mclk_save
[0] & 0xf0) | 0x14, 0x3c5);
442 uc_ovl_vcmd_wait (volatile uint8_t * vio
)
444 while ((VIDEO_IN (vio
, V_COMPOSE_MODE
)
445 & (V1_COMMAND_FIRE
| V3_COMMAND_FIRE
)));
449 * @brief Probe hardware to find some useable chipset.
451 * @param verbose specifies verbose level.
452 * @param force specifies force mode : driver should ignore
453 * device_id (danger but useful for new devices)
455 * @returns 0 if it can handle something in PC.
456 * a negative error code otherwise.
459 unichrome_probe (int verbose
, int force
)
461 pciinfo_t lst
[MAX_PCI_DEVICES
];
464 err
= pci_scan (lst
, &num_pci
);
467 printf ("[unichrome] Error occurred during pci scan: %s\n",
474 for (i
= 0; i
< num_pci
; i
++)
476 if (lst
[i
].vendor
== VENDOR_VIA2
)
480 idx
= find_chip (lst
[i
].device
);
483 dname
= pci_device_name (VENDOR_VIA2
, lst
[i
].device
);
484 dname
= dname
? dname
: "Unknown chip";
485 printf ("[unichrome] Found chip: %s\n", dname
);
486 if ((lst
[i
].command
& PCI_COMMAND_IO
) == 0)
488 printf ("[unichrome] Device is disabled, ignoring\n");
491 uc_cap
.device_id
= lst
[i
].device
;
493 memcpy (&pci_info
, &lst
[i
], sizeof (pciinfo_t
));
500 printf ("[unichrome] Can't find chip\n");
505 * @brief Initializes driver.
508 * a negative error code otherwise.
511 unichrome_init (void)
514 uc_mem
= map_phys_mem (pci_info
.base0
, VIDEOMEMORY_SIZE
);
518 tmp
= inb (0x3c5) << 0x18;
519 vio
= map_phys_mem (tmp
, 0x1000);
522 mclk_save
[0] = inb (0x3c5);
524 mclk_save
[1] = inb (0x3c5);
526 mclk_save
[2] = inb (0x3c5);
528 uc_grkey
.ckey
.blue
= 0x00;
529 uc_grkey
.ckey
.green
= 0x00;
530 uc_grkey
.ckey
.red
= 0x00;
532 /* Detect whether we have a CLE266Ax or CLE266Cx */
538 if (0x55 == inb (0x3d5))
540 /* Only CLE266Cx supports CR4F */
545 /* Otherwise assume to be a CLE266Ax */
552 logfile
= fopen ("/tmp/uc_vidix.log", "w");
558 * @brief Destroys driver.
561 unichrome_destroy (void)
568 outb (mclk_save
[0], 0x3c5);
570 outb (mclk_save
[1], 0x3c5);
572 outb (mclk_save
[2], 0x3c5);
575 unmap_phys_mem (uc_mem
, VIDEOMEMORY_SIZE
);
576 unmap_phys_mem (vio
, 0x1000);
580 * @brief Get chipset's hardware capabilities.
582 * @param to Pointer to the vidix_capability_t structure to be filled.
587 unichrome_get_caps (vidix_capability_t
* to
)
589 memcpy (to
, &uc_cap
, sizeof (vidix_capability_t
));
594 * @brief Report if the video FourCC is supported by hardware.
596 * @param fourcc input image format.
598 * @returns 1 if the fourcc is supported.
602 is_supported_fourcc (uint32_t fourcc
)
621 * @brief Try to configure video memory for given fourcc.
623 * @param to Pointer to the vidix_fourcc_t structure to be filled.
629 unichrome_query_fourcc (vidix_fourcc_t
* to
)
631 if (is_supported_fourcc (to
->fourcc
))
633 to
->depth
= VID_DEPTH_ALL
;
634 to
->flags
= VID_CAP_EXPAND
| VID_CAP_SHRINK
| VID_CAP_COLORKEY
;
638 to
->depth
= to
->flags
= 0;
643 * @brief Get the GrKeys
645 * @param grkey Pointer to the vidix_grkey_t structure to be filled by driver.
650 unichrome_get_gkey (vidix_grkey_t
* grkey
)
652 memcpy (grkey
, &uc_grkey
, sizeof (vidix_grkey_t
));
657 * @brief Set the GrKeys
659 * @param grkey Colorkey to be set.
664 unichrome_set_gkey (const vidix_grkey_t
* grkey
)
666 unsigned long dwCompose
= VIDEO_IN (vio
, V_COMPOSE_MODE
) & ~0x0f;
667 memcpy (&uc_grkey
, grkey
, sizeof (vidix_grkey_t
));
668 if (uc_grkey
.ckey
.op
!= CKEY_FALSE
)
670 /* Set colorkey (how do I detect BPP in hardware ??) */
672 if (1) /* Assume 16-bit graphics */
674 ckey
= (grkey
->ckey
.blue
& 0x1f)
675 | ((grkey
->ckey
.green
& 0x3f) << 5)
676 | ((grkey
->ckey
.red
& 0x1f) << 11);
680 ckey
= (grkey
->ckey
.blue
)
681 | (grkey
->ckey
.green
<< 8) | (grkey
->ckey
.red
<< 16);
683 VIDEO_OUT (vio
, V_COLOR_KEY
, ckey
);
684 dwCompose
|= SELECT_VIDEO_IF_COLOR_KEY
;
687 /* Execute the changes */
688 VIDEO_OUT (vio
, V_COMPOSE_MODE
, dwCompose
| V1_COMMAND_FIRE
);
693 * @brief Unichrome driver equalizer capabilities.
695 static vidix_video_eq_t equal
= {
696 VEQ_CAP_BRIGHTNESS
| VEQ_CAP_SATURATION
| VEQ_CAP_HUE
,
697 300, 100, 0, 0, 0, 0, 0, 0
702 * @brief Get the equalizer capabilities.
704 * @param eq Pointer to the vidix_video_eq_t structure to be filled by driver.
709 unichrome_get_eq (vidix_video_eq_t
* eq
)
711 memcpy (eq
, &equal
, sizeof (vidix_video_eq_t
));
716 * @brief Set the equalizer capabilities for color correction
718 * @param eq equalizer capabilities to be set.
723 unichrome_set_eq (const vidix_video_eq_t
* eq
)
729 * @brief Y, U, V offsets.
731 static int YOffs
, UOffs
, VOffs
;
733 static int unichrome_frame_select (unsigned int frame
);
736 * @brief Configure driver for playback. Driver should prepare BES.
738 * @param info configuration description for playback.
740 * @returns 0 in case of success.
744 unichrome_config_playback (vidix_playback_t
* info
)
748 long base0
, pitch
= 0;
749 int uv_size
= 0, swap_uv
;
753 /* Overlay register settings */
754 uint32_t win_start
, win_end
;
756 uint32_t dcount
, falign
, qwfetch
;
757 uint32_t v_ctrl
, fifo_ctrl
;
759 if (!is_supported_fourcc (info
->fourcc
))
765 drw_w
= info
->dest
.w
;
766 drw_h
= info
->dest
.h
;
769 uc_ovl_setup_fifo (&extfifo_on
, src_w
);
771 /* Get image format, FIFO size, etc. */
772 uc_ovl_map_v1_control (info
->fourcc
, src_w
, hwrev
, extfifo_on
,
773 &v_ctrl
, &fifo_ctrl
);
775 /* Setup layer window */
776 win_start
= (info
->dest
.x
<< 16) | info
->dest
.y
;
777 win_end
= ((info
->dest
.x
+ drw_w
- 1) << 16) | (info
->dest
.y
+ drw_h
- 1);
779 /* Get scaling and data-fetch parameters */
782 uc_ovl_map_vzoom (src_h
, drw_h
, &zoom
, &mini
);
783 uc_ovl_map_hzoom (src_w
, drw_w
, &zoom
, &mini
, (int *) &falign
, (int *) &dcount
);
784 qwfetch
= uc_ovl_map_qwfetch (info
->fourcc
, src_w
);
786 /* Calculate buffer sizes */
788 switch (info
->fourcc
)
795 pitch
= ALIGN_TO (src_w
, 32);
796 uv_size
= (pitch
>> 1) * (src_h
>> 1);
802 pitch
= ALIGN_TO (src_w
<< 1, 32);
807 pitch
= ALIGN_TO (src_w
<< 2, 32);
811 if ((src_w
> 4096) || (src_h
> 4096) ||
812 (src_w
< 32) || (src_h
< 1) || (pitch
> 0x1fff))
814 printf ("[unichrome] Layer size out of bounds\n");
817 /* Calculate offsets */
819 info
->offset
.v
= info
->offset
.y
+ pitch
* src_h
;
820 info
->offset
.u
= info
->offset
.v
+ uv_size
;
821 info
->frame_size
= info
->offset
.u
+ uv_size
;
822 YOffs
= info
->offset
.y
;
823 UOffs
= (swap_uv
? info
->offset
.v
: info
->offset
.u
);
824 VOffs
= (swap_uv
? info
->offset
.u
: info
->offset
.v
);
826 /* Assume we have 2 MB to play with */
827 info
->num_frames
= FRAMEBUFFER_SIZE
/ info
->frame_size
;
828 if (info
->num_frames
> VID_PLAY_MAXFRAMES
)
829 info
->num_frames
= VID_PLAY_MAXFRAMES
;
831 /* Start at 6 MB. Let's hope it's not in use. */
832 base0
= FRAMEBUFFER_START
;
833 info
->dga_addr
= uc_mem
+ base0
;
835 info
->dest
.pitch
.y
= 32;
836 info
->dest
.pitch
.u
= 32;
837 info
->dest
.pitch
.v
= 32;
839 for (i
= 0; i
< info
->num_frames
; i
++)
841 info
->offsets
[i
] = info
->frame_size
* i
;
842 frames
[i
] = base0
+ info
->offsets
[i
];
845 /* Write to the hardware */
846 uc_ovl_vcmd_wait (vio
);
848 /* Configure diy_pitchlay parameters now */
849 if (v_ctrl
& V1_COLORSPACE_SIGN
)
853 VIDEO_OUT (vio
, V1_ColorSpaceReg_2
, ColorSpaceValue_2_3123C0
);
854 VIDEO_OUT (vio
, V1_ColorSpaceReg_1
, ColorSpaceValue_1_3123C0
);
858 VIDEO_OUT (vio
, V1_ColorSpaceReg_2
, ColorSpaceValue_2
);
859 VIDEO_OUT (vio
, V1_ColorSpaceReg_1
, ColorSpaceValue_1
);
863 VIDEO_OUT (vio
, V1_CONTROL
, v_ctrl
);
864 VIDEO_OUT (vio
, V_FIFO_CONTROL
, fifo_ctrl
);
866 VIDEO_OUT (vio
, V1_WIN_START_Y
, win_start
);
867 VIDEO_OUT (vio
, V1_WIN_END_Y
, win_end
);
869 VIDEO_OUT (vio
, V1_SOURCE_HEIGHT
, (src_h
<< 16) | dcount
);
871 VIDEO_OUT (vio
, V12_QWORD_PER_LINE
, qwfetch
<< 20);
872 VIDEO_OUT (vio
, V1_STRIDE
, pitch
| ((pitch
>> 1) << 16));
874 VIDEO_OUT (vio
, V1_MINI_CONTROL
, mini
);
875 VIDEO_OUT (vio
, V1_ZOOM_CONTROL
, zoom
);
877 /* Configure buffer address and execute the changes now! */
878 unichrome_frame_select (0);
884 * @brief Set playback on : driver should activate BES on this call.
889 unichrome_playback_on (void)
891 LOGWRITE ("Enable overlay\n");
893 /* Turn on overlay */
894 VIDEO_OUT (vio
, V1_CONTROL
, VIDEO_IN (vio
, V1_CONTROL
) | V1_ENABLE
);
896 /* Execute the changes */
897 VIDEO_OUT (vio
, V_COMPOSE_MODE
,
898 VIDEO_IN (vio
, V_COMPOSE_MODE
) | V1_COMMAND_FIRE
);
904 * @brief Set playback off : driver should deactivate BES on this call.
909 unichrome_playback_off (void)
911 LOGWRITE ("Disable overlay\n");
913 uc_ovl_vcmd_wait (vio
);
916 VIDEO_OUT (vio
, V_FIFO_CONTROL
, UC_MAP_V1_FIFO_CONTROL (16, 12, 8));
918 /* Turn off overlay */
919 VIDEO_OUT (vio
, V1_CONTROL
, VIDEO_IN (vio
, V1_CONTROL
) & ~V1_ENABLE
);
921 /* Execute the changes */
922 VIDEO_OUT (vio
, V_COMPOSE_MODE
,
923 VIDEO_IN (vio
, V_COMPOSE_MODE
) | V1_COMMAND_FIRE
);
929 * @brief Driver should prepare and activate corresponded frame.
931 * @param frame the frame index.
935 * @note This function is used only for double and triple buffering
936 * and never used for single buffering playback.
939 unichrome_frame_select (unsigned int frame
)
941 LOGWRITE ("Frame select\n");
943 uc_ovl_vcmd_wait (vio
);
945 /* Configure buffer address */
946 VIDEO_OUT (vio
, V1_STARTADDR_Y0
, frames
[frame
] + YOffs
);
947 VIDEO_OUT (vio
, V1_STARTADDR_CB0
, frames
[frame
] + UOffs
);
948 VIDEO_OUT (vio
, V1_STARTADDR_CR0
, frames
[frame
] + VOffs
);
950 /* Execute the changes */
951 VIDEO_OUT (vio
, V_COMPOSE_MODE
,
952 VIDEO_IN (vio
, V_COMPOSE_MODE
) | V1_COMMAND_FIRE
);
957 VDXDriver unichrome_drv
= {
960 .probe
= unichrome_probe
,
961 .get_caps
= unichrome_get_caps
,
962 .query_fourcc
= unichrome_query_fourcc
,
963 .init
= unichrome_init
,
964 .destroy
= unichrome_destroy
,
965 .config_playback
= unichrome_config_playback
,
966 .playback_on
= unichrome_playback_on
,
967 .playback_off
= unichrome_playback_off
,
968 .frame_sel
= unichrome_frame_select
,
969 .get_eq
= unichrome_get_eq
,
970 .set_eq
= unichrome_set_eq
,
971 .get_gkey
= unichrome_get_gkey
,
972 .set_gkey
= unichrome_set_gkey
,