xref: /netbsd/sys/dev/dtv/dtv_ioctl.c (revision 1308e7f6)
1*1308e7f6Sjmcneill /* $NetBSD: dtv_ioctl.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
2*1308e7f6Sjmcneill 
3*1308e7f6Sjmcneill /*-
4*1308e7f6Sjmcneill  * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5*1308e7f6Sjmcneill  * All rights reserved.
6*1308e7f6Sjmcneill  *
7*1308e7f6Sjmcneill  * Redistribution and use in source and binary forms, with or without
8*1308e7f6Sjmcneill  * modification, are permitted provided that the following conditions
9*1308e7f6Sjmcneill  * are met:
10*1308e7f6Sjmcneill  * 1. Redistributions of source code must retain the above copyright
11*1308e7f6Sjmcneill  *    notice, this list of conditions and the following disclaimer.
12*1308e7f6Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
13*1308e7f6Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
14*1308e7f6Sjmcneill  *    documentation and/or other materials provided with the distribution.
15*1308e7f6Sjmcneill  * 3. All advertising materials mentioning features or use of this software
16*1308e7f6Sjmcneill  *    must display the following acknowledgement:
17*1308e7f6Sjmcneill  *        This product includes software developed by Jared D. McNeill.
18*1308e7f6Sjmcneill  * 4. Neither the name of The NetBSD Foundation nor the names of its
19*1308e7f6Sjmcneill  *    contributors may be used to endorse or promote products derived
20*1308e7f6Sjmcneill  *    from this software without specific prior written permission.
21*1308e7f6Sjmcneill  *
22*1308e7f6Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23*1308e7f6Sjmcneill  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*1308e7f6Sjmcneill  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25*1308e7f6Sjmcneill  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26*1308e7f6Sjmcneill  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27*1308e7f6Sjmcneill  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28*1308e7f6Sjmcneill  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29*1308e7f6Sjmcneill  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30*1308e7f6Sjmcneill  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31*1308e7f6Sjmcneill  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32*1308e7f6Sjmcneill  * POSSIBILITY OF SUCH DAMAGE.
33*1308e7f6Sjmcneill  */
34*1308e7f6Sjmcneill 
35*1308e7f6Sjmcneill #include <sys/cdefs.h>
36*1308e7f6Sjmcneill __KERNEL_RCSID(0, "$NetBSD: dtv_ioctl.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $");
37*1308e7f6Sjmcneill 
38*1308e7f6Sjmcneill #include <sys/param.h>
39*1308e7f6Sjmcneill #include <sys/types.h>
40*1308e7f6Sjmcneill #include <sys/conf.h>
41*1308e7f6Sjmcneill #include <sys/kmem.h>
42*1308e7f6Sjmcneill #include <sys/device.h>
43*1308e7f6Sjmcneill #include <sys/select.h>
44*1308e7f6Sjmcneill 
45*1308e7f6Sjmcneill #include <dev/dtv/dtvvar.h>
46*1308e7f6Sjmcneill 
47*1308e7f6Sjmcneill int
48*1308e7f6Sjmcneill dtv_frontend_ioctl(struct dtv_softc *sc, u_long cmd, void *data, int flags)
49*1308e7f6Sjmcneill {
50*1308e7f6Sjmcneill 	switch (cmd) {
51*1308e7f6Sjmcneill 	case FE_READ_STATUS:
52*1308e7f6Sjmcneill 		*(fe_status_t *)data = dtv_device_get_status(sc);
53*1308e7f6Sjmcneill 		return 0;
54*1308e7f6Sjmcneill 	case FE_READ_BER:
55*1308e7f6Sjmcneill 		*(uint32_t *)data = 0;	/* XXX TODO */
56*1308e7f6Sjmcneill 		return 0;
57*1308e7f6Sjmcneill 	case FE_READ_SNR:
58*1308e7f6Sjmcneill 		*(uint16_t *)data = dtv_device_get_snr(sc);
59*1308e7f6Sjmcneill 		return 0;
60*1308e7f6Sjmcneill 	case FE_READ_SIGNAL_STRENGTH:
61*1308e7f6Sjmcneill 		*(uint16_t *)data = dtv_device_get_signal_strength(sc);
62*1308e7f6Sjmcneill 		return 0;
63*1308e7f6Sjmcneill 	case FE_SET_FRONTEND:
64*1308e7f6Sjmcneill 		return dtv_device_set_tuner(sc, data);
65*1308e7f6Sjmcneill 	case FE_GET_INFO:
66*1308e7f6Sjmcneill 		dtv_device_get_devinfo(sc, data);
67*1308e7f6Sjmcneill 		return 0;
68*1308e7f6Sjmcneill 	default:
69*1308e7f6Sjmcneill 		return EINVAL;
70*1308e7f6Sjmcneill 	}
71*1308e7f6Sjmcneill }
72*1308e7f6Sjmcneill 
73*1308e7f6Sjmcneill int
74*1308e7f6Sjmcneill dtv_demux_ioctl(struct dtv_softc *sc, u_long cmd, void *data, int flags)
75*1308e7f6Sjmcneill {
76*1308e7f6Sjmcneill 	struct dmx_pes_filter_params *pesfilt;
77*1308e7f6Sjmcneill 	uint16_t pid;
78*1308e7f6Sjmcneill 	size_t bufsize;
79*1308e7f6Sjmcneill 	int error;
80*1308e7f6Sjmcneill 
81*1308e7f6Sjmcneill 	switch (cmd) {
82*1308e7f6Sjmcneill 	case DMX_START:
83*1308e7f6Sjmcneill 		if (sc->sc_bufsize_chg) {
84*1308e7f6Sjmcneill 			if ((error = dtv_buffer_setup(sc, sc->sc_bufsize)) != 0)
85*1308e7f6Sjmcneill 				return error;
86*1308e7f6Sjmcneill 			sc->sc_bufsize_chg = false;
87*1308e7f6Sjmcneill 		}
88*1308e7f6Sjmcneill 		return dtv_device_start_transfer(sc);
89*1308e7f6Sjmcneill 	case DMX_STOP:
90*1308e7f6Sjmcneill 		return dtv_device_stop_transfer(sc);
91*1308e7f6Sjmcneill 	case DMX_SET_BUFFER_SIZE:
92*1308e7f6Sjmcneill 		bufsize = *(uintptr_t *)data;
93*1308e7f6Sjmcneill 		if (bufsize >= DTV_DEFAULT_BUFSIZE &&
94*1308e7f6Sjmcneill 		    sc->sc_bufsize != bufsize) {
95*1308e7f6Sjmcneill 			sc->sc_bufsize = bufsize;
96*1308e7f6Sjmcneill 			sc->sc_bufsize_chg = true;
97*1308e7f6Sjmcneill 		}
98*1308e7f6Sjmcneill 		return 0;
99*1308e7f6Sjmcneill 	case DMX_SET_PES_FILTER:
100*1308e7f6Sjmcneill 		pesfilt = data;
101*1308e7f6Sjmcneill 
102*1308e7f6Sjmcneill 		if (pesfilt->input != DMX_IN_FRONTEND)
103*1308e7f6Sjmcneill 			return EINVAL;
104*1308e7f6Sjmcneill 		if (pesfilt->output != DMX_OUT_TS_TAP)
105*1308e7f6Sjmcneill 			return EINVAL;
106*1308e7f6Sjmcneill 		if (pesfilt->pes_type != DMX_PES_OTHER)
107*1308e7f6Sjmcneill 			return EINVAL;
108*1308e7f6Sjmcneill 
109*1308e7f6Sjmcneill 		error = dtv_demux_ioctl(sc, DMX_ADD_PID, &pesfilt->pid, flags);
110*1308e7f6Sjmcneill 		if (error)
111*1308e7f6Sjmcneill 			return error;
112*1308e7f6Sjmcneill 
113*1308e7f6Sjmcneill 		if (pesfilt->flags & DMX_IMMEDIATE_START) {
114*1308e7f6Sjmcneill 			error = dtv_demux_ioctl(sc, DMX_START, NULL, flags);
115*1308e7f6Sjmcneill 			if (error)
116*1308e7f6Sjmcneill 				return error;
117*1308e7f6Sjmcneill 		}
118*1308e7f6Sjmcneill 		return 0;
119*1308e7f6Sjmcneill 	case DMX_ADD_PID:
120*1308e7f6Sjmcneill 		pid = *(uint16_t *)data;
121*1308e7f6Sjmcneill 		if (pid > 0x2000)
122*1308e7f6Sjmcneill 			return EINVAL;
123*1308e7f6Sjmcneill 
124*1308e7f6Sjmcneill 		if (pid == 0x2000) {
125*1308e7f6Sjmcneill 			memset(sc->sc_ts.ts_pidfilter, 1,
126*1308e7f6Sjmcneill 			    sizeof(sc->sc_ts.ts_pidfilter));
127*1308e7f6Sjmcneill 		} else {
128*1308e7f6Sjmcneill 			sc->sc_ts.ts_pidfilter[pid] = 1;
129*1308e7f6Sjmcneill 		}
130*1308e7f6Sjmcneill 		return 0;
131*1308e7f6Sjmcneill 	case DMX_REMOVE_PID:
132*1308e7f6Sjmcneill 		pid = *(uint16_t *)data;
133*1308e7f6Sjmcneill 		if (pid > 0x2000)
134*1308e7f6Sjmcneill 			return EINVAL;
135*1308e7f6Sjmcneill 
136*1308e7f6Sjmcneill 		if (pid == 0x2000) {
137*1308e7f6Sjmcneill 			memset(sc->sc_ts.ts_pidfilter, 0,
138*1308e7f6Sjmcneill 			    sizeof(sc->sc_ts.ts_pidfilter));
139*1308e7f6Sjmcneill 		} else {
140*1308e7f6Sjmcneill 			sc->sc_ts.ts_pidfilter[pid] = 0;
141*1308e7f6Sjmcneill 		}
142*1308e7f6Sjmcneill 		return 0;
143*1308e7f6Sjmcneill 	default:
144*1308e7f6Sjmcneill 		return EINVAL;
145*1308e7f6Sjmcneill 	}
146*1308e7f6Sjmcneill }
147