1 /* $NetBSD: dtvvar.h,v 1.6 2011/08/09 01:42:24 jmcneill Exp $ */
2 
3 /*-
4  * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *        This product includes software developed by Jared D. McNeill.
18  * 4. Neither the name of The NetBSD Foundation nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifndef _DEV_DTV_DTVVAR_H
36 #define _DEV_DTV_DTVVAR_H
37 
38 #include <dev/dtv/dtvif.h>
39 #include <dev/dtv/dtv_scatter.h>
40 
41 #define   DTV_DEFAULT_BLOCKSIZE         (32 * PAGE_SIZE)
42 #define   DTV_DEFAULT_BUFSIZE (32 * DTV_DEFAULT_BLOCKSIZE)
43 
44 #define   TS_PKTLEN           188
45 #define   TS_HAS_SYNC(_tspkt) ((_tspkt)[0] == 0x47)
46 #define   TS_HAS_PUSI(_tspkt) ((_tspkt)[1] & 0x40)
47 #define   TS_HAS_AF(_tspkt)   ((_tspkt)[3] & 0x20)
48 #define   TS_HAS_PAYLOAD(_tspkt)        ((_tspkt)[3] & 0x10)
49 #define   TS_PID(_tspkt)                ((((_tspkt)[1] & 0x1f) << 8) | (_tspkt)[2])
50 #define   TS_SECTION_MAXLEN   4096
51 
52 struct dtv_buffer {
53           uint32_t  db_offset;
54           uint32_t  db_bytesused;
55           size_t              db_length;
56           SIMPLEQ_ENTRY(dtv_buffer) db_entries;
57 };
58 
59 SIMPLEQ_HEAD(dtv_sample_queue, dtv_buffer);
60 
61 struct dtv_stream {
62           unsigned int                  ds_nbufs;
63           struct dtv_buffer   **ds_buf;
64           struct dtv_scatter_buf        ds_data;
65           struct dtv_sample_queue       ds_ingress, ds_egress;
66           kmutex_t            ds_ingress_lock, ds_egress_lock;
67           kcondvar_t                    ds_sample_cv;
68           struct selinfo                ds_sel;
69           uint32_t            ds_bytesread;
70 };
71 
72 typedef enum {
73           DTV_DEMUX_MODE_NONE,
74           DTV_DEMUX_MODE_SECTION,
75           DTV_DEMUX_MODE_PES,
76 } dtv_demux_mode_t;
77 
78 struct dtv_ts_section {
79           uint8_t                       sec_buf[TS_SECTION_MAXLEN];
80           uint16_t            sec_bytesused;
81           uint16_t            sec_length;
82 };
83 
84 struct dtv_demux {
85           struct dtv_softc    *dd_sc;
86           struct selinfo                dd_sel;
87           kmutex_t            dd_lock;
88           kcondvar_t                    dd_section_cv;
89 
90           bool                          dd_running;
91 
92           dtv_demux_mode_t    dd_mode;
93           struct {
94                     struct dmx_sct_filter_params  params;
95                     struct dtv_ts_section                   section[16];
96                     unsigned int                            rp, wp;
97                     unsigned int                            nsections;
98                     bool                                    overflow;
99           } dd_secfilt;
100 
101           TAILQ_ENTRY(dtv_demux)        dd_entries;
102 };
103 
104 struct dtv_ts {
105           uint8_t                       ts_pidfilter[0x2000];
106           kmutex_t            ts_lock;
107 };
108 
109 struct dtv_softc {
110           device_t  sc_dev;
111           const struct dtv_hw_if *sc_hw;
112           void                *sc_priv;
113 
114           bool                sc_dying;
115 
116           unsigned int        sc_open;
117           kmutex_t  sc_lock;
118 
119           size_t              sc_bufsize;
120           bool                sc_bufsize_chg;
121 
122           struct dtv_stream sc_stream;
123           struct dtv_ts       sc_ts;
124 
125           TAILQ_HEAD(, dtv_demux) sc_demux_list;
126           kmutex_t  sc_demux_lock;
127           int                 sc_demux_runcnt;
128 };
129 
130 #define   dtv_device_get_devinfo(sc, info)        \
131           ((sc)->sc_hw->get_devinfo((sc)->sc_priv, (info)))
132 #define   dtv_device_open(sc, flags)              \
133           ((sc)->sc_hw->open((sc)->sc_priv, (flags)))
134 #define   dtv_device_close(sc)                              \
135           ((sc)->sc_hw->close((sc)->sc_priv))
136 #define   dtv_device_set_tuner(sc, params)        \
137           ((sc)->sc_hw->set_tuner((sc)->sc_priv, (params)))
138 #define   dtv_device_get_status(sc)               \
139           ((sc)->sc_hw->get_status((sc)->sc_priv))
140 #define   dtv_device_get_signal_strength(sc)      \
141           ((sc)->sc_hw->get_signal_strength((sc)->sc_priv))
142 #define   dtv_device_get_snr(sc)                            \
143           ((sc)->sc_hw->get_snr((sc)->sc_priv))
144 #define   dtv_device_start_transfer(sc) \
145           ((sc)->sc_hw->start_transfer((sc)->sc_priv, dtv_buffer_submit, (sc)))
146 #define   dtv_device_stop_transfer(sc)            \
147           ((sc)->sc_hw->stop_transfer((sc)->sc_priv))
148 
149 int       dtv_frontend_ioctl(struct dtv_softc *, u_long, void *, int);
150 
151 int       dtv_demux_open(struct dtv_softc *, int, int, lwp_t *);
152 void      dtv_demux_write(struct dtv_softc *, const uint8_t *, size_t);
153 
154 int       dtv_buffer_realloc(struct dtv_softc *, size_t);
155 int       dtv_buffer_setup(struct dtv_softc *);
156 int       dtv_buffer_destroy(struct dtv_softc *);
157 int       dtv_buffer_read(struct dtv_softc *, struct uio *, int);
158 int       dtv_buffer_poll(struct dtv_softc *, int, lwp_t *);
159 void      dtv_buffer_submit(void *, const struct dtv_payload *);
160 
161 void      dtv_common_close(struct dtv_softc *);
162 
163 #endif /* !_DEV_DTV_DTVVAR_H */
164