• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *
4  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
5  *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21 
22 /*
23 
24    This source file is specifically designed to interface with the
25    wm8775.
26 
27 */
28 
29 #include "pvrusb2-wm8775.h"
30 #include "pvrusb2-i2c-cmd-v4l2.h"
31 
32 
33 #include "pvrusb2-hdw-internal.h"
34 #include "pvrusb2-debug.h"
35 #include <linux/videodev2.h>
36 #include <media/v4l2-common.h>
37 #include <linux/errno.h>
38 #include <linux/slab.h>
39 
40 struct pvr2_v4l_wm8775 {
41 	struct pvr2_i2c_handler handler;
42 	struct pvr2_i2c_client *client;
43 	struct pvr2_hdw *hdw;
44 	unsigned long stale_mask;
45 };
46 
47 
set_input(struct pvr2_v4l_wm8775 * ctxt)48 static void set_input(struct pvr2_v4l_wm8775 *ctxt)
49 {
50 	struct v4l2_routing route;
51 	struct pvr2_hdw *hdw = ctxt->hdw;
52 
53 	memset(&route,0,sizeof(route));
54 
55 	switch(hdw->input_val) {
56 	case PVR2_CVAL_INPUT_RADIO:
57 		route.input = 1;
58 		break;
59 	default:
60 		/* All other cases just use the second input */
61 		route.input = 2;
62 		break;
63 	}
64 	pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
65 		   hdw->input_val,route.input);
66 
67 	pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
68 }
69 
check_input(struct pvr2_v4l_wm8775 * ctxt)70 static int check_input(struct pvr2_v4l_wm8775 *ctxt)
71 {
72 	struct pvr2_hdw *hdw = ctxt->hdw;
73 	return hdw->input_dirty != 0;
74 }
75 
76 
77 struct pvr2_v4l_wm8775_ops {
78 	void (*update)(struct pvr2_v4l_wm8775 *);
79 	int (*check)(struct pvr2_v4l_wm8775 *);
80 };
81 
82 
83 static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
84 	{ .update = set_input, .check = check_input},
85 };
86 
87 
wm8775_describe(struct pvr2_v4l_wm8775 * ctxt,char * buf,unsigned int cnt)88 static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
89 				     char *buf,unsigned int cnt)
90 {
91 	return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
92 }
93 
94 
wm8775_detach(struct pvr2_v4l_wm8775 * ctxt)95 static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
96 {
97 	ctxt->client->handler = NULL;
98 	kfree(ctxt);
99 }
100 
101 
wm8775_check(struct pvr2_v4l_wm8775 * ctxt)102 static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
103 {
104 	unsigned long msk;
105 	unsigned int idx;
106 
107 	for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
108 		msk = 1 << idx;
109 		if (ctxt->stale_mask & msk) continue;
110 		if (wm8775_ops[idx].check(ctxt)) {
111 			ctxt->stale_mask |= msk;
112 		}
113 	}
114 	return ctxt->stale_mask != 0;
115 }
116 
117 
wm8775_update(struct pvr2_v4l_wm8775 * ctxt)118 static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
119 {
120 	unsigned long msk;
121 	unsigned int idx;
122 
123 	for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
124 		msk = 1 << idx;
125 		if (!(ctxt->stale_mask & msk)) continue;
126 		ctxt->stale_mask &= ~msk;
127 		wm8775_ops[idx].update(ctxt);
128 	}
129 }
130 
131 
132 static const struct pvr2_i2c_handler_functions hfuncs = {
133 	.detach = (void (*)(void *))wm8775_detach,
134 	.check = (int (*)(void *))wm8775_check,
135 	.update = (void (*)(void *))wm8775_update,
136 	.describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
137 };
138 
139 
pvr2_i2c_wm8775_setup(struct pvr2_hdw * hdw,struct pvr2_i2c_client * cp)140 int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
141 {
142 	struct pvr2_v4l_wm8775 *ctxt;
143 
144 	if (cp->handler) return 0;
145 
146 	ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
147 	if (!ctxt) return 0;
148 
149 	ctxt->handler.func_data = ctxt;
150 	ctxt->handler.func_table = &hfuncs;
151 	ctxt->client = cp;
152 	ctxt->hdw = hdw;
153 	ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
154 	cp->handler = &ctxt->handler;
155 	pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
156 		   cp->client->addr);
157 	return !0;
158 }
159 
160 
161 
162 
163 /*
164   Stuff for Emacs to see, in order to encourage consistent editing style:
165   *** Local Variables: ***
166   *** mode: c ***
167   *** fill-column: 70 ***
168   *** tab-width: 8 ***
169   *** c-basic-offset: 8 ***
170   *** End: ***
171   */
172