aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/dream/Kconfig13
-rw-r--r--drivers/staging/dream/Makefile5
-rw-r--r--drivers/staging/dream/TODO13
-rw-r--r--drivers/staging/dream/camera/Kconfig46
-rw-r--r--drivers/staging/dream/camera/Makefile8
-rw-r--r--drivers/staging/dream/camera/msm_camera.c2181
-rw-r--r--drivers/staging/dream/camera/msm_io7x.c291
-rw-r--r--drivers/staging/dream/camera/msm_io8x.c320
-rw-r--r--drivers/staging/dream/camera/msm_v4l2.c798
-rw-r--r--drivers/staging/dream/camera/msm_vfe7x.c702
-rw-r--r--drivers/staging/dream/camera/msm_vfe7x.h255
-rw-r--r--drivers/staging/dream/camera/msm_vfe8x.c736
-rw-r--r--drivers/staging/dream/camera/msm_vfe8x.h895
-rw-r--r--drivers/staging/dream/camera/msm_vfe8x_proc.c4003
-rw-r--r--drivers/staging/dream/camera/msm_vfe8x_proc.h1549
-rw-r--r--drivers/staging/dream/camera/mt9d112.c762
-rw-r--r--drivers/staging/dream/camera/mt9d112.h36
-rw-r--r--drivers/staging/dream/camera/mt9d112_reg.c307
-rw-r--r--drivers/staging/dream/camera/mt9p012.h51
-rw-r--r--drivers/staging/dream/camera/mt9p012_fox.c1306
-rw-r--r--drivers/staging/dream/camera/mt9p012_reg.c573
-rw-r--r--drivers/staging/dream/camera/mt9t013.c1497
-rw-r--r--drivers/staging/dream/camera/mt9t013.h48
-rw-r--r--drivers/staging/dream/camera/mt9t013_reg.c266
-rw-r--r--drivers/staging/dream/camera/s5k3e2fx.c1307
-rw-r--r--drivers/staging/dream/camera/s5k3e2fx.h9
-rw-r--r--drivers/staging/dream/generic_gpio.c274
-rw-r--r--drivers/staging/dream/gpio_axis.c181
-rw-r--r--drivers/staging/dream/gpio_event.c224
-rw-r--r--drivers/staging/dream/gpio_input.c337
-rw-r--r--drivers/staging/dream/gpio_matrix.c399
-rw-r--r--drivers/staging/dream/gpio_output.c84
-rw-r--r--drivers/staging/dream/include/linux/android_pmem.h80
-rw-r--r--drivers/staging/dream/include/linux/gpio_event.h154
-rw-r--r--drivers/staging/dream/include/linux/msm_adsp.h84
-rw-r--r--drivers/staging/dream/include/linux/msm_audio.h115
-rw-r--r--drivers/staging/dream/include/linux/msm_rpcrouter.h47
-rw-r--r--drivers/staging/dream/include/linux/wakelock.h91
-rw-r--r--drivers/staging/dream/include/mach/camera.h279
-rw-r--r--drivers/staging/dream/include/mach/msm_adsp.h112
-rw-r--r--drivers/staging/dream/include/mach/msm_rpcrouter.h179
-rw-r--r--drivers/staging/dream/include/mach/msm_smd.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h94
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h70
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h914
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h318
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h256
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h85
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h176
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h127
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h376
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h177
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h82
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h80
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h235
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h212
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h910
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h290
-rw-r--r--drivers/staging/dream/include/media/msm_camera.h388
-rw-r--r--drivers/staging/dream/pmem.c1333
-rw-r--r--drivers/staging/dream/qdsp5/Makefile18
-rw-r--r--drivers/staging/dream/qdsp5/adsp.c1159
-rw-r--r--drivers/staging/dream/qdsp5/adsp.h369
-rw-r--r--drivers/staging/dream/qdsp5/adsp_6210.c283
-rw-r--r--drivers/staging/dream/qdsp5/adsp_6220.c284
-rw-r--r--drivers/staging/dream/qdsp5/adsp_6225.c328
-rw-r--r--drivers/staging/dream/qdsp5/adsp_driver.c643
-rw-r--r--drivers/staging/dream/qdsp5/adsp_info.c121
-rw-r--r--drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c31
-rw-r--r--drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c182
-rw-r--r--drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c65
-rw-r--r--drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c54
-rw-r--r--drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c239
-rw-r--r--drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c163
-rw-r--r--drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c235
-rw-r--r--drivers/staging/dream/qdsp5/audio_aac.c1054
-rw-r--r--drivers/staging/dream/qdsp5/audio_amrnb.c875
-rw-r--r--drivers/staging/dream/qdsp5/audio_evrc.c847
-rw-r--r--drivers/staging/dream/qdsp5/audio_in.c970
-rw-r--r--drivers/staging/dream/qdsp5/audio_mp3.c972
-rw-r--r--drivers/staging/dream/qdsp5/audio_out.c841
-rw-r--r--drivers/staging/dream/qdsp5/audio_qcelp.c858
-rw-r--r--drivers/staging/dream/qdsp5/audmgr.c314
-rw-r--r--drivers/staging/dream/qdsp5/audmgr.h215
-rw-r--r--drivers/staging/dream/qdsp5/audmgr_new.h213
-rw-r--r--drivers/staging/dream/qdsp5/audpp.c429
-rw-r--r--drivers/staging/dream/qdsp5/evlog.h134
-rw-r--r--drivers/staging/dream/qdsp5/snd.c280
-rw-r--r--drivers/staging/dream/synaptics_i2c_rmi.c649
-rw-r--r--drivers/staging/dream/synaptics_i2c_rmi.h53
93 files changed, 0 insertions, 39835 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index f9c9c8a397db..5eafdf435550 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -87,8 +87,6 @@ source "drivers/staging/rtl8712/Kconfig"
87 87
88source "drivers/staging/frontier/Kconfig" 88source "drivers/staging/frontier/Kconfig"
89 89
90source "drivers/staging/dream/Kconfig"
91
92source "drivers/staging/pohmelfs/Kconfig" 90source "drivers/staging/pohmelfs/Kconfig"
93 91
94source "drivers/staging/autofs/Kconfig" 92source "drivers/staging/autofs/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a85074f8321b..a97a955c094b 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/
28obj-$(CONFIG_R8712U) += rtl8712/ 28obj-$(CONFIG_R8712U) += rtl8712/
29obj-$(CONFIG_SPECTRA) += spectra/ 29obj-$(CONFIG_SPECTRA) += spectra/
30obj-$(CONFIG_TRANZPORT) += frontier/ 30obj-$(CONFIG_TRANZPORT) += frontier/
31obj-$(CONFIG_DREAM) += dream/
32obj-$(CONFIG_POHMELFS) += pohmelfs/ 31obj-$(CONFIG_POHMELFS) += pohmelfs/
33obj-$(CONFIG_AUTOFS_FS) += autofs/ 32obj-$(CONFIG_AUTOFS_FS) += autofs/
34obj-$(CONFIG_IDE_PHISON) += phison/ 33obj-$(CONFIG_IDE_PHISON) += phison/
diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig
deleted file mode 100644
index 0c30b19a5a7c..000000000000
--- a/drivers/staging/dream/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
1config DREAM
2 tristate "HTC Dream support"
3 depends on MACH_TROUT
4
5if DREAM
6
7source "drivers/staging/dream/camera/Kconfig"
8
9config INPUT_GPIO
10 tristate "GPIO driver support"
11 help
12 Say Y here if you want to support gpio based keys, wheels etc...
13endif
diff --git a/drivers/staging/dream/Makefile b/drivers/staging/dream/Makefile
deleted file mode 100644
index 87de1a57f237..000000000000
--- a/drivers/staging/dream/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1ccflags-y:=-Idrivers/staging/dream/include
2obj-$(CONFIG_MSM_ADSP) += qdsp5/
3obj-$(CONFIG_MSM_CAMERA) += camera/
4obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o
5
diff --git a/drivers/staging/dream/TODO b/drivers/staging/dream/TODO
deleted file mode 100644
index dcd3ba808655..000000000000
--- a/drivers/staging/dream/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
1
2* camera driver uses old V4L API
3
4* coding style in some places is lacking
5
6* gpio_input.c has some features matrix_keypad lacks. They should be
7merged to gpio_input, with gpio_input.c removed
8
9* pmem provides interface for userspace. Needs to be reviewed at least.
10
11* it is probably possible to simplify touchscreen driver using threaded_irq's.
12
13* touchscreen driver should be switched to oficial multitouch API
diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig
deleted file mode 100644
index bfb6d241d807..000000000000
--- a/drivers/staging/dream/camera/Kconfig
+++ /dev/null
@@ -1,46 +0,0 @@
1comment "Qualcomm MSM Camera And Video"
2
3menuconfig MSM_CAMERA
4 bool "Qualcomm MSM camera and video capture support"
5 depends on ARCH_MSM && VIDEO_V4L2_COMMON
6 help
7 Say Y here to enable selecting the video adapters for
8 Qualcomm msm camera and video encoding
9
10config MSM_CAMERA_DEBUG
11 bool "Qualcomm MSM camera debugging with printk"
12 depends on MSM_CAMERA
13 help
14 Enable printk() debug for msm camera
15
16config MSM_CAMERA_FLASH
17 bool "Qualcomm MSM camera flash support"
18 depends on MSM_CAMERA && BROKEN
19 ---help---
20 Enable support for LED flash for msm camera
21
22
23comment "Camera Sensor Selection"
24config MT9T013
25 bool "Sensor mt9t013 (BAYER 3M)"
26 depends on MSM_CAMERA
27 ---help---
28 MICRON 3M Bayer Sensor with AutoFocus
29
30config MT9D112
31 bool "Sensor mt9d112 (YUV 2M)"
32 depends on MSM_CAMERA
33 ---help---
34 MICRON 2M YUV Sensor
35
36config MT9P012
37 bool "Sensor mt9p012 (BAYER 5M)"
38 depends on MSM_CAMERA
39 ---help---
40 MICRON 5M Bayer Sensor with Autofocus
41
42config S5K3E2FX
43 bool "Sensor s5k3e2fx (Samsung 5M)"
44 depends on MSM_CAMERA
45 ---help---
46 Samsung 5M with Autofocus
diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile
deleted file mode 100644
index 03711dc6f482..000000000000
--- a/drivers/staging/dream/camera/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1ccflags-y:=-Idrivers/staging/dream/include
2obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
3obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
4obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
5obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o
6obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
7obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o
8obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
deleted file mode 100644
index de4ab61efd4b..000000000000
--- a/drivers/staging/dream/camera/msm_camera.c
+++ /dev/null
@@ -1,2181 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5/* FIXME: most allocations need not be GFP_ATOMIC */
6/* FIXME: management of mutexes */
7/* FIXME: msm_pmem_region_lookup return values */
8/* FIXME: way too many copy to/from user */
9/* FIXME: does region->active mean free */
10/* FIXME: check limits on command lenghts passed from userspace */
11/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/init.h>
17#include <linux/sched.h>
18#include <mach/board.h>
19
20#include <linux/fs.h>
21#include <linux/list.h>
22#include <linux/uaccess.h>
23#include <linux/android_pmem.h>
24#include <linux/poll.h>
25#include <media/msm_camera.h>
26#include <mach/camera.h>
27
28#define MSM_MAX_CAMERA_SENSORS 5
29
30#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
31 __func__, __LINE__, ((to) ? "to" : "from"))
32#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
33#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
34
35static struct class *msm_class;
36static dev_t msm_devno;
37static LIST_HEAD(msm_sensors);
38
39#define __CONTAINS(r, v, l, field) ({ \
40 typeof(r) __r = r; \
41 typeof(v) __v = v; \
42 typeof(v) __e = __v + l; \
43 int res = __v >= __r->field && \
44 __e <= __r->field + __r->len; \
45 res; \
46})
47
48#define CONTAINS(r1, r2, field) ({ \
49 typeof(r2) __r2 = r2; \
50 __CONTAINS(r1, __r2->field, __r2->len, field); \
51})
52
53#define IN_RANGE(r, v, field) ({ \
54 typeof(r) __r = r; \
55 typeof(v) __vv = v; \
56 int res = ((__vv >= __r->field) && \
57 (__vv < (__r->field + __r->len))); \
58 res; \
59})
60
61#define OVERLAPS(r1, r2, field) ({ \
62 typeof(r1) __r1 = r1; \
63 typeof(r2) __r2 = r2; \
64 typeof(__r2->field) __v = __r2->field; \
65 typeof(__v) __e = __v + __r2->len - 1; \
66 int res = (IN_RANGE(__r1, __v, field) || \
67 IN_RANGE(__r1, __e, field)); \
68 res; \
69})
70
71#define MSM_DRAIN_QUEUE_NOSYNC(sync, name) do { \
72 struct msm_queue_cmd *qcmd = NULL; \
73 CDBG("%s: draining queue "#name"\n", __func__); \
74 while (!list_empty(&(sync)->name)) { \
75 qcmd = list_first_entry(&(sync)->name, \
76 struct msm_queue_cmd, list); \
77 list_del_init(&qcmd->list); \
78 kfree(qcmd); \
79 }; \
80} while (0)
81
82#define MSM_DRAIN_QUEUE(sync, name) do { \
83 unsigned long flags; \
84 spin_lock_irqsave(&(sync)->name##_lock, flags); \
85 MSM_DRAIN_QUEUE_NOSYNC(sync, name); \
86 spin_unlock_irqrestore(&(sync)->name##_lock, flags); \
87} while (0)
88
89static int check_overlap(struct hlist_head *ptype,
90 unsigned long paddr,
91 unsigned long len)
92{
93 struct msm_pmem_region *region;
94 struct msm_pmem_region t = { .paddr = paddr, .len = len };
95 struct hlist_node *node;
96
97 hlist_for_each_entry(region, node, ptype, list) {
98 if (CONTAINS(region, &t, paddr) ||
99 CONTAINS(&t, region, paddr) ||
100 OVERLAPS(region, &t, paddr)) {
101 printk(KERN_ERR
102 " region (PHYS %p len %ld)"
103 " clashes with registered region"
104 " (paddr %p len %ld)\n",
105 (void *)t.paddr, t.len,
106 (void *)region->paddr, region->len);
107 return -1;
108 }
109 }
110
111 return 0;
112}
113
114static int msm_pmem_table_add(struct hlist_head *ptype,
115 struct msm_pmem_info *info)
116{
117 struct file *file;
118 unsigned long paddr;
119 unsigned long vstart;
120 unsigned long len;
121 int rc;
122 struct msm_pmem_region *region;
123
124 rc = get_pmem_file(info->fd, &paddr, &vstart, &len, &file);
125 if (rc < 0) {
126 pr_err("msm_pmem_table_add: get_pmem_file fd %d error %d\n",
127 info->fd, rc);
128 return rc;
129 }
130
131 if (check_overlap(ptype, paddr, len) < 0)
132 return -EINVAL;
133
134 CDBG("%s: type = %d, paddr = 0x%lx, vaddr = 0x%lx\n",
135 __func__,
136 info->type, paddr, (unsigned long)info->vaddr);
137
138 region = kmalloc(sizeof(*region), GFP_KERNEL);
139 if (!region)
140 return -ENOMEM;
141
142 INIT_HLIST_NODE(&region->list);
143
144 region->type = info->type;
145 region->vaddr = info->vaddr;
146 region->paddr = paddr;
147 region->len = len;
148 region->file = file;
149 region->y_off = info->y_off;
150 region->cbcr_off = info->cbcr_off;
151 region->fd = info->fd;
152 region->active = info->active;
153
154 hlist_add_head(&(region->list), ptype);
155
156 return 0;
157}
158
159/* return of 0 means failure */
160static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
161 int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount)
162{
163 struct msm_pmem_region *region;
164 struct msm_pmem_region *regptr;
165 struct hlist_node *node, *n;
166
167 uint8_t rc = 0;
168
169 regptr = reg;
170
171 hlist_for_each_entry_safe(region, node, n, ptype, list) {
172 if (region->type == pmem_type && region->active) {
173 *regptr = *region;
174 rc += 1;
175 if (rc >= maxcount)
176 break;
177 regptr++;
178 }
179 }
180
181 return rc;
182}
183
184static unsigned long msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
185 unsigned long pyaddr,
186 unsigned long pcbcraddr,
187 uint32_t *yoff, uint32_t *cbcroff, int *fd)
188{
189 struct msm_pmem_region *region;
190 struct hlist_node *node, *n;
191
192 hlist_for_each_entry_safe(region, node, n, &sync->frame, list) {
193 if (pyaddr == (region->paddr + region->y_off) &&
194 pcbcraddr == (region->paddr +
195 region->cbcr_off) &&
196 region->active) {
197 /* offset since we could pass vaddr inside
198 * a registerd pmem buffer
199 */
200 *yoff = region->y_off;
201 *cbcroff = region->cbcr_off;
202 *fd = region->fd;
203 region->active = 0;
204 return (unsigned long)(region->vaddr);
205 }
206 }
207
208 return 0;
209}
210
211static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
212 unsigned long addr, int *fd)
213{
214 struct msm_pmem_region *region;
215 struct hlist_node *node, *n;
216
217 hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
218 if (addr == region->paddr && region->active) {
219 /* offset since we could pass vaddr inside a
220 * registered pmem buffer */
221 *fd = region->fd;
222 region->active = 0;
223 return (unsigned long)(region->vaddr);
224 }
225 }
226
227 return 0;
228}
229
230static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
231 unsigned long buffer,
232 uint32_t yoff, uint32_t cbcroff, int fd)
233{
234 struct msm_pmem_region *region;
235 struct hlist_node *node, *n;
236
237 hlist_for_each_entry_safe(region,
238 node, n, &sync->frame, list) {
239 if (((unsigned long)(region->vaddr) == buffer) &&
240 (region->y_off == yoff) &&
241 (region->cbcr_off == cbcroff) &&
242 (region->fd == fd) &&
243 (region->active == 0)) {
244
245 region->active = 1;
246 return region->paddr;
247 }
248 }
249
250 return 0;
251}
252
253static unsigned long msm_pmem_stats_vtop_lookup(
254 struct msm_sync *sync,
255 unsigned long buffer,
256 int fd)
257{
258 struct msm_pmem_region *region;
259 struct hlist_node *node, *n;
260
261 hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
262 if (((unsigned long)(region->vaddr) == buffer) &&
263 (region->fd == fd) && region->active == 0) {
264 region->active = 1;
265 return region->paddr;
266 }
267 }
268
269 return 0;
270}
271
272static int __msm_pmem_table_del(struct msm_sync *sync,
273 struct msm_pmem_info *pinfo)
274{
275 int rc = 0;
276 struct msm_pmem_region *region;
277 struct hlist_node *node, *n;
278
279 switch (pinfo->type) {
280 case MSM_PMEM_OUTPUT1:
281 case MSM_PMEM_OUTPUT2:
282 case MSM_PMEM_THUMBAIL:
283 case MSM_PMEM_MAINIMG:
284 case MSM_PMEM_RAW_MAINIMG:
285 hlist_for_each_entry_safe(region, node, n,
286 &sync->frame, list) {
287
288 if (pinfo->type == region->type &&
289 pinfo->vaddr == region->vaddr &&
290 pinfo->fd == region->fd) {
291 hlist_del(node);
292 put_pmem_file(region->file);
293 kfree(region);
294 }
295 }
296 break;
297
298 case MSM_PMEM_AEC_AWB:
299 case MSM_PMEM_AF:
300 hlist_for_each_entry_safe(region, node, n,
301 &sync->stats, list) {
302
303 if (pinfo->type == region->type &&
304 pinfo->vaddr == region->vaddr &&
305 pinfo->fd == region->fd) {
306 hlist_del(node);
307 put_pmem_file(region->file);
308 kfree(region);
309 }
310 }
311 break;
312
313 default:
314 rc = -EINVAL;
315 break;
316 }
317
318 return rc;
319}
320
321static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg)
322{
323 struct msm_pmem_info info;
324
325 if (copy_from_user(&info, arg, sizeof(info))) {
326 ERR_COPY_FROM_USER();
327 return -EFAULT;
328 }
329
330 return __msm_pmem_table_del(sync, &info);
331}
332
333static int __msm_get_frame(struct msm_sync *sync,
334 struct msm_frame *frame)
335{
336 unsigned long flags;
337 int rc = 0;
338
339 struct msm_queue_cmd *qcmd = NULL;
340 struct msm_vfe_phy_info *pphy;
341
342 spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
343 if (!list_empty(&sync->prev_frame_q)) {
344 qcmd = list_first_entry(&sync->prev_frame_q,
345 struct msm_queue_cmd, list);
346 list_del_init(&qcmd->list);
347 }
348 spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
349
350 if (!qcmd) {
351 pr_err("%s: no preview frame.\n", __func__);
352 return -EAGAIN;
353 }
354
355 pphy = (struct msm_vfe_phy_info *)(qcmd->command);
356
357 frame->buffer =
358 msm_pmem_frame_ptov_lookup(sync,
359 pphy->y_phy,
360 pphy->cbcr_phy, &(frame->y_off),
361 &(frame->cbcr_off), &(frame->fd));
362 if (!frame->buffer) {
363 pr_err("%s: cannot get frame, invalid lookup address "
364 "y=%x cbcr=%x offset=%d\n",
365 __func__,
366 pphy->y_phy,
367 pphy->cbcr_phy,
368 frame->y_off);
369 rc = -EINVAL;
370 }
371
372 CDBG("__msm_get_frame: y=0x%x, cbcr=0x%x, qcmd=0x%x, virt_addr=0x%x\n",
373 pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
374
375 kfree(qcmd);
376 return rc;
377}
378
379static int msm_get_frame(struct msm_sync *sync, void __user *arg)
380{
381 int rc = 0;
382 struct msm_frame frame;
383
384 if (copy_from_user(&frame,
385 arg,
386 sizeof(struct msm_frame))) {
387 ERR_COPY_FROM_USER();
388 return -EFAULT;
389 }
390
391 rc = __msm_get_frame(sync, &frame);
392 if (rc < 0)
393 return rc;
394
395 if (sync->croplen) {
396 if (frame.croplen > sync->croplen) {
397 pr_err("msm_get_frame: invalid frame croplen %d\n",
398 frame.croplen);
399 return -EINVAL;
400 }
401
402 if (copy_to_user((void *)frame.cropinfo,
403 sync->cropinfo,
404 sync->croplen)) {
405 ERR_COPY_TO_USER();
406 return -EFAULT;
407 }
408 }
409
410 if (copy_to_user((void *)arg,
411 &frame, sizeof(struct msm_frame))) {
412 ERR_COPY_TO_USER();
413 rc = -EFAULT;
414 }
415
416 CDBG("Got frame!!!\n");
417
418 return rc;
419}
420
421static int msm_enable_vfe(struct msm_sync *sync, void __user *arg)
422{
423 int rc = -EIO;
424 struct camera_enable_cmd cfg;
425
426 if (copy_from_user(&cfg,
427 arg,
428 sizeof(struct camera_enable_cmd))) {
429 ERR_COPY_FROM_USER();
430 return -EFAULT;
431 }
432
433 if (sync->vfefn.vfe_enable)
434 rc = sync->vfefn.vfe_enable(&cfg);
435
436 CDBG("msm_enable_vfe: returned rc = %d\n", rc);
437 return rc;
438}
439
440static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
441{
442 int rc = -EIO;
443 struct camera_enable_cmd cfg;
444
445 if (copy_from_user(&cfg,
446 arg,
447 sizeof(struct camera_enable_cmd))) {
448 ERR_COPY_FROM_USER();
449 return -EFAULT;
450 }
451
452 if (sync->vfefn.vfe_disable)
453 rc = sync->vfefn.vfe_disable(&cfg, NULL);
454
455 CDBG("msm_disable_vfe: returned rc = %d\n", rc);
456 return rc;
457}
458
459static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
460 struct msm_control_device_queue *queue,
461 struct msm_queue_cmd *qcmd,
462 int timeout)
463{
464 unsigned long flags;
465 int rc;
466
467 spin_lock_irqsave(&sync->msg_event_q_lock, flags);
468 list_add_tail(&qcmd->list, &sync->msg_event_q);
469 /* wake up config thread */
470 wake_up(&sync->msg_event_wait);
471 spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
472
473 if (!queue)
474 return NULL;
475
476 /* wait for config status */
477 rc = wait_event_interruptible_timeout(
478 queue->ctrl_status_wait,
479 !list_empty_careful(&queue->ctrl_status_q),
480 timeout);
481 if (list_empty_careful(&queue->ctrl_status_q)) {
482 if (!rc)
483 rc = -ETIMEDOUT;
484 if (rc < 0) {
485 pr_err("msm_control: wait_event error %d\n", rc);
486#if 0
487 /* This is a bit scary. If we time out too early, we
488 * will free qcmd at the end of this function, and the
489 * dsp may do the same when it does respond, so we
490 * remove the message from the source queue.
491 */
492 pr_err("%s: error waiting for ctrl_status_q: %d\n",
493 __func__, rc);
494 spin_lock_irqsave(&sync->msg_event_q_lock, flags);
495 list_del_init(&qcmd->list);
496 spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
497#endif
498 return ERR_PTR(rc);
499 }
500 }
501
502 /* control command status is ready */
503 spin_lock_irqsave(&queue->ctrl_status_q_lock, flags);
504 BUG_ON(list_empty(&queue->ctrl_status_q));
505 qcmd = list_first_entry(&queue->ctrl_status_q,
506 struct msm_queue_cmd, list);
507 list_del_init(&qcmd->list);
508 spin_unlock_irqrestore(&queue->ctrl_status_q_lock, flags);
509
510 return qcmd;
511}
512
513static int msm_control(struct msm_control_device *ctrl_pmsm,
514 int block,
515 void __user *arg)
516{
517 int rc = 0;
518
519 struct msm_sync *sync = ctrl_pmsm->pmsm->sync;
520 struct msm_ctrl_cmd udata, *ctrlcmd;
521 struct msm_queue_cmd *qcmd = NULL, *qcmd_temp;
522
523 if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
524 ERR_COPY_FROM_USER();
525 rc = -EFAULT;
526 goto end;
527 }
528
529 qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
530 sizeof(struct msm_ctrl_cmd) + udata.length,
531 GFP_KERNEL);
532 if (!qcmd) {
533 pr_err("msm_control: cannot allocate buffer\n");
534 rc = -ENOMEM;
535 goto end;
536 }
537
538 qcmd->type = MSM_CAM_Q_CTRL;
539 qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
540 *ctrlcmd = udata;
541 ctrlcmd->value = ctrlcmd + 1;
542
543 if (udata.length) {
544 if (copy_from_user(ctrlcmd->value,
545 udata.value, udata.length)) {
546 ERR_COPY_FROM_USER();
547 rc = -EFAULT;
548 goto end;
549 }
550 }
551
552 if (!block) {
553 /* qcmd will be set to NULL */
554 qcmd = __msm_control(sync, NULL, qcmd, 0);
555 goto end;
556 }
557
558 qcmd_temp = __msm_control(sync,
559 &ctrl_pmsm->ctrl_q,
560 qcmd, MAX_SCHEDULE_TIMEOUT);
561
562 if (IS_ERR(qcmd_temp)) {
563 rc = PTR_ERR(qcmd_temp);
564 goto end;
565 }
566 qcmd = qcmd_temp;
567
568 if (qcmd->command) {
569 void __user *to = udata.value;
570 udata = *(struct msm_ctrl_cmd *)qcmd->command;
571 if (udata.length > 0) {
572 if (copy_to_user(to,
573 udata.value,
574 udata.length)) {
575 ERR_COPY_TO_USER();
576 rc = -EFAULT;
577 goto end;
578 }
579 }
580 udata.value = to;
581
582 if (copy_to_user((void *)arg, &udata,
583 sizeof(struct msm_ctrl_cmd))) {
584 ERR_COPY_TO_USER();
585 rc = -EFAULT;
586 goto end;
587 }
588 }
589
590end:
591 /* Note: if we get here as a result of an error, we will free the
592 * qcmd that we kmalloc() in this function. When we come here as
593 * a result of a successful completion, we are freeing the qcmd that
594 * we dequeued from queue->ctrl_status_q.
595 */
596 kfree(qcmd);
597
598 CDBG("msm_control: end rc = %d\n", rc);
599 return rc;
600}
601
602static int msm_get_stats(struct msm_sync *sync, void __user *arg)
603{
604 unsigned long flags;
605 int timeout;
606 int rc = 0;
607
608 struct msm_stats_event_ctrl se;
609
610 struct msm_queue_cmd *qcmd = NULL;
611 struct msm_ctrl_cmd *ctrl = NULL;
612 struct msm_vfe_resp *data = NULL;
613 struct msm_stats_buf stats;
614
615 if (copy_from_user(&se, arg,
616 sizeof(struct msm_stats_event_ctrl))) {
617 ERR_COPY_FROM_USER();
618 return -EFAULT;
619 }
620
621 timeout = (int)se.timeout_ms;
622
623 CDBG("msm_get_stats timeout %d\n", timeout);
624 rc = wait_event_interruptible_timeout(
625 sync->msg_event_wait,
626 !list_empty_careful(&sync->msg_event_q),
627 msecs_to_jiffies(timeout));
628 if (list_empty_careful(&sync->msg_event_q)) {
629 if (rc == 0)
630 rc = -ETIMEDOUT;
631 if (rc < 0) {
632 pr_err("msm_get_stats error %d\n", rc);
633 return rc;
634 }
635 }
636 CDBG("msm_get_stats returned from wait: %d\n", rc);
637
638 spin_lock_irqsave(&sync->msg_event_q_lock, flags);
639 BUG_ON(list_empty(&sync->msg_event_q));
640 qcmd = list_first_entry(&sync->msg_event_q,
641 struct msm_queue_cmd, list);
642 list_del_init(&qcmd->list);
643 spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
644
645 CDBG("=== received from DSP === %d\n", qcmd->type);
646
647 switch (qcmd->type) {
648 case MSM_CAM_Q_VFE_EVT:
649 case MSM_CAM_Q_VFE_MSG:
650 data = (struct msm_vfe_resp *)(qcmd->command);
651
652 /* adsp event and message */
653 se.resptype = MSM_CAM_RESP_STAT_EVT_MSG;
654
655 /* 0 - msg from aDSP, 1 - event from mARM */
656 se.stats_event.type = data->evt_msg.type;
657 se.stats_event.msg_id = data->evt_msg.msg_id;
658 se.stats_event.len = data->evt_msg.len;
659
660 CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
661 CDBG("length = %d\n", se.stats_event.len);
662 CDBG("msg_id = %d\n", se.stats_event.msg_id);
663
664 if ((data->type == VFE_MSG_STATS_AF) ||
665 (data->type == VFE_MSG_STATS_WE)) {
666
667 stats.buffer =
668 msm_pmem_stats_ptov_lookup(sync,
669 data->phy.sbuf_phy,
670 &(stats.fd));
671 if (!stats.buffer) {
672 pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
673 __func__);
674 rc = -EINVAL;
675 goto failure;
676 }
677
678 if (copy_to_user((void *)(se.stats_event.data),
679 &stats,
680 sizeof(struct msm_stats_buf))) {
681 ERR_COPY_TO_USER();
682 rc = -EFAULT;
683 goto failure;
684 }
685 } else if ((data->evt_msg.len > 0) &&
686 (data->type == VFE_MSG_GENERAL)) {
687 if (copy_to_user((void *)(se.stats_event.data),
688 data->evt_msg.data,
689 data->evt_msg.len)) {
690 ERR_COPY_TO_USER();
691 rc = -EFAULT;
692 }
693 } else if (data->type == VFE_MSG_OUTPUT1 ||
694 data->type == VFE_MSG_OUTPUT2) {
695 if (copy_to_user((void *)(se.stats_event.data),
696 data->extdata,
697 data->extlen)) {
698 ERR_COPY_TO_USER();
699 rc = -EFAULT;
700 }
701 } else if (data->type == VFE_MSG_SNAPSHOT && sync->pict_pp) {
702 struct msm_postproc buf;
703 struct msm_pmem_region region;
704 buf.fmnum = msm_pmem_region_lookup(&sync->frame,
705 MSM_PMEM_MAINIMG,
706 &region, 1);
707 if (buf.fmnum == 1) {
708 buf.fmain.buffer = (unsigned long)region.vaddr;
709 buf.fmain.y_off = region.y_off;
710 buf.fmain.cbcr_off = region.cbcr_off;
711 buf.fmain.fd = region.fd;
712 } else {
713 buf.fmnum = msm_pmem_region_lookup(&sync->frame,
714 MSM_PMEM_RAW_MAINIMG,
715 &region, 1);
716 if (buf.fmnum == 1) {
717 buf.fmain.path = MSM_FRAME_PREV_2;
718 buf.fmain.buffer =
719 (unsigned long)region.vaddr;
720 buf.fmain.fd = region.fd;
721 } else {
722 pr_err("%s: pmem lookup failed\n",
723 __func__);
724 rc = -EINVAL;
725 }
726 }
727
728 if (copy_to_user((void *)(se.stats_event.data), &buf,
729 sizeof(buf))) {
730 ERR_COPY_TO_USER();
731 rc = -EFAULT;
732 goto failure;
733 }
734 CDBG("snapshot copy_to_user!\n");
735 }
736 break;
737
738 case MSM_CAM_Q_CTRL:
739 /* control command from control thread */
740 ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
741
742 CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
743 CDBG("length = %d\n", ctrl->length);
744
745 if (ctrl->length > 0) {
746 if (copy_to_user((void *)(se.ctrl_cmd.value),
747 ctrl->value,
748 ctrl->length)) {
749 ERR_COPY_TO_USER();
750 rc = -EFAULT;
751 goto failure;
752 }
753 }
754
755 se.resptype = MSM_CAM_RESP_CTRL;
756
757 /* what to control */
758 se.ctrl_cmd.type = ctrl->type;
759 se.ctrl_cmd.length = ctrl->length;
760 se.ctrl_cmd.resp_fd = ctrl->resp_fd;
761 break;
762
763 case MSM_CAM_Q_V4L2_REQ:
764 /* control command from v4l2 client */
765 ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
766
767 CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
768 CDBG("length = %d\n", ctrl->length);
769
770 if (ctrl->length > 0) {
771 if (copy_to_user((void *)(se.ctrl_cmd.value),
772 ctrl->value, ctrl->length)) {
773 ERR_COPY_TO_USER();
774 rc = -EFAULT;
775 goto failure;
776 }
777 }
778
779 /* 2 tells config thread this is v4l2 request */
780 se.resptype = MSM_CAM_RESP_V4L2;
781
782 /* what to control */
783 se.ctrl_cmd.type = ctrl->type;
784 se.ctrl_cmd.length = ctrl->length;
785 break;
786
787 default:
788 rc = -EFAULT;
789 goto failure;
790 } /* switch qcmd->type */
791
792 if (copy_to_user((void *)arg, &se, sizeof(se))) {
793 ERR_COPY_TO_USER();
794 rc = -EFAULT;
795 }
796
797failure:
798 kfree(qcmd);
799
800 CDBG("msm_get_stats: %d\n", rc);
801 return rc;
802}
803
804static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
805 void __user *arg)
806{
807 unsigned long flags;
808 int rc = 0;
809
810 struct msm_ctrl_cmd udata, *ctrlcmd;
811 struct msm_queue_cmd *qcmd = NULL;
812
813 if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
814 ERR_COPY_FROM_USER();
815 rc = -EFAULT;
816 goto end;
817 }
818
819 qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
820 sizeof(struct msm_ctrl_cmd) + udata.length,
821 GFP_KERNEL);
822 if (!qcmd) {
823 rc = -ENOMEM;
824 goto end;
825 }
826
827 qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
828 *ctrlcmd = udata;
829 if (udata.length > 0) {
830 ctrlcmd->value = ctrlcmd + 1;
831 if (copy_from_user(ctrlcmd->value,
832 (void *)udata.value,
833 udata.length)) {
834 ERR_COPY_FROM_USER();
835 rc = -EFAULT;
836 kfree(qcmd);
837 goto end;
838 }
839 } else
840 ctrlcmd->value = NULL;
841
842end:
843 CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
844 if (rc == 0) {
845 /* wake up control thread */
846 spin_lock_irqsave(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
847 list_add_tail(&qcmd->list, &ctrl_pmsm->ctrl_q.ctrl_status_q);
848 wake_up(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
849 spin_unlock_irqrestore(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
850 }
851
852 return rc;
853}
854
855static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
856{
857 struct msm_vfe_cfg_cmd cfgcmd;
858 struct msm_pmem_region region[8];
859 struct axidata axi_data;
860 void *data = NULL;
861 int rc = -EIO;
862
863 memset(&axi_data, 0, sizeof(axi_data));
864
865 if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
866 ERR_COPY_FROM_USER();
867 return -EFAULT;
868 }
869
870 switch (cfgcmd.cmd_type) {
871 case CMD_STATS_ENABLE:
872 axi_data.bufnum1 =
873 msm_pmem_region_lookup(&sync->stats,
874 MSM_PMEM_AEC_AWB, &region[0],
875 NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
876 if (!axi_data.bufnum1) {
877 pr_err("%s: pmem region lookup error\n", __func__);
878 return -EINVAL;
879 }
880 axi_data.region = &region[0];
881 data = &axi_data;
882 break;
883 case CMD_STATS_AF_ENABLE:
884 axi_data.bufnum1 =
885 msm_pmem_region_lookup(&sync->stats,
886 MSM_PMEM_AF, &region[0],
887 NUM_AF_STAT_OUTPUT_BUFFERS);
888 if (!axi_data.bufnum1) {
889 pr_err("%s: pmem region lookup error\n", __func__);
890 return -EINVAL;
891 }
892 axi_data.region = &region[0];
893 data = &axi_data;
894 break;
895 case CMD_GENERAL:
896 case CMD_STATS_DISABLE:
897 break;
898 default:
899 pr_err("%s: unknown command type %d\n",
900 __func__, cfgcmd.cmd_type);
901 return -EINVAL;
902 }
903
904
905 if (sync->vfefn.vfe_config)
906 rc = sync->vfefn.vfe_config(&cfgcmd, data);
907
908 return rc;
909}
910
911static int msm_frame_axi_cfg(struct msm_sync *sync,
912 struct msm_vfe_cfg_cmd *cfgcmd)
913{
914 int rc = -EIO;
915 struct axidata axi_data;
916 void *data = &axi_data;
917 struct msm_pmem_region region[8];
918 int pmem_type;
919
920 memset(&axi_data, 0, sizeof(axi_data));
921
922 switch (cfgcmd->cmd_type) {
923 case CMD_AXI_CFG_OUT1:
924 pmem_type = MSM_PMEM_OUTPUT1;
925 axi_data.bufnum1 =
926 msm_pmem_region_lookup(&sync->frame, pmem_type,
927 &region[0], 8);
928 if (!axi_data.bufnum1) {
929 pr_err("%s: pmem region lookup error\n", __func__);
930 return -EINVAL;
931 }
932 break;
933
934 case CMD_AXI_CFG_OUT2:
935 pmem_type = MSM_PMEM_OUTPUT2;
936 axi_data.bufnum2 =
937 msm_pmem_region_lookup(&sync->frame, pmem_type,
938 &region[0], 8);
939 if (!axi_data.bufnum2) {
940 pr_err("%s: pmem region lookup error\n", __func__);
941 return -EINVAL;
942 }
943 break;
944
945 case CMD_AXI_CFG_SNAP_O1_AND_O2:
946 pmem_type = MSM_PMEM_THUMBAIL;
947 axi_data.bufnum1 =
948 msm_pmem_region_lookup(&sync->frame, pmem_type,
949 &region[0], 8);
950 if (!axi_data.bufnum1) {
951 pr_err("%s: pmem region lookup error\n", __func__);
952 return -EINVAL;
953 }
954
955 pmem_type = MSM_PMEM_MAINIMG;
956 axi_data.bufnum2 =
957 msm_pmem_region_lookup(&sync->frame, pmem_type,
958 &region[axi_data.bufnum1], 8);
959 if (!axi_data.bufnum2) {
960 pr_err("%s: pmem region lookup error\n", __func__);
961 return -EINVAL;
962 }
963 break;
964
965 case CMD_RAW_PICT_AXI_CFG:
966 pmem_type = MSM_PMEM_RAW_MAINIMG;
967 axi_data.bufnum2 =
968 msm_pmem_region_lookup(&sync->frame, pmem_type,
969 &region[0], 8);
970 if (!axi_data.bufnum2) {
971 pr_err("%s: pmem region lookup error\n", __func__);
972 return -EINVAL;
973 }
974 break;
975
976 case CMD_GENERAL:
977 data = NULL;
978 break;
979
980 default:
981 pr_err("%s: unknown command type %d\n",
982 __func__, cfgcmd->cmd_type);
983 return -EINVAL;
984 }
985
986 axi_data.region = &region[0];
987
988 /* send the AXI configuration command to driver */
989 if (sync->vfefn.vfe_config)
990 rc = sync->vfefn.vfe_config(cfgcmd, data);
991
992 return rc;
993}
994
995static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg)
996{
997 int rc = 0;
998 struct msm_camsensor_info info;
999 struct msm_camera_sensor_info *sdata;
1000
1001 if (copy_from_user(&info,
1002 arg,
1003 sizeof(struct msm_camsensor_info))) {
1004 ERR_COPY_FROM_USER();
1005 return -EFAULT;
1006 }
1007
1008 sdata = sync->pdev->dev.platform_data;
1009 CDBG("sensor_name %s\n", sdata->sensor_name);
1010
1011 memcpy(&info.name[0],
1012 sdata->sensor_name,
1013 MAX_SENSOR_NAME);
1014 info.flash_enabled = sdata->flash_type != MSM_CAMERA_FLASH_NONE;
1015
1016 /* copy back to user space */
1017 if (copy_to_user((void *)arg,
1018 &info,
1019 sizeof(struct msm_camsensor_info))) {
1020 ERR_COPY_TO_USER();
1021 rc = -EFAULT;
1022 }
1023
1024 return rc;
1025}
1026
1027static int __msm_put_frame_buf(struct msm_sync *sync,
1028 struct msm_frame *pb)
1029{
1030 unsigned long pphy;
1031 struct msm_vfe_cfg_cmd cfgcmd;
1032
1033 int rc = -EIO;
1034
1035 pphy = msm_pmem_frame_vtop_lookup(sync,
1036 pb->buffer,
1037 pb->y_off, pb->cbcr_off, pb->fd);
1038
1039 if (pphy != 0) {
1040 CDBG("rel: vaddr = 0x%lx, paddr = 0x%lx\n",
1041 pb->buffer, pphy);
1042 cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE;
1043 cfgcmd.value = (void *)pb;
1044 if (sync->vfefn.vfe_config)
1045 rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
1046 } else {
1047 pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
1048 __func__);
1049 rc = -EINVAL;
1050 }
1051
1052 return rc;
1053}
1054
1055static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg)
1056{
1057 struct msm_frame buf_t;
1058
1059 if (copy_from_user(&buf_t,
1060 arg,
1061 sizeof(struct msm_frame))) {
1062 ERR_COPY_FROM_USER();
1063 return -EFAULT;
1064 }
1065
1066 return __msm_put_frame_buf(sync, &buf_t);
1067}
1068
1069static int __msm_register_pmem(struct msm_sync *sync,
1070 struct msm_pmem_info *pinfo)
1071{
1072 int rc = 0;
1073
1074 switch (pinfo->type) {
1075 case MSM_PMEM_OUTPUT1:
1076 case MSM_PMEM_OUTPUT2:
1077 case MSM_PMEM_THUMBAIL:
1078 case MSM_PMEM_MAINIMG:
1079 case MSM_PMEM_RAW_MAINIMG:
1080 rc = msm_pmem_table_add(&sync->frame, pinfo);
1081 break;
1082
1083 case MSM_PMEM_AEC_AWB:
1084 case MSM_PMEM_AF:
1085 rc = msm_pmem_table_add(&sync->stats, pinfo);
1086 break;
1087
1088 default:
1089 rc = -EINVAL;
1090 break;
1091 }
1092
1093 return rc;
1094}
1095
1096static int msm_register_pmem(struct msm_sync *sync, void __user *arg)
1097{
1098 struct msm_pmem_info info;
1099
1100 if (copy_from_user(&info, arg, sizeof(info))) {
1101 ERR_COPY_FROM_USER();
1102 return -EFAULT;
1103 }
1104
1105 return __msm_register_pmem(sync, &info);
1106}
1107
1108static int msm_stats_axi_cfg(struct msm_sync *sync,
1109 struct msm_vfe_cfg_cmd *cfgcmd)
1110{
1111 int rc = -EIO;
1112 struct axidata axi_data;
1113 void *data = &axi_data;
1114
1115 struct msm_pmem_region region[3];
1116 int pmem_type = MSM_PMEM_MAX;
1117
1118 memset(&axi_data, 0, sizeof(axi_data));
1119
1120 switch (cfgcmd->cmd_type) {
1121 case CMD_STATS_AXI_CFG:
1122 pmem_type = MSM_PMEM_AEC_AWB;
1123 break;
1124 case CMD_STATS_AF_AXI_CFG:
1125 pmem_type = MSM_PMEM_AF;
1126 break;
1127 case CMD_GENERAL:
1128 data = NULL;
1129 break;
1130 default:
1131 pr_err("%s: unknown command type %d\n",
1132 __func__, cfgcmd->cmd_type);
1133 return -EINVAL;
1134 }
1135
1136 if (cfgcmd->cmd_type != CMD_GENERAL) {
1137 axi_data.bufnum1 =
1138 msm_pmem_region_lookup(&sync->stats, pmem_type,
1139 &region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
1140 if (!axi_data.bufnum1) {
1141 pr_err("%s: pmem region lookup error\n", __func__);
1142 return -EINVAL;
1143 }
1144 axi_data.region = &region[0];
1145 }
1146
1147 /* send the AEC/AWB STATS configuration command to driver */
1148 if (sync->vfefn.vfe_config)
1149 rc = sync->vfefn.vfe_config(cfgcmd, &axi_data);
1150
1151 return rc;
1152}
1153
1154static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
1155{
1156 int rc = -EIO;
1157
1158 struct msm_stats_buf buf;
1159 unsigned long pphy;
1160 struct msm_vfe_cfg_cmd cfgcmd;
1161
1162 if (copy_from_user(&buf, arg,
1163 sizeof(struct msm_stats_buf))) {
1164 ERR_COPY_FROM_USER();
1165 return -EFAULT;
1166 }
1167
1168 CDBG("msm_put_stats_buffer\n");
1169 pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
1170
1171 if (pphy != 0) {
1172 if (buf.type == STAT_AEAW)
1173 cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
1174 else if (buf.type == STAT_AF)
1175 cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
1176 else {
1177 pr_err("%s: invalid buf type %d\n",
1178 __func__,
1179 buf.type);
1180 rc = -EINVAL;
1181 goto put_done;
1182 }
1183
1184 cfgcmd.value = (void *)&buf;
1185
1186 if (sync->vfefn.vfe_config) {
1187 rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
1188 if (rc < 0)
1189 pr_err("msm_put_stats_buffer: "\
1190 "vfe_config err %d\n", rc);
1191 } else
1192 pr_err("msm_put_stats_buffer: vfe_config is NULL\n");
1193 } else {
1194 pr_err("msm_put_stats_buffer: NULL physical address\n");
1195 rc = -EINVAL;
1196 }
1197
1198put_done:
1199 return rc;
1200}
1201
1202static int msm_axi_config(struct msm_sync *sync, void __user *arg)
1203{
1204 struct msm_vfe_cfg_cmd cfgcmd;
1205
1206 if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
1207 ERR_COPY_FROM_USER();
1208 return -EFAULT;
1209 }
1210
1211 switch (cfgcmd.cmd_type) {
1212 case CMD_AXI_CFG_OUT1:
1213 case CMD_AXI_CFG_OUT2:
1214 case CMD_AXI_CFG_SNAP_O1_AND_O2:
1215 case CMD_RAW_PICT_AXI_CFG:
1216 return msm_frame_axi_cfg(sync, &cfgcmd);
1217
1218 case CMD_STATS_AXI_CFG:
1219 case CMD_STATS_AF_AXI_CFG:
1220 return msm_stats_axi_cfg(sync, &cfgcmd);
1221
1222 default:
1223 pr_err("%s: unknown command type %d\n",
1224 __func__,
1225 cfgcmd.cmd_type);
1226 return -EINVAL;
1227 }
1228
1229 return 0;
1230}
1231
1232static int __msm_get_pic(struct msm_sync *sync, struct msm_ctrl_cmd *ctrl)
1233{
1234 unsigned long flags;
1235 int rc = 0;
1236 int tm;
1237
1238 struct msm_queue_cmd *qcmd = NULL;
1239
1240 tm = (int)ctrl->timeout_ms;
1241
1242 rc = wait_event_interruptible_timeout(
1243 sync->pict_frame_wait,
1244 !list_empty_careful(&sync->pict_frame_q),
1245 msecs_to_jiffies(tm));
1246 if (list_empty_careful(&sync->pict_frame_q)) {
1247 if (rc == 0)
1248 return -ETIMEDOUT;
1249 if (rc < 0) {
1250 pr_err("msm_camera_get_picture, rc = %d\n", rc);
1251 return rc;
1252 }
1253 }
1254
1255 spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
1256 BUG_ON(list_empty(&sync->pict_frame_q));
1257 qcmd = list_first_entry(&sync->pict_frame_q,
1258 struct msm_queue_cmd, list);
1259 list_del_init(&qcmd->list);
1260 spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
1261
1262 if (qcmd->command != NULL) {
1263 struct msm_ctrl_cmd *q =
1264 (struct msm_ctrl_cmd *)qcmd->command;
1265 ctrl->type = q->type;
1266 ctrl->status = q->status;
1267 } else {
1268 ctrl->type = -1;
1269 ctrl->status = -1;
1270 }
1271
1272 kfree(qcmd);
1273 return rc;
1274}
1275
1276static int msm_get_pic(struct msm_sync *sync, void __user *arg)
1277{
1278 struct msm_ctrl_cmd ctrlcmd_t;
1279 int rc;
1280
1281 if (copy_from_user(&ctrlcmd_t,
1282 arg,
1283 sizeof(struct msm_ctrl_cmd))) {
1284 ERR_COPY_FROM_USER();
1285 return -EFAULT;
1286 }
1287
1288 rc = __msm_get_pic(sync, &ctrlcmd_t);
1289 if (rc < 0)
1290 return rc;
1291
1292 if (sync->croplen) {
1293 if (ctrlcmd_t.length < sync->croplen) {
1294 pr_err("msm_get_pic: invalid len %d\n",
1295 ctrlcmd_t.length);
1296 return -EINVAL;
1297 }
1298 if (copy_to_user(ctrlcmd_t.value,
1299 sync->cropinfo,
1300 sync->croplen)) {
1301 ERR_COPY_TO_USER();
1302 return -EFAULT;
1303 }
1304 }
1305
1306 if (copy_to_user((void *)arg,
1307 &ctrlcmd_t,
1308 sizeof(struct msm_ctrl_cmd))) {
1309 ERR_COPY_TO_USER();
1310 return -EFAULT;
1311 }
1312 return 0;
1313}
1314
1315static int msm_set_crop(struct msm_sync *sync, void __user *arg)
1316{
1317 struct crop_info crop;
1318
1319 if (copy_from_user(&crop,
1320 arg,
1321 sizeof(struct crop_info))) {
1322 ERR_COPY_FROM_USER();
1323 return -EFAULT;
1324 }
1325
1326 if (!sync->croplen) {
1327 sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
1328 if (!sync->cropinfo)
1329 return -ENOMEM;
1330 } else if (sync->croplen < crop.len)
1331 return -EINVAL;
1332
1333 if (copy_from_user(sync->cropinfo,
1334 crop.info,
1335 crop.len)) {
1336 ERR_COPY_FROM_USER();
1337 kfree(sync->cropinfo);
1338 return -EFAULT;
1339 }
1340
1341 sync->croplen = crop.len;
1342
1343 return 0;
1344}
1345
1346static int msm_pict_pp_done(struct msm_sync *sync, void __user *arg)
1347{
1348 struct msm_ctrl_cmd udata;
1349 struct msm_ctrl_cmd *ctrlcmd = NULL;
1350 struct msm_queue_cmd *qcmd = NULL;
1351 unsigned long flags;
1352 int rc = 0;
1353
1354 if (!sync->pict_pp)
1355 return -EINVAL;
1356
1357 if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
1358 ERR_COPY_FROM_USER();
1359 rc = -EFAULT;
1360 goto pp_fail;
1361 }
1362
1363 qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
1364 sizeof(struct msm_ctrl_cmd),
1365 GFP_KERNEL);
1366 if (!qcmd) {
1367 rc = -ENOMEM;
1368 goto pp_fail;
1369 }
1370
1371 qcmd->type = MSM_CAM_Q_VFE_MSG;
1372 qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
1373 memset(ctrlcmd, 0, sizeof(struct msm_ctrl_cmd));
1374 ctrlcmd->type = udata.type;
1375 ctrlcmd->status = udata.status;
1376
1377 spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
1378 list_add_tail(&qcmd->list, &sync->pict_frame_q);
1379 spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
1380 wake_up(&sync->pict_frame_wait);
1381
1382pp_fail:
1383 return rc;
1384}
1385
1386static long msm_ioctl_common(struct msm_device *pmsm,
1387 unsigned int cmd,
1388 void __user *argp)
1389{
1390 CDBG("msm_ioctl_common\n");
1391 switch (cmd) {
1392 case MSM_CAM_IOCTL_REGISTER_PMEM:
1393 return msm_register_pmem(pmsm->sync, argp);
1394 case MSM_CAM_IOCTL_UNREGISTER_PMEM:
1395 return msm_pmem_table_del(pmsm->sync, argp);
1396 default:
1397 return -EINVAL;
1398 }
1399}
1400
1401static long msm_ioctl_config(struct file *filep, unsigned int cmd,
1402 unsigned long arg)
1403{
1404 int rc = -EINVAL;
1405 void __user *argp = (void __user *)arg;
1406 struct msm_device *pmsm = filep->private_data;
1407
1408 CDBG("msm_ioctl_config cmd = %d\n", _IOC_NR(cmd));
1409
1410 switch (cmd) {
1411 case MSM_CAM_IOCTL_GET_SENSOR_INFO:
1412 rc = msm_get_sensor_info(pmsm->sync, argp);
1413 break;
1414
1415 case MSM_CAM_IOCTL_CONFIG_VFE:
1416 /* Coming from config thread for update */
1417 rc = msm_config_vfe(pmsm->sync, argp);
1418 break;
1419
1420 case MSM_CAM_IOCTL_GET_STATS:
1421 /* Coming from config thread wait
1422 * for vfe statistics and control requests */
1423 rc = msm_get_stats(pmsm->sync, argp);
1424 break;
1425
1426 case MSM_CAM_IOCTL_ENABLE_VFE:
1427 /* This request comes from control thread:
1428 * enable either QCAMTASK or VFETASK */
1429 rc = msm_enable_vfe(pmsm->sync, argp);
1430 break;
1431
1432 case MSM_CAM_IOCTL_DISABLE_VFE:
1433 /* This request comes from control thread:
1434 * disable either QCAMTASK or VFETASK */
1435 rc = msm_disable_vfe(pmsm->sync, argp);
1436 break;
1437
1438 case MSM_CAM_IOCTL_VFE_APPS_RESET:
1439 msm_camio_vfe_blk_reset();
1440 rc = 0;
1441 break;
1442
1443 case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
1444 rc = msm_put_stats_buffer(pmsm->sync, argp);
1445 break;
1446
1447 case MSM_CAM_IOCTL_AXI_CONFIG:
1448 rc = msm_axi_config(pmsm->sync, argp);
1449 break;
1450
1451 case MSM_CAM_IOCTL_SET_CROP:
1452 rc = msm_set_crop(pmsm->sync, argp);
1453 break;
1454
1455 case MSM_CAM_IOCTL_PICT_PP: {
1456 uint8_t enable;
1457 if (copy_from_user(&enable, argp, sizeof(enable))) {
1458 ERR_COPY_FROM_USER();
1459 rc = -EFAULT;
1460 } else {
1461 pmsm->sync->pict_pp = enable;
1462 rc = 0;
1463 }
1464 break;
1465 }
1466
1467 case MSM_CAM_IOCTL_PICT_PP_DONE:
1468 rc = msm_pict_pp_done(pmsm->sync, argp);
1469 break;
1470
1471 case MSM_CAM_IOCTL_SENSOR_IO_CFG:
1472 rc = pmsm->sync->sctrl.s_config(argp);
1473 break;
1474
1475 case MSM_CAM_IOCTL_FLASH_LED_CFG: {
1476 uint32_t led_state;
1477 if (copy_from_user(&led_state, argp, sizeof(led_state))) {
1478 ERR_COPY_FROM_USER();
1479 rc = -EFAULT;
1480 } else
1481 rc = msm_camera_flash_set_led_state(led_state);
1482 break;
1483 }
1484
1485 default:
1486 rc = msm_ioctl_common(pmsm, cmd, argp);
1487 break;
1488 }
1489
1490 CDBG("msm_ioctl_config cmd = %d DONE\n", _IOC_NR(cmd));
1491 return rc;
1492}
1493
1494static int msm_unblock_poll_frame(struct msm_sync *);
1495
1496static long msm_ioctl_frame(struct file *filep, unsigned int cmd,
1497 unsigned long arg)
1498{
1499 int rc = -EINVAL;
1500 void __user *argp = (void __user *)arg;
1501 struct msm_device *pmsm = filep->private_data;
1502
1503
1504 switch (cmd) {
1505 case MSM_CAM_IOCTL_GETFRAME:
1506 /* Coming from frame thread to get frame
1507 * after SELECT is done */
1508 rc = msm_get_frame(pmsm->sync, argp);
1509 break;
1510 case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
1511 rc = msm_put_frame_buffer(pmsm->sync, argp);
1512 break;
1513 case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME:
1514 rc = msm_unblock_poll_frame(pmsm->sync);
1515 break;
1516 default:
1517 break;
1518 }
1519
1520 return rc;
1521}
1522
1523
1524static long msm_ioctl_control(struct file *filep, unsigned int cmd,
1525 unsigned long arg)
1526{
1527 int rc = -EINVAL;
1528 void __user *argp = (void __user *)arg;
1529 struct msm_control_device *ctrl_pmsm = filep->private_data;
1530 struct msm_device *pmsm = ctrl_pmsm->pmsm;
1531
1532 switch (cmd) {
1533 case MSM_CAM_IOCTL_CTRL_COMMAND:
1534 /* Coming from control thread, may need to wait for
1535 * command status */
1536 rc = msm_control(ctrl_pmsm, 1, argp);
1537 break;
1538 case MSM_CAM_IOCTL_CTRL_COMMAND_2:
1539 /* Sends a message, returns immediately */
1540 rc = msm_control(ctrl_pmsm, 0, argp);
1541 break;
1542 case MSM_CAM_IOCTL_CTRL_CMD_DONE:
1543 /* Config thread calls the control thread to notify it
1544 * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND.
1545 */
1546 rc = msm_ctrl_cmd_done(ctrl_pmsm, argp);
1547 break;
1548 case MSM_CAM_IOCTL_GET_PICTURE:
1549 rc = msm_get_pic(pmsm->sync, argp);
1550 break;
1551 default:
1552 rc = msm_ioctl_common(pmsm, cmd, argp);
1553 break;
1554 }
1555
1556 return rc;
1557}
1558
1559static int __msm_release(struct msm_sync *sync)
1560{
1561 struct msm_pmem_region *region;
1562 struct hlist_node *hnode;
1563 struct hlist_node *n;
1564
1565 mutex_lock(&sync->lock);
1566 if (sync->opencnt)
1567 sync->opencnt--;
1568
1569 if (!sync->opencnt) {
1570 /* need to clean up system resource */
1571 if (sync->vfefn.vfe_release)
1572 sync->vfefn.vfe_release(sync->pdev);
1573
1574 if (sync->cropinfo) {
1575 kfree(sync->cropinfo);
1576 sync->cropinfo = NULL;
1577 sync->croplen = 0;
1578 }
1579
1580 hlist_for_each_entry_safe(region, hnode, n,
1581 &sync->frame, list) {
1582 hlist_del(hnode);
1583 put_pmem_file(region->file);
1584 kfree(region);
1585 }
1586
1587 hlist_for_each_entry_safe(region, hnode, n,
1588 &sync->stats, list) {
1589 hlist_del(hnode);
1590 put_pmem_file(region->file);
1591 kfree(region);
1592 }
1593
1594 MSM_DRAIN_QUEUE(sync, msg_event_q);
1595 MSM_DRAIN_QUEUE(sync, prev_frame_q);
1596 MSM_DRAIN_QUEUE(sync, pict_frame_q);
1597
1598 sync->sctrl.s_release();
1599
1600 sync->apps_id = NULL;
1601 CDBG("msm_release completed!\n");
1602 }
1603 mutex_unlock(&sync->lock);
1604
1605 return 0;
1606}
1607
1608static int msm_release_config(struct inode *node, struct file *filep)
1609{
1610 int rc;
1611 struct msm_device *pmsm = filep->private_data;
1612 printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
1613 rc = __msm_release(pmsm->sync);
1614 atomic_set(&pmsm->opened, 0);
1615 return rc;
1616}
1617
1618static int msm_release_control(struct inode *node, struct file *filep)
1619{
1620 int rc;
1621 struct msm_control_device *ctrl_pmsm = filep->private_data;
1622 struct msm_device *pmsm = ctrl_pmsm->pmsm;
1623 printk(KERN_INFO "msm_camera: RELEASE %s\n",
1624 filep->f_path.dentry->d_name.name);
1625 rc = __msm_release(pmsm->sync);
1626 if (!rc) {
1627 MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
1628 MSM_DRAIN_QUEUE(pmsm->sync, pict_frame_q);
1629 }
1630 kfree(ctrl_pmsm);
1631 return rc;
1632}
1633
1634static int msm_release_frame(struct inode *node, struct file *filep)
1635{
1636 int rc;
1637 struct msm_device *pmsm = filep->private_data;
1638 printk(KERN_INFO "msm_camera: RELEASE %s\n",
1639 filep->f_path.dentry->d_name.name);
1640 rc = __msm_release(pmsm->sync);
1641 if (!rc) {
1642 MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
1643 atomic_set(&pmsm->opened, 0);
1644 }
1645 return rc;
1646}
1647
1648static int msm_unblock_poll_frame(struct msm_sync *sync)
1649{
1650 unsigned long flags;
1651 CDBG("msm_unblock_poll_frame\n");
1652 spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
1653 sync->unblock_poll_frame = 1;
1654 wake_up(&sync->prev_frame_wait);
1655 spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
1656 return 0;
1657}
1658
1659static unsigned int __msm_poll_frame(struct msm_sync *sync,
1660 struct file *filep,
1661 struct poll_table_struct *pll_table)
1662{
1663 int rc = 0;
1664 unsigned long flags;
1665
1666 poll_wait(filep, &sync->prev_frame_wait, pll_table);
1667
1668 spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
1669 if (!list_empty_careful(&sync->prev_frame_q))
1670 /* frame ready */
1671 rc = POLLIN | POLLRDNORM;
1672 if (sync->unblock_poll_frame) {
1673 CDBG("%s: sync->unblock_poll_frame is true\n", __func__);
1674 rc |= POLLPRI;
1675 sync->unblock_poll_frame = 0;
1676 }
1677 spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
1678
1679 return rc;
1680}
1681
1682static unsigned int msm_poll_frame(struct file *filep,
1683 struct poll_table_struct *pll_table)
1684{
1685 struct msm_device *pmsm = filep->private_data;
1686 return __msm_poll_frame(pmsm->sync, filep, pll_table);
1687}
1688
1689/*
1690 * This function executes in interrupt context.
1691 */
1692
1693static void *msm_vfe_sync_alloc(int size,
1694 void *syncdata __attribute__((unused)))
1695{
1696 struct msm_queue_cmd *qcmd =
1697 kmalloc(sizeof(struct msm_queue_cmd) + size, GFP_ATOMIC);
1698 return qcmd ? qcmd + 1 : NULL;
1699}
1700
1701/*
1702 * This function executes in interrupt context.
1703 */
1704
1705static void msm_vfe_sync(struct msm_vfe_resp *vdata,
1706 enum msm_queue qtype, void *syncdata)
1707{
1708 struct msm_queue_cmd *qcmd = NULL;
1709 struct msm_queue_cmd *qcmd_frame = NULL;
1710 struct msm_vfe_phy_info *fphy;
1711
1712 unsigned long flags;
1713 struct msm_sync *sync = (struct msm_sync *)syncdata;
1714 if (!sync) {
1715 pr_err("msm_camera: no context in dsp callback.\n");
1716 return;
1717 }
1718
1719 qcmd = ((struct msm_queue_cmd *)vdata) - 1;
1720 qcmd->type = qtype;
1721
1722 if (qtype == MSM_CAM_Q_VFE_MSG) {
1723 switch (vdata->type) {
1724 case VFE_MSG_OUTPUT1:
1725 case VFE_MSG_OUTPUT2:
1726 qcmd_frame =
1727 kmalloc(sizeof(struct msm_queue_cmd) +
1728 sizeof(struct msm_vfe_phy_info),
1729 GFP_ATOMIC);
1730 if (!qcmd_frame)
1731 goto mem_fail;
1732 fphy = (struct msm_vfe_phy_info *)(qcmd_frame + 1);
1733 *fphy = vdata->phy;
1734
1735 qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
1736 qcmd_frame->command = fphy;
1737
1738 CDBG("qcmd_frame= 0x%x phy_y= 0x%x, phy_cbcr= 0x%x\n",
1739 (int) qcmd_frame, fphy->y_phy, fphy->cbcr_phy);
1740
1741 spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
1742 list_add_tail(&qcmd_frame->list, &sync->prev_frame_q);
1743 wake_up(&sync->prev_frame_wait);
1744 spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
1745 CDBG("woke up frame thread\n");
1746 break;
1747 case VFE_MSG_SNAPSHOT:
1748 if (sync->pict_pp)
1749 break;
1750
1751 CDBG("snapshot pp = %d\n", sync->pict_pp);
1752 qcmd_frame =
1753 kmalloc(sizeof(struct msm_queue_cmd),
1754 GFP_ATOMIC);
1755 if (!qcmd_frame)
1756 goto mem_fail;
1757 qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
1758 qcmd_frame->command = NULL;
1759 spin_lock_irqsave(&sync->pict_frame_q_lock,
1760 flags);
1761 list_add_tail(&qcmd_frame->list, &sync->pict_frame_q);
1762 wake_up(&sync->pict_frame_wait);
1763 spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
1764 CDBG("woke up picture thread\n");
1765 break;
1766 default:
1767 CDBG("%s: qtype = %d not handled\n",
1768 __func__, vdata->type);
1769 break;
1770 }
1771 }
1772
1773 qcmd->command = (void *)vdata;
1774 CDBG("vdata->type = %d\n", vdata->type);
1775
1776 spin_lock_irqsave(&sync->msg_event_q_lock, flags);
1777 list_add_tail(&qcmd->list, &sync->msg_event_q);
1778 wake_up(&sync->msg_event_wait);
1779 spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
1780 CDBG("woke up config thread\n");
1781 return;
1782
1783mem_fail:
1784 kfree(qcmd);
1785}
1786
1787static struct msm_vfe_callback msm_vfe_s = {
1788 .vfe_resp = msm_vfe_sync,
1789 .vfe_alloc = msm_vfe_sync_alloc,
1790};
1791
1792static int __msm_open(struct msm_sync *sync, const char *const apps_id)
1793{
1794 int rc = 0;
1795
1796 mutex_lock(&sync->lock);
1797 if (sync->apps_id && strcmp(sync->apps_id, apps_id)) {
1798 pr_err("msm_camera(%s): sensor %s is already opened for %s\n",
1799 apps_id,
1800 sync->sdata->sensor_name,
1801 sync->apps_id);
1802 rc = -EBUSY;
1803 goto msm_open_done;
1804 }
1805
1806 sync->apps_id = apps_id;
1807
1808 if (!sync->opencnt) {
1809
1810 msm_camvfe_fn_init(&sync->vfefn, sync);
1811 if (sync->vfefn.vfe_init) {
1812 rc = sync->vfefn.vfe_init(&msm_vfe_s,
1813 sync->pdev);
1814 if (rc < 0) {
1815 pr_err("vfe_init failed at %d\n", rc);
1816 goto msm_open_done;
1817 }
1818 rc = sync->sctrl.s_init(sync->sdata);
1819 if (rc < 0) {
1820 pr_err("sensor init failed: %d\n", rc);
1821 goto msm_open_done;
1822 }
1823 } else {
1824 pr_err("no sensor init func\n");
1825 rc = -ENODEV;
1826 goto msm_open_done;
1827 }
1828
1829 if (rc >= 0) {
1830 INIT_HLIST_HEAD(&sync->frame);
1831 INIT_HLIST_HEAD(&sync->stats);
1832 sync->unblock_poll_frame = 0;
1833 }
1834 }
1835 sync->opencnt++;
1836
1837msm_open_done:
1838 mutex_unlock(&sync->lock);
1839 return rc;
1840}
1841
1842static int msm_open_common(struct inode *inode, struct file *filep,
1843 int once)
1844{
1845 int rc;
1846 struct msm_device *pmsm =
1847 container_of(inode->i_cdev, struct msm_device, cdev);
1848
1849 CDBG("msm_camera: open %s\n", filep->f_path.dentry->d_name.name);
1850
1851 if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) {
1852 pr_err("msm_camera: %s is already opened.\n",
1853 filep->f_path.dentry->d_name.name);
1854 return -EBUSY;
1855 }
1856
1857 rc = nonseekable_open(inode, filep);
1858 if (rc < 0) {
1859 pr_err("msm_open: nonseekable_open error %d\n", rc);
1860 return rc;
1861 }
1862
1863 rc = __msm_open(pmsm->sync, MSM_APPS_ID_PROP);
1864 if (rc < 0)
1865 return rc;
1866
1867 filep->private_data = pmsm;
1868
1869 CDBG("msm_open() open: rc = %d\n", rc);
1870 return rc;
1871}
1872
1873static int msm_open(struct inode *inode, struct file *filep)
1874{
1875 return msm_open_common(inode, filep, 1);
1876}
1877
1878static int msm_open_control(struct inode *inode, struct file *filep)
1879{
1880 int rc;
1881
1882 struct msm_control_device *ctrl_pmsm =
1883 kmalloc(sizeof(struct msm_control_device), GFP_KERNEL);
1884 if (!ctrl_pmsm)
1885 return -ENOMEM;
1886
1887 rc = msm_open_common(inode, filep, 0);
1888 if (rc < 0) {
1889 kfree(ctrl_pmsm);
1890 return rc;
1891 }
1892
1893 ctrl_pmsm->pmsm = filep->private_data;
1894 filep->private_data = ctrl_pmsm;
1895 spin_lock_init(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock);
1896 INIT_LIST_HEAD(&ctrl_pmsm->ctrl_q.ctrl_status_q);
1897 init_waitqueue_head(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
1898
1899 CDBG("msm_open() open: rc = %d\n", rc);
1900 return rc;
1901}
1902
1903static int __msm_v4l2_control(struct msm_sync *sync,
1904 struct msm_ctrl_cmd *out)
1905{
1906 int rc = 0;
1907
1908 struct msm_queue_cmd *qcmd = NULL, *rcmd = NULL;
1909 struct msm_ctrl_cmd *ctrl;
1910 struct msm_control_device_queue FIXME;
1911
1912 /* wake up config thread, 4 is for V4L2 application */
1913 qcmd = kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
1914 if (!qcmd) {
1915 pr_err("msm_control: cannot allocate buffer\n");
1916 rc = -ENOMEM;
1917 goto end;
1918 }
1919 qcmd->type = MSM_CAM_Q_V4L2_REQ;
1920 qcmd->command = out;
1921
1922 rcmd = __msm_control(sync, &FIXME, qcmd, out->timeout_ms);
1923 if (IS_ERR(rcmd)) {
1924 rc = PTR_ERR(rcmd);
1925 goto end;
1926 }
1927
1928 ctrl = (struct msm_ctrl_cmd *)(rcmd->command);
1929 /* FIXME: we should just set out->length = ctrl->length; */
1930 BUG_ON(out->length < ctrl->length);
1931 memcpy(out->value, ctrl->value, ctrl->length);
1932
1933end:
1934 kfree(rcmd);
1935 CDBG("__msm_v4l2_control: end rc = %d\n", rc);
1936 return rc;
1937}
1938
1939static const struct file_operations msm_fops_config = {
1940 .owner = THIS_MODULE,
1941 .open = msm_open,
1942 .unlocked_ioctl = msm_ioctl_config,
1943 .release = msm_release_config,
1944 .llseek = no_llseek,
1945};
1946
1947static const struct file_operations msm_fops_control = {
1948 .owner = THIS_MODULE,
1949 .open = msm_open_control,
1950 .unlocked_ioctl = msm_ioctl_control,
1951 .release = msm_release_control,
1952 .llseek = no_llseek,
1953};
1954
1955static const struct file_operations msm_fops_frame = {
1956 .owner = THIS_MODULE,
1957 .open = msm_open,
1958 .unlocked_ioctl = msm_ioctl_frame,
1959 .release = msm_release_frame,
1960 .poll = msm_poll_frame,
1961 .llseek = no_llseek,
1962};
1963
1964static int msm_setup_cdev(struct msm_device *msm,
1965 int node,
1966 dev_t devno,
1967 const char *suffix,
1968 const struct file_operations *fops)
1969{
1970 int rc = -ENODEV;
1971
1972 struct device *device =
1973 device_create(msm_class, NULL,
1974 devno, NULL,
1975 "%s%d", suffix, node);
1976
1977 if (IS_ERR(device)) {
1978 rc = PTR_ERR(device);
1979 pr_err("msm_camera: error creating device: %d\n", rc);
1980 return rc;
1981 }
1982
1983 cdev_init(&msm->cdev, fops);
1984 msm->cdev.owner = THIS_MODULE;
1985
1986 rc = cdev_add(&msm->cdev, devno, 1);
1987 if (rc < 0) {
1988 pr_err("msm_camera: error adding cdev: %d\n", rc);
1989 device_destroy(msm_class, devno);
1990 return rc;
1991 }
1992
1993 return rc;
1994}
1995
1996static int msm_tear_down_cdev(struct msm_device *msm, dev_t devno)
1997{
1998 cdev_del(&msm->cdev);
1999 device_destroy(msm_class, devno);
2000 return 0;
2001}
2002
2003int msm_v4l2_register(struct msm_v4l2_driver *drv)
2004{
2005 /* FIXME: support multiple sensors */
2006 if (list_empty(&msm_sensors))
2007 return -ENODEV;
2008
2009 drv->sync = list_first_entry(&msm_sensors, struct msm_sync, list);
2010 drv->open = __msm_open;
2011 drv->release = __msm_release;
2012 drv->ctrl = __msm_v4l2_control;
2013 drv->reg_pmem = __msm_register_pmem;
2014 drv->get_frame = __msm_get_frame;
2015 drv->put_frame = __msm_put_frame_buf;
2016 drv->get_pict = __msm_get_pic;
2017 drv->drv_poll = __msm_poll_frame;
2018
2019 return 0;
2020}
2021EXPORT_SYMBOL(msm_v4l2_register);
2022
2023int msm_v4l2_unregister(struct msm_v4l2_driver *drv)
2024{
2025 drv->sync = NULL;
2026 return 0;
2027}
2028EXPORT_SYMBOL(msm_v4l2_unregister);
2029
2030static int msm_sync_init(struct msm_sync *sync,
2031 struct platform_device *pdev,
2032 int (*sensor_probe)(const struct msm_camera_sensor_info *,
2033 struct msm_sensor_ctrl *))
2034{
2035 int rc = 0;
2036 struct msm_sensor_ctrl sctrl;
2037 sync->sdata = pdev->dev.platform_data;
2038
2039 spin_lock_init(&sync->msg_event_q_lock);
2040 INIT_LIST_HEAD(&sync->msg_event_q);
2041 init_waitqueue_head(&sync->msg_event_wait);
2042
2043 spin_lock_init(&sync->prev_frame_q_lock);
2044 INIT_LIST_HEAD(&sync->prev_frame_q);
2045 init_waitqueue_head(&sync->prev_frame_wait);
2046
2047 spin_lock_init(&sync->pict_frame_q_lock);
2048 INIT_LIST_HEAD(&sync->pict_frame_q);
2049 init_waitqueue_head(&sync->pict_frame_wait);
2050
2051 rc = msm_camio_probe_on(pdev);
2052 if (rc < 0)
2053 return rc;
2054 rc = sensor_probe(sync->sdata, &sctrl);
2055 if (rc >= 0) {
2056 sync->pdev = pdev;
2057 sync->sctrl = sctrl;
2058 }
2059 msm_camio_probe_off(pdev);
2060 if (rc < 0) {
2061 pr_err("msm_camera: failed to initialize %s\n",
2062 sync->sdata->sensor_name);
2063 return rc;
2064 }
2065
2066 sync->opencnt = 0;
2067 mutex_init(&sync->lock);
2068 CDBG("initialized %s\n", sync->sdata->sensor_name);
2069 return rc;
2070}
2071
2072static int msm_sync_destroy(struct msm_sync *sync)
2073{
2074 return 0;
2075}
2076
2077static int msm_device_init(struct msm_device *pmsm,
2078 struct msm_sync *sync,
2079 int node)
2080{
2081 int dev_num = 3 * node;
2082 int rc = msm_setup_cdev(pmsm, node,
2083 MKDEV(MAJOR(msm_devno), dev_num),
2084 "control", &msm_fops_control);
2085 if (rc < 0) {
2086 pr_err("error creating control node: %d\n", rc);
2087 return rc;
2088 }
2089
2090 rc = msm_setup_cdev(pmsm + 1, node,
2091 MKDEV(MAJOR(msm_devno), dev_num + 1),
2092 "config", &msm_fops_config);
2093 if (rc < 0) {
2094 pr_err("error creating config node: %d\n", rc);
2095 msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno),
2096 dev_num));
2097 return rc;
2098 }
2099
2100 rc = msm_setup_cdev(pmsm + 2, node,
2101 MKDEV(MAJOR(msm_devno), dev_num + 2),
2102 "frame", &msm_fops_frame);
2103 if (rc < 0) {
2104 pr_err("error creating frame node: %d\n", rc);
2105 msm_tear_down_cdev(pmsm,
2106 MKDEV(MAJOR(msm_devno), dev_num));
2107 msm_tear_down_cdev(pmsm + 1,
2108 MKDEV(MAJOR(msm_devno), dev_num + 1));
2109 return rc;
2110 }
2111
2112 atomic_set(&pmsm[0].opened, 0);
2113 atomic_set(&pmsm[1].opened, 0);
2114 atomic_set(&pmsm[2].opened, 0);
2115
2116 pmsm[0].sync = sync;
2117 pmsm[1].sync = sync;
2118 pmsm[2].sync = sync;
2119
2120 return rc;
2121}
2122
2123int msm_camera_drv_start(struct platform_device *dev,
2124 int (*sensor_probe)(const struct msm_camera_sensor_info *,
2125 struct msm_sensor_ctrl *))
2126{
2127 struct msm_device *pmsm = NULL;
2128 struct msm_sync *sync;
2129 int rc = -ENODEV;
2130 static int camera_node;
2131
2132 if (camera_node >= MSM_MAX_CAMERA_SENSORS) {
2133 pr_err("msm_camera: too many camera sensors\n");
2134 return rc;
2135 }
2136
2137 if (!msm_class) {
2138 /* There are three device nodes per sensor */
2139 rc = alloc_chrdev_region(&msm_devno, 0,
2140 3 * MSM_MAX_CAMERA_SENSORS,
2141 "msm_camera");
2142 if (rc < 0) {
2143 pr_err("msm_camera: failed to allocate chrdev: %d\n",
2144 rc);
2145 return rc;
2146 }
2147
2148 msm_class = class_create(THIS_MODULE, "msm_camera");
2149 if (IS_ERR(msm_class)) {
2150 rc = PTR_ERR(msm_class);
2151 pr_err("msm_camera: create device class failed: %d\n",
2152 rc);
2153 return rc;
2154 }
2155 }
2156
2157 pmsm = kzalloc(sizeof(struct msm_device) * 3 +
2158 sizeof(struct msm_sync), GFP_ATOMIC);
2159 if (!pmsm)
2160 return -ENOMEM;
2161 sync = (struct msm_sync *)(pmsm + 3);
2162
2163 rc = msm_sync_init(sync, dev, sensor_probe);
2164 if (rc < 0) {
2165 kfree(pmsm);
2166 return rc;
2167 }
2168
2169 CDBG("setting camera node %d\n", camera_node);
2170 rc = msm_device_init(pmsm, sync, camera_node);
2171 if (rc < 0) {
2172 msm_sync_destroy(sync);
2173 kfree(pmsm);
2174 return rc;
2175 }
2176
2177 camera_node++;
2178 list_add(&sync->list, &msm_sensors);
2179 return rc;
2180}
2181EXPORT_SYMBOL(msm_camera_drv_start);
diff --git a/drivers/staging/dream/camera/msm_io7x.c b/drivers/staging/dream/camera/msm_io7x.c
deleted file mode 100644
index 55c020bb7afa..000000000000
--- a/drivers/staging/dream/camera/msm_io7x.c
+++ /dev/null
@@ -1,291 +0,0 @@
1/*
2 * Copyright (c) 2008-2009 QUALCOMM Incorporated
3 */
4
5#include <linux/delay.h>
6#include <linux/clk.h>
7#include <linux/io.h>
8#include <mach/gpio.h>
9#include <mach/board.h>
10#include <mach/camera.h>
11
12#define CAMIF_CFG_RMSK 0x1fffff
13#define CAM_SEL_BMSK 0x2
14#define CAM_PCLK_SRC_SEL_BMSK 0x60000
15#define CAM_PCLK_INVERT_BMSK 0x80000
16#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
17
18#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
19#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
20#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
21
22#define CAM_SEL_SHFT 0x1
23#define CAM_PCLK_SRC_SEL_SHFT 0x11
24#define CAM_PCLK_INVERT_SHFT 0x13
25#define CAM_PAD_REG_SW_RESET_SHFT 0x14
26
27#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
28#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
29#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
30#define APPS_RESET_OFFSET 0x00000210
31
32static struct clk *camio_vfe_mdc_clk;
33static struct clk *camio_mdc_clk;
34static struct clk *camio_vfe_clk;
35
36static struct msm_camera_io_ext camio_ext;
37static struct resource *appio, *mdcio;
38void __iomem *appbase, *mdcbase;
39
40static struct msm_camera_io_ext camio_ext;
41static struct resource *appio, *mdcio;
42void __iomem *appbase, *mdcbase;
43
44extern int clk_set_flags(struct clk *clk, unsigned long flags);
45
46int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
47{
48 int rc = -1;
49 struct clk *clk = NULL;
50
51 switch (clktype) {
52 case CAMIO_VFE_MDC_CLK:
53 clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
54 break;
55
56 case CAMIO_MDC_CLK:
57 clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
58 break;
59
60 case CAMIO_VFE_CLK:
61 clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
62 break;
63
64 default:
65 break;
66 }
67
68 if (!IS_ERR(clk)) {
69 clk_enable(clk);
70 rc = 0;
71 }
72
73 return rc;
74}
75
76int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
77{
78 int rc = -1;
79 struct clk *clk = NULL;
80
81 switch (clktype) {
82 case CAMIO_VFE_MDC_CLK:
83 clk = camio_vfe_mdc_clk;
84 break;
85
86 case CAMIO_MDC_CLK:
87 clk = camio_mdc_clk;
88 break;
89
90 case CAMIO_VFE_CLK:
91 clk = camio_vfe_clk;
92 break;
93
94 default:
95 break;
96 }
97
98 if (!IS_ERR(clk)) {
99 clk_disable(clk);
100 clk_put(clk);
101 rc = 0;
102 }
103
104 return rc;
105}
106
107void msm_camio_clk_rate_set(int rate)
108{
109 struct clk *clk = camio_vfe_clk;
110
111 if (clk != ERR_PTR(-ENOENT))
112 clk_set_rate(clk, rate);
113}
114
115int msm_camio_enable(struct platform_device *pdev)
116{
117 int rc = 0;
118 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
119 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
120
121 camio_ext = camdev->ioext;
122
123 appio = request_mem_region(camio_ext.appphy,
124 camio_ext.appsz, pdev->name);
125 if (!appio) {
126 rc = -EBUSY;
127 goto enable_fail;
128 }
129
130 appbase = ioremap(camio_ext.appphy,
131 camio_ext.appsz);
132 if (!appbase) {
133 rc = -ENOMEM;
134 goto apps_no_mem;
135 }
136
137 mdcio = request_mem_region(camio_ext.mdcphy,
138 camio_ext.mdcsz, pdev->name);
139 if (!mdcio) {
140 rc = -EBUSY;
141 goto mdc_busy;
142 }
143
144 mdcbase = ioremap(camio_ext.mdcphy,
145 camio_ext.mdcsz);
146 if (!mdcbase) {
147 rc = -ENOMEM;
148 goto mdc_no_mem;
149 }
150
151 camdev->camera_gpio_on();
152
153 msm_camio_clk_enable(CAMIO_VFE_CLK);
154 msm_camio_clk_enable(CAMIO_MDC_CLK);
155 msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
156 return 0;
157
158mdc_no_mem:
159 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
160mdc_busy:
161 iounmap(appbase);
162apps_no_mem:
163 release_mem_region(camio_ext.appphy, camio_ext.appsz);
164enable_fail:
165 return rc;
166}
167
168void msm_camio_disable(struct platform_device *pdev)
169{
170 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
171 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
172
173 iounmap(mdcbase);
174 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
175 iounmap(appbase);
176 release_mem_region(camio_ext.appphy, camio_ext.appsz);
177
178 camdev->camera_gpio_off();
179
180 msm_camio_clk_disable(CAMIO_VFE_CLK);
181 msm_camio_clk_disable(CAMIO_MDC_CLK);
182 msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
183}
184
185void msm_camio_camif_pad_reg_reset(void)
186{
187 uint32_t reg;
188 uint32_t mask, value;
189
190 /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
191 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
192
193 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
194
195 mask = CAM_SEL_BMSK |
196 CAM_PCLK_SRC_SEL_BMSK |
197 CAM_PCLK_INVERT_BMSK;
198
199 value = 1 << CAM_SEL_SHFT |
200 3 << CAM_PCLK_SRC_SEL_SHFT |
201 0 << CAM_PCLK_INVERT_SHFT;
202
203 writel((reg & (~mask)) | (value & mask), mdcbase);
204 mdelay(10);
205
206 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
207 mask = CAM_PAD_REG_SW_RESET_BMSK;
208 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
209 writel((reg & (~mask)) | (value & mask), mdcbase);
210 mdelay(10);
211
212 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
213 mask = CAM_PAD_REG_SW_RESET_BMSK;
214 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
215 writel((reg & (~mask)) | (value & mask), mdcbase);
216 mdelay(10);
217
218 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
219 mdelay(10);
220}
221
222void msm_camio_vfe_blk_reset(void)
223{
224 uint32_t val;
225
226 val = readl(appbase + 0x00000210);
227 val |= 0x1;
228 writel(val, appbase + 0x00000210);
229 mdelay(10);
230
231 val = readl(appbase + 0x00000210);
232 val &= ~0x1;
233 writel(val, appbase + 0x00000210);
234 mdelay(10);
235}
236
237void msm_camio_camif_pad_reg_reset_2(void)
238{
239 uint32_t reg;
240 uint32_t mask, value;
241
242 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
243 mask = CAM_PAD_REG_SW_RESET_BMSK;
244 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
245 writel((reg & (~mask)) | (value & mask), mdcbase);
246 mdelay(10);
247
248 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
249 mask = CAM_PAD_REG_SW_RESET_BMSK;
250 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
251 writel((reg & (~mask)) | (value & mask), mdcbase);
252 mdelay(10);
253}
254
255void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
256{
257 struct clk *clk = NULL;
258
259 clk = camio_vfe_clk;
260
261 if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
262 switch (srctype) {
263 case MSM_CAMIO_CLK_SRC_INTERNAL:
264 clk_set_flags(clk, 0x00000100 << 1);
265 break;
266
267 case MSM_CAMIO_CLK_SRC_EXTERNAL:
268 clk_set_flags(clk, 0x00000100);
269 break;
270
271 default:
272 break;
273 }
274 }
275}
276
277int msm_camio_probe_on(struct platform_device *pdev)
278{
279 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
280 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
281 camdev->camera_gpio_on();
282 return msm_camio_clk_enable(CAMIO_VFE_CLK);
283}
284
285int msm_camio_probe_off(struct platform_device *pdev)
286{
287 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
288 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
289 camdev->camera_gpio_off();
290 return msm_camio_clk_disable(CAMIO_VFE_CLK);
291}
diff --git a/drivers/staging/dream/camera/msm_io8x.c b/drivers/staging/dream/camera/msm_io8x.c
deleted file mode 100644
index 895161ae2e14..000000000000
--- a/drivers/staging/dream/camera/msm_io8x.c
+++ /dev/null
@@ -1,320 +0,0 @@
1/*
2 * Copyright (c) 2008-2009 QUALCOMM Incorporated
3 */
4
5#include <linux/delay.h>
6#include <linux/clk.h>
7#include <linux/io.h>
8#include <mach/gpio.h>
9#include <mach/board.h>
10#include <mach/camera.h>
11
12#define CAMIF_CFG_RMSK 0x1fffff
13#define CAM_SEL_BMSK 0x2
14#define CAM_PCLK_SRC_SEL_BMSK 0x60000
15#define CAM_PCLK_INVERT_BMSK 0x80000
16#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
17
18#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
19#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
20#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
21
22#define CAM_SEL_SHFT 0x1
23#define CAM_PCLK_SRC_SEL_SHFT 0x11
24#define CAM_PCLK_INVERT_SHFT 0x13
25#define CAM_PAD_REG_SW_RESET_SHFT 0x14
26
27#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
28#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
29#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
30#define APPS_RESET_OFFSET 0x00000210
31
32static struct clk *camio_vfe_mdc_clk;
33static struct clk *camio_mdc_clk;
34static struct clk *camio_vfe_clk;
35static struct clk *camio_vfe_axi_clk;
36static struct msm_camera_io_ext camio_ext;
37static struct resource *appio, *mdcio;
38void __iomem *appbase, *mdcbase;
39
40extern int clk_set_flags(struct clk *clk, unsigned long flags);
41
42int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
43{
44 int rc = 0;
45 struct clk *clk = NULL;
46
47 switch (clktype) {
48 case CAMIO_VFE_MDC_CLK:
49 camio_vfe_mdc_clk =
50 clk = clk_get(NULL, "vfe_mdc_clk");
51 break;
52
53 case CAMIO_MDC_CLK:
54 camio_mdc_clk =
55 clk = clk_get(NULL, "mdc_clk");
56 break;
57
58 case CAMIO_VFE_CLK:
59 camio_vfe_clk =
60 clk = clk_get(NULL, "vfe_clk");
61 break;
62
63 case CAMIO_VFE_AXI_CLK:
64 camio_vfe_axi_clk =
65 clk = clk_get(NULL, "vfe_axi_clk");
66 break;
67
68 default:
69 break;
70 }
71
72 if (!IS_ERR(clk))
73 clk_enable(clk);
74 else
75 rc = -1;
76
77 return rc;
78}
79
80int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
81{
82 int rc = 0;
83 struct clk *clk = NULL;
84
85 switch (clktype) {
86 case CAMIO_VFE_MDC_CLK:
87 clk = camio_vfe_mdc_clk;
88 break;
89
90 case CAMIO_MDC_CLK:
91 clk = camio_mdc_clk;
92 break;
93
94 case CAMIO_VFE_CLK:
95 clk = camio_vfe_clk;
96 break;
97
98 case CAMIO_VFE_AXI_CLK:
99 clk = camio_vfe_axi_clk;
100 break;
101
102 default:
103 break;
104 }
105
106 if (!IS_ERR(clk)) {
107 clk_disable(clk);
108 clk_put(clk);
109 } else
110 rc = -1;
111
112 return rc;
113}
114
115void msm_camio_clk_rate_set(int rate)
116{
117 struct clk *clk = camio_vfe_mdc_clk;
118
119 /* TODO: check return */
120 clk_set_rate(clk, rate);
121}
122
123int msm_camio_enable(struct platform_device *pdev)
124{
125 int rc = 0;
126 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
127 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
128
129 camio_ext = camdev->ioext;
130
131 appio = request_mem_region(camio_ext.appphy,
132 camio_ext.appsz, pdev->name);
133 if (!appio) {
134 rc = -EBUSY;
135 goto enable_fail;
136 }
137
138 appbase = ioremap(camio_ext.appphy,
139 camio_ext.appsz);
140 if (!appbase) {
141 rc = -ENOMEM;
142 goto apps_no_mem;
143 }
144
145 mdcio = request_mem_region(camio_ext.mdcphy,
146 camio_ext.mdcsz, pdev->name);
147 if (!mdcio) {
148 rc = -EBUSY;
149 goto mdc_busy;
150 }
151
152 mdcbase = ioremap(camio_ext.mdcphy,
153 camio_ext.mdcsz);
154 if (!mdcbase) {
155 rc = -ENOMEM;
156 goto mdc_no_mem;
157 }
158
159 camdev->camera_gpio_on();
160
161 msm_camio_clk_enable(CAMIO_VFE_CLK);
162 msm_camio_clk_enable(CAMIO_MDC_CLK);
163 msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
164 msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
165 return 0;
166
167mdc_no_mem:
168 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
169mdc_busy:
170 iounmap(appbase);
171apps_no_mem:
172 release_mem_region(camio_ext.appphy, camio_ext.appsz);
173enable_fail:
174 return rc;
175}
176
177void msm_camio_disable(struct platform_device *pdev)
178{
179 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
180 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
181
182 iounmap(mdcbase);
183 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
184 iounmap(appbase);
185 release_mem_region(camio_ext.appphy, camio_ext.appsz);
186
187 camdev->camera_gpio_off();
188
189 msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
190 msm_camio_clk_disable(CAMIO_MDC_CLK);
191 msm_camio_clk_disable(CAMIO_VFE_CLK);
192 msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
193}
194
195void msm_camio_camif_pad_reg_reset(void)
196{
197 uint32_t reg;
198 uint32_t mask, value;
199
200 /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
201 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
202
203 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
204
205 mask = CAM_SEL_BMSK |
206 CAM_PCLK_SRC_SEL_BMSK |
207 CAM_PCLK_INVERT_BMSK |
208 EXT_CAM_HSYNC_POL_SEL_BMSK |
209 EXT_CAM_VSYNC_POL_SEL_BMSK |
210 MDDI_CLK_CHICKEN_BIT_BMSK;
211
212 value = 1 << CAM_SEL_SHFT |
213 3 << CAM_PCLK_SRC_SEL_SHFT |
214 0 << CAM_PCLK_INVERT_SHFT |
215 0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
216 0 << EXT_CAM_VSYNC_POL_SEL_SHFT |
217 0 << MDDI_CLK_CHICKEN_BIT_SHFT;
218 writel((reg & (~mask)) | (value & mask), mdcbase);
219 mdelay(10);
220
221 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
222 mask = CAM_PAD_REG_SW_RESET_BMSK;
223 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
224 writel((reg & (~mask)) | (value & mask), mdcbase);
225 mdelay(10);
226
227 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
228 mask = CAM_PAD_REG_SW_RESET_BMSK;
229 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
230 writel((reg & (~mask)) | (value & mask), mdcbase);
231 mdelay(10);
232
233 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
234
235 mdelay(10);
236
237 /* todo: check return */
238 if (camio_vfe_clk)
239 clk_set_rate(camio_vfe_clk, 96000000);
240}
241
242void msm_camio_vfe_blk_reset(void)
243{
244 uint32_t val;
245
246 val = readl(appbase + 0x00000210);
247 val |= 0x1;
248 writel(val, appbase + 0x00000210);
249 mdelay(10);
250
251 val = readl(appbase + 0x00000210);
252 val &= ~0x1;
253 writel(val, appbase + 0x00000210);
254 mdelay(10);
255}
256
257void msm_camio_camif_pad_reg_reset_2(void)
258{
259 uint32_t reg;
260 uint32_t mask, value;
261
262 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
263 mask = CAM_PAD_REG_SW_RESET_BMSK;
264 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
265 writel((reg & (~mask)) | (value & mask), mdcbase);
266 mdelay(10);
267
268 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
269 mask = CAM_PAD_REG_SW_RESET_BMSK;
270 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
271 writel((reg & (~mask)) | (value & mask), mdcbase);
272 mdelay(10);
273}
274
275void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
276{
277 struct clk *clk = NULL;
278
279 clk = camio_vfe_clk;
280
281 if (clk != NULL) {
282 switch (srctype) {
283 case MSM_CAMIO_CLK_SRC_INTERNAL:
284 clk_set_flags(clk, 0x00000100 << 1);
285 break;
286
287 case MSM_CAMIO_CLK_SRC_EXTERNAL:
288 clk_set_flags(clk, 0x00000100);
289 break;
290
291 default:
292 break;
293 }
294 }
295}
296
297void msm_camio_clk_axi_rate_set(int rate)
298{
299 struct clk *clk = camio_vfe_axi_clk;
300 /* todo: check return */
301 clk_set_rate(clk, rate);
302}
303
304int msm_camio_probe_on(struct platform_device *pdev)
305{
306 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
307 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
308
309 camdev->camera_gpio_on();
310 return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
311}
312
313int msm_camio_probe_off(struct platform_device *pdev)
314{
315 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
316 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
317
318 camdev->camera_gpio_off();
319 return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
320}
diff --git a/drivers/staging/dream/camera/msm_v4l2.c b/drivers/staging/dream/camera/msm_v4l2.c
deleted file mode 100644
index c276f2f7583a..000000000000
--- a/drivers/staging/dream/camera/msm_v4l2.c
+++ /dev/null
@@ -1,798 +0,0 @@
1/*
2 *
3 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
4 *
5 */
6
7#include <linux/workqueue.h>
8#include <linux/delay.h>
9#include <linux/types.h>
10#include <linux/list.h>
11#include <linux/ioctl.h>
12#include <linux/spinlock.h>
13#include <linux/videodev2.h>
14#include <linux/proc_fs.h>
15#include <linux/slab.h>
16#include <media/v4l2-dev.h>
17#include <media/msm_camera.h>
18#include <mach/camera.h>
19#include <media/v4l2-ioctl.h>
20/*#include <linux/platform_device.h>*/
21
22#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \
23 struct v4l2_buffer)
24
25#define MSM_V4L2_GET_PICTURE _IOWR('V', BASE_VIDIOC_PRIVATE+2, \
26 struct v4l2_buffer)
27
28#define MSM_V4L2_DEVICE_NAME "msm_v4l2"
29
30#define MSM_V4L2_PROC_NAME "msm_v4l2"
31
32#define MSM_V4L2_DEVNUM_MPEG2 0
33#define MSM_V4L2_DEVNUM_YUV 20
34
35/* HVGA-P (portrait) and HVGA-L (landscape) */
36#define MSM_V4L2_WIDTH 480
37#define MSM_V4L2_HEIGHT 320
38
39#if 1
40#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args)
41#else
42#define D(fmt, args...) do {} while (0)
43#endif
44
45#define PREVIEW_FRAMES_NUM 4
46
47struct msm_v4l2_device {
48 struct list_head read_queue;
49 struct v4l2_format current_cap_format;
50 struct v4l2_format current_pix_format;
51 struct video_device *pvdev;
52 struct msm_v4l2_driver *drv;
53 uint8_t opencnt;
54
55 spinlock_t read_queue_lock;
56};
57
58static struct msm_v4l2_device *g_pmsm_v4l2_dev;
59
60
61static DEFINE_MUTEX(msm_v4l2_opencnt_lock);
62
63static int msm_v4l2_open(struct file *f)
64{
65 int rc = 0;
66 D("%s\n", __func__);
67 mutex_lock(&msm_v4l2_opencnt_lock);
68 if (!g_pmsm_v4l2_dev->opencnt) {
69 rc = g_pmsm_v4l2_dev->drv->open(
70 g_pmsm_v4l2_dev->drv->sync,
71 MSM_APPS_ID_V4L2);
72 }
73 g_pmsm_v4l2_dev->opencnt++;
74 mutex_unlock(&msm_v4l2_opencnt_lock);
75 return rc;
76}
77
78static int msm_v4l2_release(struct file *f)
79{
80 int rc = 0;
81 D("%s\n", __func__);
82 mutex_lock(&msm_v4l2_opencnt_lock);
83 if (!g_pmsm_v4l2_dev->opencnt) {
84 g_pmsm_v4l2_dev->opencnt--;
85 if (!g_pmsm_v4l2_dev->opencnt) {
86 rc = g_pmsm_v4l2_dev->drv->release(
87 g_pmsm_v4l2_dev->drv->sync);
88 }
89 }
90 mutex_unlock(&msm_v4l2_opencnt_lock);
91 return rc;
92}
93
94static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w)
95{
96 return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w);
97}
98
99static long msm_v4l2_ioctl(struct file *filep,
100 unsigned int cmd, unsigned long arg)
101{
102 struct msm_ctrl_cmd *ctrlcmd;
103
104 D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__);
105
106 switch (cmd) {
107 case MSM_V4L2_START_SNAPSHOT:
108
109 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
110 if (!ctrlcmd) {
111 CDBG("msm_v4l2_ioctl: cannot allocate buffer\n");
112 return -ENOMEM;
113 }
114
115 ctrlcmd->length = 0;
116 ctrlcmd->value = NULL;
117 ctrlcmd->timeout_ms = 10000;
118
119 D("msm_v4l2_ioctl, MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n",
120 cmd);
121 ctrlcmd->type = MSM_V4L2_SNAPSHOT;
122 return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync,
123 ctrlcmd);
124
125 case MSM_V4L2_GET_PICTURE:
126 D("msm_v4l2_ioctl, MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd);
127 ctrlcmd = (struct msm_ctrl_cmd *)arg;
128 return g_pmsm_v4l2_dev->drv->get_pict(
129 g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
130
131 default:
132 D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd);
133 return video_ioctl2(filep, cmd, arg);
134 }
135}
136
137static void msm_v4l2_release_dev(struct video_device *d)
138{
139 D("%s\n", __func__);
140}
141
142static int msm_v4l2_querycap(struct file *f,
143 void *pctx, struct v4l2_capability *pcaps)
144{
145 D("%s\n", __func__);
146 strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver));
147 strncpy(pcaps->card,
148 MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card));
149 pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
150 return 0;
151}
152
153static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm)
154{
155 D("%s\n", __func__);
156 return 0;
157}
158
159static int msm_v4l2_queryctrl(struct file *f,
160 void *pctx, struct v4l2_queryctrl *pqctrl)
161{
162 int rc = 0;
163 struct msm_ctrl_cmd *ctrlcmd;
164
165 D("%s\n", __func__);
166
167 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
168 if (!ctrlcmd) {
169 CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n");
170 return -ENOMEM;
171 }
172
173 ctrlcmd->type = MSM_V4L2_QUERY_CTRL;
174 ctrlcmd->length = sizeof(struct v4l2_queryctrl);
175 ctrlcmd->value = pqctrl;
176 ctrlcmd->timeout_ms = 10000;
177
178 rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
179 if (rc < 0)
180 return -1;
181
182 return ctrlcmd->status;
183}
184
185static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
186{
187 int rc = 0;
188 struct msm_ctrl_cmd *ctrlcmd;
189
190 D("%s\n", __func__);
191
192 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
193 if (!ctrlcmd) {
194 CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n");
195 return -ENOMEM;
196 }
197
198 ctrlcmd->type = MSM_V4L2_GET_CTRL;
199 ctrlcmd->length = sizeof(struct v4l2_control);
200 ctrlcmd->value = c;
201 ctrlcmd->timeout_ms = 10000;
202
203 rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
204 if (rc < 0)
205 return -1;
206
207 return ctrlcmd->status;
208}
209
210static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
211{
212 int rc = 0;
213 struct msm_ctrl_cmd *ctrlcmd;
214
215 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
216 if (!ctrlcmd) {
217 CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n");
218 return -ENOMEM;
219 }
220
221 ctrlcmd->type = MSM_V4L2_SET_CTRL;
222 ctrlcmd->length = sizeof(struct v4l2_control);
223 ctrlcmd->value = c;
224 ctrlcmd->timeout_ms = 10000;
225
226 D("%s\n", __func__);
227
228 rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
229 if (rc < 0)
230 return -1;
231
232 return ctrlcmd->status;
233}
234
235static int msm_v4l2_reqbufs(struct file *f,
236 void *pctx, struct v4l2_requestbuffers *b)
237{
238 D("%s\n", __func__);
239 return 0;
240}
241
242static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
243{
244 struct msm_pmem_info pmem_buf;
245#if 0
246 __u32 width = 0;
247 __u32 height = 0;
248 __u32 y_size = 0;
249 __u32 y_pad = 0;
250
251 /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */
252 width = 640;
253 /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */
254 height = 480;
255
256 D("%s: width = %d, height = %d\n", __func__, width, height);
257
258 y_size = width * height;
259 y_pad = y_size % 4;
260#endif
261
262 __u32 y_pad = pb->bytesused % 4;
263
264 /* V4L2 videodev will do the copy_from_user. */
265
266 memset(&pmem_buf, 0, sizeof(struct msm_pmem_info));
267 pmem_buf.type = MSM_PMEM_OUTPUT2;
268 pmem_buf.vaddr = (void *)pb->m.userptr;
269 pmem_buf.y_off = 0;
270 pmem_buf.fd = (int)pb->reserved;
271 /* pmem_buf.cbcr_off = (y_size + y_pad); */
272 pmem_buf.cbcr_off = (pb->bytesused + y_pad);
273
274 g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf);
275
276 return 0;
277}
278
279static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
280{
281 /*
282 __u32 y_size = 0;
283 __u32 y_pad = 0;
284 __u32 width = 0;
285 __u32 height = 0;
286 */
287
288 __u32 y_pad = 0;
289
290 struct msm_pmem_info meminfo;
291 struct msm_frame frame;
292 static int cnt;
293
294 if ((pb->flags >> 16) & 0x0001) {
295 /* this is for previwe */
296#if 0
297 width = 640;
298 height = 480;
299
300 /* V4L2 videodev will do the copy_from_user. */
301 D("%s: width = %d, height = %d\n", __func__, width, height);
302 y_size = width * height;
303 y_pad = y_size % 4;
304#endif
305
306 y_pad = pb->bytesused % 4;
307
308 if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
309 /* this qbuf is actually for releasing */
310
311 frame.buffer = pb->m.userptr;
312 frame.y_off = 0;
313 /* frame.cbcr_off = (y_size + y_pad); */
314 frame.cbcr_off = (pb->bytesused + y_pad);
315 frame.fd = pb->reserved;
316
317 D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n",
318 pb->bytesused);
319
320 g_pmsm_v4l2_dev->drv->put_frame(
321 g_pmsm_v4l2_dev->drv->sync,
322 &frame);
323
324 return 0;
325 }
326
327 D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n",
328 pb->bytesused);
329
330 meminfo.type = MSM_PMEM_OUTPUT2;
331 meminfo.fd = (int)pb->reserved;
332 meminfo.vaddr = (void *)pb->m.userptr;
333 meminfo.y_off = 0;
334 /* meminfo.cbcr_off = (y_size + y_pad); */
335 meminfo.cbcr_off = (pb->bytesused + y_pad);
336 if (cnt == PREVIEW_FRAMES_NUM - 1)
337 meminfo.active = 0;
338 else
339 meminfo.active = 1;
340 cnt++;
341 g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
342 &meminfo);
343 } else if ((pb->flags) & 0x0001) {
344 /* this is for snapshot */
345
346 __u32 y_size = 0;
347
348 if ((pb->flags >> 8) & 0x01) {
349
350 y_size = pb->bytesused;
351
352 meminfo.type = MSM_PMEM_THUMBAIL;
353 } else if ((pb->flags >> 9) & 0x01) {
354
355 y_size = pb->bytesused;
356
357 meminfo.type = MSM_PMEM_MAINIMG;
358 }
359
360 y_pad = y_size % 4;
361
362 meminfo.fd = (int)pb->reserved;
363 meminfo.vaddr = (void *)pb->m.userptr;
364 meminfo.y_off = 0;
365 /* meminfo.cbcr_off = (y_size + y_pad); */
366 meminfo.cbcr_off = (y_size + y_pad);
367 meminfo.active = 1;
368 g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
369 &meminfo);
370 }
371
372 return 0;
373}
374
375static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
376{
377 struct msm_frame frame;
378 D("%s\n", __func__);
379
380 /* V4L2 videodev will do the copy_to_user. */
381 if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
382
383 D("%s, %d\n", __func__, __LINE__);
384
385 g_pmsm_v4l2_dev->drv->get_frame(
386 g_pmsm_v4l2_dev->drv->sync,
387 &frame);
388
389 pb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
390 pb->m.userptr = (unsigned long)frame.buffer; /* FIXME */
391 pb->reserved = (int)frame.fd;
392 /* pb->length = (int)frame.cbcr_off; */
393
394 pb->bytesused = frame.cbcr_off;
395
396 } else if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
397 __u32 y_pad = pb->bytesused % 4;
398
399 frame.buffer = pb->m.userptr;
400 frame.y_off = 0;
401 /* frame.cbcr_off = (y_size + y_pad); */
402 frame.cbcr_off = (pb->bytesused + y_pad);
403 frame.fd = pb->reserved;
404
405 g_pmsm_v4l2_dev->drv->put_frame(
406 g_pmsm_v4l2_dev->drv->sync,
407 &frame);
408 }
409
410 return 0;
411}
412
413static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i)
414{
415 struct msm_ctrl_cmd *ctrlcmd;
416
417 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
418 if (!ctrlcmd) {
419 CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
420 return -ENOMEM;
421 }
422
423 ctrlcmd->type = MSM_V4L2_STREAM_ON;
424 ctrlcmd->timeout_ms = 10000;
425 ctrlcmd->length = 0;
426 ctrlcmd->value = NULL;
427
428 D("%s\n", __func__);
429
430 g_pmsm_v4l2_dev->drv->ctrl(
431 g_pmsm_v4l2_dev->drv->sync,
432 ctrlcmd);
433
434 D("%s after drv->ctrl \n", __func__);
435
436 return 0;
437}
438
439static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i)
440{
441 struct msm_ctrl_cmd *ctrlcmd;
442
443 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
444 if (!ctrlcmd) {
445 CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
446 return -ENOMEM;
447 }
448
449 ctrlcmd->type = MSM_V4L2_STREAM_OFF;
450 ctrlcmd->timeout_ms = 10000;
451 ctrlcmd->length = 0;
452 ctrlcmd->value = NULL;
453
454
455 D("%s\n", __func__);
456
457 g_pmsm_v4l2_dev->drv->ctrl(
458 g_pmsm_v4l2_dev->drv->sync,
459 ctrlcmd);
460
461 return 0;
462}
463
464static int msm_v4l2_enum_fmt_overlay(struct file *f,
465 void *pctx, struct v4l2_fmtdesc *pfmtdesc)
466{
467 D("%s\n", __func__);
468 return 0;
469}
470
471static int msm_v4l2_enum_fmt_cap(struct file *f,
472 void *pctx, struct v4l2_fmtdesc *pfmtdesc)
473{
474 D("%s\n", __func__);
475
476 switch (pfmtdesc->index) {
477 case 0:
478 pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
479 pfmtdesc->flags = 0;
480 strncpy(pfmtdesc->description, "YUV 4:2:0",
481 sizeof(pfmtdesc->description));
482 pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420;
483 break;
484 default:
485 return -EINVAL;
486 }
487
488 return 0;
489}
490
491static int msm_v4l2_g_fmt_cap(struct file *f,
492 void *pctx, struct v4l2_format *pfmt)
493{
494 D("%s\n", __func__);
495 pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
496 pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
497 pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
498 pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
499 pfmt->fmt.pix.field = V4L2_FIELD_ANY;
500 pfmt->fmt.pix.bytesperline = 0;
501 pfmt->fmt.pix.sizeimage = 0;
502 pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
503 pfmt->fmt.pix.priv = 0;
504 return 0;
505}
506
507static int msm_v4l2_s_fmt_cap(struct file *f,
508 void *pctx, struct v4l2_format *pfmt)
509{
510 struct msm_ctrl_cmd *ctrlcmd;
511
512 D("%s\n", __func__);
513
514 ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
515 if (!ctrlcmd) {
516 CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
517 return -ENOMEM;
518 }
519
520 ctrlcmd->type = MSM_V4L2_VID_CAP_TYPE;
521 ctrlcmd->length = sizeof(struct v4l2_format);
522 ctrlcmd->value = pfmt;
523 ctrlcmd->timeout_ms = 10000;
524
525 if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
526 kfree(ctrlcmd);
527 return -1;
528 }
529
530#if 0
531 /* FIXEME */
532 if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) {
533 kfree(ctrlcmd);
534 return -EINVAL;
535 }
536#endif
537
538 /* Ok, but check other params, too. */
539
540#if 0
541 memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt,
542 sizeof(struct v4l2_format));
543#endif
544
545 g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
546
547 return 0;
548}
549
550static int msm_v4l2_g_fmt_overlay(struct file *f,
551 void *pctx, struct v4l2_format *pfmt)
552{
553 D("%s\n", __func__);
554 pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
555 pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
556 pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
557 pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
558 pfmt->fmt.pix.field = V4L2_FIELD_ANY;
559 pfmt->fmt.pix.bytesperline = 0;
560 pfmt->fmt.pix.sizeimage = 0;
561 pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
562 pfmt->fmt.pix.priv = 0;
563 return 0;
564}
565
566static int msm_v4l2_s_fmt_overlay(struct file *f,
567 void *pctx, struct v4l2_format *pfmt)
568{
569 D("%s\n", __func__);
570 return 0;
571}
572
573static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i)
574{
575 D("%s\n", __func__);
576 return 0;
577}
578
579static int msm_v4l2_g_jpegcomp(struct file *f,
580 void *pctx, struct v4l2_jpegcompression *pcomp)
581{
582 D("%s\n", __func__);
583 return 0;
584}
585
586static int msm_v4l2_s_jpegcomp(struct file *f,
587 void *pctx, struct v4l2_jpegcompression *pcomp)
588{
589 D("%s\n", __func__);
590 return 0;
591}
592
593#ifdef CONFIG_PROC_FS
594int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset,
595 int count, int *eof, void *data)
596{
597 int len = 0;
598 len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n");
599
600 if (g_pmsm_v4l2_dev) {
601 len += snprintf(pbuf, strlen("mode: ") + 1, "mode: ");
602
603 if (g_pmsm_v4l2_dev->current_cap_format.type
604 == V4L2_BUF_TYPE_VIDEO_CAPTURE)
605 len += snprintf(pbuf, strlen("capture\n") + 1,
606 "capture\n");
607 else
608 len += snprintf(pbuf, strlen("unknown\n") + 1,
609 "unknown\n");
610
611 len += snprintf(pbuf, 21, "resolution: %dx%d\n",
612 g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
613 width,
614 g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
615 height);
616
617 len += snprintf(pbuf,
618 strlen("pixel format: ") + 1, "pixel format: ");
619 if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat
620 == V4L2_PIX_FMT_YVU420)
621 len += snprintf(pbuf, strlen("yvu420\n") + 1,
622 "yvu420\n");
623 else
624 len += snprintf(pbuf, strlen("unknown\n") + 1,
625 "unknown\n");
626
627 len += snprintf(pbuf, strlen("colorspace: ") + 1,
628 "colorspace: ");
629 if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace
630 == V4L2_COLORSPACE_JPEG)
631 len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n");
632 else
633 len += snprintf(pbuf, strlen("unknown\n") + 1,
634 "unknown\n");
635 }
636
637 *eof = 1;
638 return len;
639}
640#endif
641
642static const struct v4l2_file_operations msm_v4l2_fops = {
643 .owner = THIS_MODULE,
644 .open = msm_v4l2_open,
645 .poll = msm_v4l2_poll,
646 .release = msm_v4l2_release,
647 .ioctl = msm_v4l2_ioctl,
648};
649
650static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev)
651{
652 pmsm_v4l2_dev->read_queue_lock =
653 __SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock);
654 INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue);
655}
656
657static int msm_v4l2_try_fmt_cap(struct file *file,
658 void *fh, struct v4l2_format *f)
659{
660 /* FIXME */
661 return 0;
662}
663
664static int mm_v4l2_try_fmt_type_private(struct file *file,
665 void *fh, struct v4l2_format *f)
666{
667 /* FIXME */
668 return 0;
669}
670
671/*
672 * should the following structure be used instead of the code in the function?
673 * static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
674 * .vidioc_querycap = ....
675 * }
676 */
677static const struct v4l2_ioctl_ops msm_ioctl_ops = {
678 .vidioc_querycap = msm_v4l2_querycap,
679 .vidioc_s_std = msm_v4l2_s_std,
680
681 .vidioc_queryctrl = msm_v4l2_queryctrl,
682 .vidioc_g_ctrl = msm_v4l2_g_ctrl,
683 .vidioc_s_ctrl = msm_v4l2_s_ctrl,
684
685 .vidioc_reqbufs = msm_v4l2_reqbufs,
686 .vidioc_querybuf = msm_v4l2_querybuf,
687 .vidioc_qbuf = msm_v4l2_qbuf,
688 .vidioc_dqbuf = msm_v4l2_dqbuf,
689
690 .vidioc_streamon = msm_v4l2_streamon,
691 .vidioc_streamoff = msm_v4l2_streamoff,
692
693 .vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay,
694 .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap,
695
696 .vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap,
697 .vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private,
698
699 .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap,
700 .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap,
701 .vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay,
702 .vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay,
703 .vidioc_overlay = msm_v4l2_overlay,
704
705 .vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp,
706 .vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp,
707};
708
709static int msm_v4l2_video_dev_init(struct video_device *pvd)
710{
711 strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name));
712 pvd->vfl_type = 1;
713 pvd->fops = &msm_v4l2_fops;
714 pvd->release = msm_v4l2_release_dev;
715 pvd->minor = -1;
716 pvd->ioctl_ops = &msm_ioctl_ops;
717 return msm_v4l2_register(g_pmsm_v4l2_dev->drv);
718}
719
720static int __init msm_v4l2_init(void)
721{
722 int rc = -ENOMEM;
723 struct video_device *pvdev = NULL;
724 struct msm_v4l2_device *pmsm_v4l2_dev = NULL;
725 D("%s\n", __func__);
726
727 pvdev = video_device_alloc();
728 if (pvdev == NULL)
729 return rc;
730
731 pmsm_v4l2_dev =
732 kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL);
733 if (pmsm_v4l2_dev == NULL) {
734 video_device_release(pvdev);
735 return rc;
736 }
737
738 msm_v4l2_dev_init(pmsm_v4l2_dev);
739
740 g_pmsm_v4l2_dev = pmsm_v4l2_dev;
741 g_pmsm_v4l2_dev->pvdev = pvdev;
742
743 g_pmsm_v4l2_dev->drv =
744 kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL);
745 if (!g_pmsm_v4l2_dev->drv) {
746 video_device_release(pvdev);
747 kfree(pmsm_v4l2_dev);
748 return rc;
749 }
750
751 rc = msm_v4l2_video_dev_init(pvdev);
752 if (rc < 0) {
753 video_device_release(pvdev);
754 kfree(g_pmsm_v4l2_dev->drv);
755 kfree(pmsm_v4l2_dev);
756 return rc;
757 }
758
759 if (video_register_device(pvdev, VFL_TYPE_GRABBER,
760 MSM_V4L2_DEVNUM_YUV)) {
761 D("failed to register device\n");
762 video_device_release(pvdev);
763 kfree(g_pmsm_v4l2_dev);
764 g_pmsm_v4l2_dev = NULL;
765 return -ENOENT;
766 }
767#ifdef CONFIG_PROC_FS
768 create_proc_read_entry(MSM_V4L2_PROC_NAME,
769 0, NULL, msm_v4l2_read_proc, NULL);
770#endif
771
772 return 0;
773}
774
775static void __exit msm_v4l2_exit(void)
776{
777 struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev;
778 D("%s\n", __func__);
779#ifdef CONFIG_PROC_FS
780 remove_proc_entry(MSM_V4L2_PROC_NAME, NULL);
781#endif
782 video_unregister_device(pvdev);
783 video_device_release(pvdev);
784
785 msm_v4l2_unregister(g_pmsm_v4l2_dev->drv);
786
787 kfree(g_pmsm_v4l2_dev->drv);
788 g_pmsm_v4l2_dev->drv = NULL;
789
790 kfree(g_pmsm_v4l2_dev);
791 g_pmsm_v4l2_dev = NULL;
792}
793
794module_init(msm_v4l2_init);
795module_exit(msm_v4l2_exit);
796
797MODULE_DESCRIPTION("MSM V4L2 driver");
798MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
deleted file mode 100644
index 198656ac3de5..000000000000
--- a/drivers/staging/dream/camera/msm_vfe7x.c
+++ /dev/null
@@ -1,702 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/msm_adsp.h>
6#include <linux/uaccess.h>
7#include <linux/fs.h>
8#include <linux/sched.h>
9#include <linux/android_pmem.h>
10#include <linux/slab.h>
11#include <mach/msm_adsp.h>
12#include <linux/delay.h>
13#include <linux/wait.h>
14#include "msm_vfe7x.h"
15
16#define QDSP_CMDQUEUE QDSP_vfeCommandQueue
17
18#define VFE_RESET_CMD 0
19#define VFE_START_CMD 1
20#define VFE_STOP_CMD 2
21#define VFE_FRAME_ACK 20
22#define STATS_AF_ACK 21
23#define STATS_WE_ACK 22
24
25#define MSG_STOP_ACK 1
26#define MSG_SNAPSHOT 2
27#define MSG_OUTPUT1 6
28#define MSG_OUTPUT2 7
29#define MSG_STATS_AF 8
30#define MSG_STATS_WE 9
31
32static struct msm_adsp_module *qcam_mod;
33static struct msm_adsp_module *vfe_mod;
34static struct msm_vfe_callback *resp;
35static void *extdata;
36static uint32_t extlen;
37
38struct mutex vfe_lock;
39static void *vfe_syncdata;
40static uint8_t vfestopped;
41
42static struct stop_event stopevent;
43
44static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
45 enum vfe_resp_msg type,
46 void *data, void **ext, int32_t *elen)
47{
48 switch (type) {
49 case VFE_MSG_OUTPUT1:
50 case VFE_MSG_OUTPUT2: {
51 pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
52 pinfo->cbcr_phy =
53 ((struct vfe_endframe *)data)->cbcr_address;
54
55 CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
56 pinfo->y_phy, pinfo->cbcr_phy);
57
58 ((struct vfe_frame_extra *)extdata)->bl_evencol =
59 ((struct vfe_endframe *)data)->blacklevelevencolumn;
60
61 ((struct vfe_frame_extra *)extdata)->bl_oddcol =
62 ((struct vfe_endframe *)data)->blackleveloddcolumn;
63
64 ((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
65 ((struct vfe_endframe *)data)->greendefectpixelcount;
66
67 ((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
68 ((struct vfe_endframe *)data)->redbluedefectpixelcount;
69
70 *ext = extdata;
71 *elen = extlen;
72 }
73 break;
74
75 case VFE_MSG_STATS_AF:
76 case VFE_MSG_STATS_WE:
77 pinfo->sbuf_phy = *(uint32_t *)data;
78 break;
79
80 default:
81 break;
82 } /* switch */
83}
84
85static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
86 void (*getevent)(void *ptr, size_t len))
87{
88 uint32_t evt_buf[3];
89 struct msm_vfe_resp *rp;
90 void *data;
91
92 len = (id == (uint16_t)-1) ? 0 : len;
93 data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata);
94
95 if (!data) {
96 pr_err("rp: cannot allocate buffer\n");
97 return;
98 }
99 rp = (struct msm_vfe_resp *)data;
100 rp->evt_msg.len = len;
101
102 if (id == ((uint16_t)-1)) {
103 /* event */
104 rp->type = VFE_EVENT;
105 rp->evt_msg.type = MSM_CAMERA_EVT;
106 getevent(evt_buf, sizeof(evt_buf));
107 rp->evt_msg.msg_id = evt_buf[0];
108 resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata);
109 } else {
110 /* messages */
111 rp->evt_msg.type = MSM_CAMERA_MSG;
112 rp->evt_msg.msg_id = id;
113 rp->evt_msg.data = rp + 1;
114 getevent(rp->evt_msg.data, len);
115
116 switch (rp->evt_msg.msg_id) {
117 case MSG_SNAPSHOT:
118 rp->type = VFE_MSG_SNAPSHOT;
119 break;
120
121 case MSG_OUTPUT1:
122 rp->type = VFE_MSG_OUTPUT1;
123 vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1,
124 rp->evt_msg.data, &(rp->extdata),
125 &(rp->extlen));
126 break;
127
128 case MSG_OUTPUT2:
129 rp->type = VFE_MSG_OUTPUT2;
130 vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2,
131 rp->evt_msg.data, &(rp->extdata),
132 &(rp->extlen));
133 break;
134
135 case MSG_STATS_AF:
136 rp->type = VFE_MSG_STATS_AF;
137 vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
138 rp->evt_msg.data, NULL, NULL);
139 break;
140
141 case MSG_STATS_WE:
142 rp->type = VFE_MSG_STATS_WE;
143 vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
144 rp->evt_msg.data, NULL, NULL);
145
146 CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
147 break;
148
149 case MSG_STOP_ACK:
150 rp->type = VFE_MSG_GENERAL;
151 stopevent.state = 1;
152 wake_up(&stopevent.wait);
153 break;
154
155
156 default:
157 rp->type = VFE_MSG_GENERAL;
158 break;
159 }
160 resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata);
161 }
162}
163
164static struct msm_adsp_ops vfe_7x_sync = {
165 .event = vfe_7x_ops,
166};
167
168static int vfe_7x_enable(struct camera_enable_cmd *enable)
169{
170 int rc = -EFAULT;
171
172 if (!strcmp(enable->name, "QCAMTASK"))
173 rc = msm_adsp_enable(qcam_mod);
174 else if (!strcmp(enable->name, "VFETASK"))
175 rc = msm_adsp_enable(vfe_mod);
176
177 return rc;
178}
179
180static int vfe_7x_disable(struct camera_enable_cmd *enable,
181 struct platform_device *dev __attribute__((unused)))
182{
183 int rc = -EFAULT;
184
185 if (!strcmp(enable->name, "QCAMTASK"))
186 rc = msm_adsp_disable(qcam_mod);
187 else if (!strcmp(enable->name, "VFETASK"))
188 rc = msm_adsp_disable(vfe_mod);
189
190 return rc;
191}
192
193static int vfe_7x_stop(void)
194{
195 int rc = 0;
196 uint32_t stopcmd = VFE_STOP_CMD;
197 rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
198 &stopcmd, sizeof(uint32_t));
199 if (rc < 0) {
200 CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
201 return rc;
202 }
203
204 stopevent.state = 0;
205 rc = wait_event_timeout(stopevent.wait,
206 stopevent.state != 0,
207 msecs_to_jiffies(stopevent.timeout));
208
209 return rc;
210}
211
212static void vfe_7x_release(struct platform_device *pdev)
213{
214 mutex_lock(&vfe_lock);
215 vfe_syncdata = NULL;
216 mutex_unlock(&vfe_lock);
217
218 if (!vfestopped) {
219 CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
220 vfe_7x_stop();
221 } else
222 vfestopped = 0;
223
224 msm_adsp_disable(qcam_mod);
225 msm_adsp_disable(vfe_mod);
226
227 msm_adsp_put(qcam_mod);
228 msm_adsp_put(vfe_mod);
229
230 msm_camio_disable(pdev);
231
232 kfree(extdata);
233 extlen = 0;
234}
235
236static int vfe_7x_init(struct msm_vfe_callback *presp,
237 struct platform_device *dev)
238{
239 int rc = 0;
240
241 init_waitqueue_head(&stopevent.wait);
242 stopevent.timeout = 200;
243 stopevent.state = 0;
244
245 if (presp && presp->vfe_resp)
246 resp = presp;
247 else
248 return -EFAULT;
249
250 /* Bring up all the required GPIOs and Clocks */
251 rc = msm_camio_enable(dev);
252 if (rc < 0)
253 return rc;
254
255 msm_camio_camif_pad_reg_reset();
256
257 extlen = sizeof(struct vfe_frame_extra);
258
259 extdata = kmalloc(extlen, GFP_ATOMIC);
260 if (!extdata) {
261 rc = -ENOMEM;
262 goto init_fail;
263 }
264
265 rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
266 if (rc) {
267 rc = -EBUSY;
268 goto get_qcam_fail;
269 }
270
271 rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
272 if (rc) {
273 rc = -EBUSY;
274 goto get_vfe_fail;
275 }
276
277 return 0;
278
279get_vfe_fail:
280 msm_adsp_put(qcam_mod);
281get_qcam_fail:
282 kfree(extdata);
283init_fail:
284 extlen = 0;
285 return rc;
286}
287
288static int vfe_7x_config_axi(int mode,
289 struct axidata *ad, struct axiout *ao)
290{
291 struct msm_pmem_region *regptr;
292 unsigned long *bptr;
293 int cnt;
294
295 int rc = 0;
296
297 if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
298 regptr = ad->region;
299
300 CDBG("bufnum1 = %d\n", ad->bufnum1);
301 CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
302 regptr->paddr, regptr->y_off, regptr->cbcr_off);
303
304 bptr = &ao->output1buffer1_y_phy;
305 for (cnt = 0; cnt < ad->bufnum1; cnt++) {
306 *bptr = regptr->paddr + regptr->y_off;
307 bptr++;
308 *bptr = regptr->paddr + regptr->cbcr_off;
309
310 bptr++;
311 regptr++;
312 }
313
314 regptr--;
315 for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
316 *bptr = regptr->paddr + regptr->y_off;
317 bptr++;
318 *bptr = regptr->paddr + regptr->cbcr_off;
319 bptr++;
320 }
321 } /* if OUTPUT1 or Both */
322
323 if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
324 regptr = &(ad->region[ad->bufnum1]);
325
326 CDBG("bufnum2 = %d\n", ad->bufnum2);
327 CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
328 regptr->paddr, regptr->y_off, regptr->cbcr_off);
329
330 bptr = &ao->output2buffer1_y_phy;
331 for (cnt = 0; cnt < ad->bufnum2; cnt++) {
332 *bptr = regptr->paddr + regptr->y_off;
333 bptr++;
334 *bptr = regptr->paddr + regptr->cbcr_off;
335
336 bptr++;
337 regptr++;
338 }
339
340 regptr--;
341 for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
342 *bptr = regptr->paddr + regptr->y_off;
343 bptr++;
344 *bptr = regptr->paddr + regptr->cbcr_off;
345 bptr++;
346 }
347 }
348
349 return rc;
350}
351
352static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
353{
354 struct msm_pmem_region *regptr;
355 unsigned char buf[256];
356
357 struct vfe_stats_ack sack;
358 struct axidata *axid;
359 uint32_t i;
360
361 struct vfe_stats_we_cfg *scfg = NULL;
362 struct vfe_stats_af_cfg *sfcfg = NULL;
363
364 struct axiout *axio = NULL;
365 void *cmd_data = NULL;
366 void *cmd_data_alloc = NULL;
367 long rc = 0;
368 struct msm_vfe_command_7k *vfecmd;
369
370 vfecmd =
371 kmalloc(sizeof(struct msm_vfe_command_7k),
372 GFP_ATOMIC);
373 if (!vfecmd) {
374 pr_err("vfecmd alloc failed!\n");
375 return -ENOMEM;
376 }
377
378 if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
379 cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
380 cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
381 if (copy_from_user(vfecmd,
382 (void __user *)(cmd->value),
383 sizeof(struct msm_vfe_command_7k))) {
384 rc = -EFAULT;
385 goto config_failure;
386 }
387 }
388
389 switch (cmd->cmd_type) {
390 case CMD_STATS_ENABLE:
391 case CMD_STATS_AXI_CFG: {
392 axid = data;
393 if (!axid) {
394 rc = -EFAULT;
395 goto config_failure;
396 }
397
398 scfg =
399 kmalloc(sizeof(struct vfe_stats_we_cfg),
400 GFP_ATOMIC);
401 if (!scfg) {
402 rc = -ENOMEM;
403 goto config_failure;
404 }
405
406 if (copy_from_user(scfg,
407 (void __user *)(vfecmd->value),
408 vfecmd->length)) {
409
410 rc = -EFAULT;
411 goto config_done;
412 }
413
414 CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
415 axid->bufnum1, scfg->wb_expstatsenable);
416
417 if (axid->bufnum1 > 0) {
418 regptr = axid->region;
419
420 for (i = 0; i < axid->bufnum1; i++) {
421
422 CDBG("STATS_ENABLE, phy = 0x%lx\n",
423 regptr->paddr);
424
425 scfg->wb_expstatoutputbuffer[i] =
426 (void *)regptr->paddr;
427 regptr++;
428 }
429
430 cmd_data = scfg;
431
432 } else {
433 rc = -EINVAL;
434 goto config_done;
435 }
436 }
437 break;
438
439 case CMD_STATS_AF_ENABLE:
440 case CMD_STATS_AF_AXI_CFG: {
441 axid = data;
442 if (!axid) {
443 rc = -EFAULT;
444 goto config_failure;
445 }
446
447 sfcfg =
448 kmalloc(sizeof(struct vfe_stats_af_cfg),
449 GFP_ATOMIC);
450
451 if (!sfcfg) {
452 rc = -ENOMEM;
453 goto config_failure;
454 }
455
456 if (copy_from_user(sfcfg,
457 (void __user *)(vfecmd->value),
458 vfecmd->length)) {
459
460 rc = -EFAULT;
461 goto config_done;
462 }
463
464 CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
465 axid->bufnum1, sfcfg->af_enable);
466
467 if (axid->bufnum1 > 0) {
468 regptr = axid->region;
469
470 for (i = 0; i < axid->bufnum1; i++) {
471
472 CDBG("STATS_ENABLE, phy = 0x%lx\n",
473 regptr->paddr);
474
475 sfcfg->af_outbuf[i] =
476 (void *)regptr->paddr;
477
478 regptr++;
479 }
480
481 cmd_data = sfcfg;
482
483 } else {
484 rc = -EINVAL;
485 goto config_done;
486 }
487 }
488 break;
489
490 case CMD_FRAME_BUF_RELEASE: {
491 struct msm_frame *b;
492 unsigned long p;
493 struct vfe_outputack fack;
494 if (!data) {
495 rc = -EFAULT;
496 goto config_failure;
497 }
498
499 b = (struct msm_frame *)(cmd->value);
500 p = *(unsigned long *)data;
501
502 fack.header = VFE_FRAME_ACK;
503
504 fack.output2newybufferaddress =
505 (void *)(p + b->y_off);
506
507 fack.output2newcbcrbufferaddress =
508 (void *)(p + b->cbcr_off);
509
510 vfecmd->queue = QDSP_CMDQUEUE;
511 vfecmd->length = sizeof(struct vfe_outputack);
512 cmd_data = &fack;
513 }
514 break;
515
516 case CMD_SNAP_BUF_RELEASE:
517 break;
518
519 case CMD_STATS_BUF_RELEASE: {
520 CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
521 if (!data) {
522 rc = -EFAULT;
523 goto config_failure;
524 }
525
526 sack.header = STATS_WE_ACK;
527 sack.bufaddr = (void *)*(uint32_t *)data;
528
529 vfecmd->queue = QDSP_CMDQUEUE;
530 vfecmd->length = sizeof(struct vfe_stats_ack);
531 cmd_data = &sack;
532 }
533 break;
534
535 case CMD_STATS_AF_BUF_RELEASE: {
536 CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
537 if (!data) {
538 rc = -EFAULT;
539 goto config_failure;
540 }
541
542 sack.header = STATS_AF_ACK;
543 sack.bufaddr = (void *)*(uint32_t *)data;
544
545 vfecmd->queue = QDSP_CMDQUEUE;
546 vfecmd->length = sizeof(struct vfe_stats_ack);
547 cmd_data = &sack;
548 }
549 break;
550
551 case CMD_GENERAL:
552 case CMD_STATS_DISABLE: {
553 if (vfecmd->length > 256) {
554 cmd_data_alloc =
555 cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
556 if (!cmd_data) {
557 rc = -ENOMEM;
558 goto config_failure;
559 }
560 } else
561 cmd_data = buf;
562
563 if (copy_from_user(cmd_data,
564 (void __user *)(vfecmd->value),
565 vfecmd->length)) {
566
567 rc = -EFAULT;
568 goto config_done;
569 }
570
571 if (vfecmd->queue == QDSP_CMDQUEUE) {
572 switch (*(uint32_t *)cmd_data) {
573 case VFE_RESET_CMD:
574 msm_camio_vfe_blk_reset();
575 msm_camio_camif_pad_reg_reset_2();
576 vfestopped = 0;
577 break;
578
579 case VFE_START_CMD:
580 msm_camio_camif_pad_reg_reset_2();
581 vfestopped = 0;
582 break;
583
584 case VFE_STOP_CMD:
585 vfestopped = 1;
586 goto config_send;
587
588 default:
589 break;
590 }
591 } /* QDSP_CMDQUEUE */
592 }
593 break;
594
595 case CMD_AXI_CFG_OUT1: {
596 axid = data;
597 if (!axid) {
598 rc = -EFAULT;
599 goto config_failure;
600 }
601
602 axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
603 if (!axio) {
604 rc = -ENOMEM;
605 goto config_failure;
606 }
607
608 if (copy_from_user(axio, (void *)(vfecmd->value),
609 sizeof(struct axiout))) {
610 rc = -EFAULT;
611 goto config_done;
612 }
613
614 vfe_7x_config_axi(OUTPUT_1, axid, axio);
615
616 cmd_data = axio;
617 }
618 break;
619
620 case CMD_AXI_CFG_OUT2:
621 case CMD_RAW_PICT_AXI_CFG: {
622 axid = data;
623 if (!axid) {
624 rc = -EFAULT;
625 goto config_failure;
626 }
627
628 axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
629 if (!axio) {
630 rc = -ENOMEM;
631 goto config_failure;
632 }
633
634 if (copy_from_user(axio, (void __user *)(vfecmd->value),
635 sizeof(struct axiout))) {
636 rc = -EFAULT;
637 goto config_done;
638 }
639
640 vfe_7x_config_axi(OUTPUT_2, axid, axio);
641 cmd_data = axio;
642 }
643 break;
644
645 case CMD_AXI_CFG_SNAP_O1_AND_O2: {
646 axid = data;
647 if (!axid) {
648 rc = -EFAULT;
649 goto config_failure;
650 }
651
652 axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
653 if (!axio) {
654 rc = -ENOMEM;
655 goto config_failure;
656 }
657
658 if (copy_from_user(axio, (void __user *)(vfecmd->value),
659 sizeof(struct axiout))) {
660 rc = -EFAULT;
661 goto config_done;
662 }
663
664 vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
665
666 cmd_data = axio;
667 }
668 break;
669
670 default:
671 break;
672 } /* switch */
673
674 if (vfestopped)
675 goto config_done;
676
677config_send:
678 CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
679 rc = msm_adsp_write(vfe_mod, vfecmd->queue,
680 cmd_data, vfecmd->length);
681
682config_done:
683 if (cmd_data_alloc != NULL)
684 kfree(cmd_data_alloc);
685
686config_failure:
687 kfree(scfg);
688 kfree(axio);
689 kfree(vfecmd);
690 return rc;
691}
692
693void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
694{
695 mutex_init(&vfe_lock);
696 fptr->vfe_init = vfe_7x_init;
697 fptr->vfe_enable = vfe_7x_enable;
698 fptr->vfe_config = vfe_7x_config;
699 fptr->vfe_disable = vfe_7x_disable;
700 fptr->vfe_release = vfe_7x_release;
701 vfe_syncdata = data;
702}
diff --git a/drivers/staging/dream/camera/msm_vfe7x.h b/drivers/staging/dream/camera/msm_vfe7x.h
deleted file mode 100644
index be3e9ad8f524..000000000000
--- a/drivers/staging/dream/camera/msm_vfe7x.h
+++ /dev/null
@@ -1,255 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4#ifndef __MSM_VFE7X_H__
5#define __MSM_VFE7X_H__
6#include <media/msm_camera.h>
7#include <mach/camera.h>
8
9struct vfe_frame_extra {
10 uint32_t bl_evencol;
11 uint32_t bl_oddcol;
12 uint16_t g_def_p_cnt;
13 uint16_t r_b_def_p_cnt;
14};
15
16struct vfe_endframe {
17 uint32_t y_address;
18 uint32_t cbcr_address;
19
20 unsigned int blacklevelevencolumn:23;
21 uint16_t reserved1:9;
22 unsigned int blackleveloddcolumn:23;
23 uint16_t reserved2:9;
24
25 uint16_t greendefectpixelcount:8;
26 uint16_t reserved3:8;
27 uint16_t redbluedefectpixelcount:8;
28 uint16_t reserved4:8;
29} __attribute__((packed, aligned(4)));
30
31struct vfe_outputack {
32 uint32_t header;
33 void *output2newybufferaddress;
34 void *output2newcbcrbufferaddress;
35} __attribute__((packed, aligned(4)));
36
37struct vfe_stats_ack {
38 uint32_t header;
39 /* MUST BE 64 bit ALIGNED */
40 void *bufaddr;
41} __attribute__((packed, aligned(4)));
42
43/* AXI Output Config Command sent to DSP */
44struct axiout {
45 uint32_t cmdheader:32;
46 int outputmode:3;
47 uint8_t format:2;
48 uint32_t /* reserved */ : 27;
49
50 /* AXI Output 1 Y Configuration, Part 1 */
51 uint32_t out1yimageheight:12;
52 uint32_t /* reserved */ : 4;
53 uint32_t out1yimagewidthin64bitwords:10;
54 uint32_t /* reserved */ : 6;
55
56 /* AXI Output 1 Y Configuration, Part 2 */
57 uint8_t out1yburstlen:2;
58 uint32_t out1ynumrows:12;
59 uint32_t out1yrowincin64bitincs:12;
60 uint32_t /* reserved */ : 6;
61
62 /* AXI Output 1 CbCr Configuration, Part 1 */
63 uint32_t out1cbcrimageheight:12;
64 uint32_t /* reserved */ : 4;
65 uint32_t out1cbcrimagewidthin64bitwords:10;
66 uint32_t /* reserved */ : 6;
67
68 /* AXI Output 1 CbCr Configuration, Part 2 */
69 uint8_t out1cbcrburstlen:2;
70 uint32_t out1cbcrnumrows:12;
71 uint32_t out1cbcrrowincin64bitincs:12;
72 uint32_t /* reserved */ : 6;
73
74 /* AXI Output 2 Y Configuration, Part 1 */
75 uint32_t out2yimageheight:12;
76 uint32_t /* reserved */ : 4;
77 uint32_t out2yimagewidthin64bitwords:10;
78 uint32_t /* reserved */ : 6;
79
80 /* AXI Output 2 Y Configuration, Part 2 */
81 uint8_t out2yburstlen:2;
82 uint32_t out2ynumrows:12;
83 uint32_t out2yrowincin64bitincs:12;
84 uint32_t /* reserved */ : 6;
85
86 /* AXI Output 2 CbCr Configuration, Part 1 */
87 uint32_t out2cbcrimageheight:12;
88 uint32_t /* reserved */ : 4;
89 uint32_t out2cbcrimagewidtein64bitwords:10;
90 uint32_t /* reserved */ : 6;
91
92 /* AXI Output 2 CbCr Configuration, Part 2 */
93 uint8_t out2cbcrburstlen:2;
94 uint32_t out2cbcrnumrows:12;
95 uint32_t out2cbcrrowincin64bitincs:12;
96 uint32_t /* reserved */ : 6;
97
98 /* Address configuration:
99 * output1 phisycal address */
100 unsigned long output1buffer1_y_phy;
101 unsigned long output1buffer1_cbcr_phy;
102 unsigned long output1buffer2_y_phy;
103 unsigned long output1buffer2_cbcr_phy;
104 unsigned long output1buffer3_y_phy;
105 unsigned long output1buffer3_cbcr_phy;
106 unsigned long output1buffer4_y_phy;
107 unsigned long output1buffer4_cbcr_phy;
108 unsigned long output1buffer5_y_phy;
109 unsigned long output1buffer5_cbcr_phy;
110 unsigned long output1buffer6_y_phy;
111 unsigned long output1buffer6_cbcr_phy;
112 unsigned long output1buffer7_y_phy;
113 unsigned long output1buffer7_cbcr_phy;
114 unsigned long output1buffer8_y_phy;
115 unsigned long output1buffer8_cbcr_phy;
116
117 /* output2 phisycal address */
118 unsigned long output2buffer1_y_phy;
119 unsigned long output2buffer1_cbcr_phy;
120 unsigned long output2buffer2_y_phy;
121 unsigned long output2buffer2_cbcr_phy;
122 unsigned long output2buffer3_y_phy;
123 unsigned long output2buffer3_cbcr_phy;
124 unsigned long output2buffer4_y_phy;
125 unsigned long output2buffer4_cbcr_phy;
126 unsigned long output2buffer5_y_phy;
127 unsigned long output2buffer5_cbcr_phy;
128 unsigned long output2buffer6_y_phy;
129 unsigned long output2buffer6_cbcr_phy;
130 unsigned long output2buffer7_y_phy;
131 unsigned long output2buffer7_cbcr_phy;
132 unsigned long output2buffer8_y_phy;
133 unsigned long output2buffer8_cbcr_phy;
134} __attribute__((packed, aligned(4)));
135
136struct vfe_stats_we_cfg {
137 uint32_t header;
138
139 /* White Balance/Exposure Statistic Selection */
140 uint8_t wb_expstatsenable:1;
141 uint8_t wb_expstatbuspriorityselection:1;
142 unsigned int wb_expstatbuspriorityvalue:4;
143 unsigned int /* reserved */ : 26;
144
145 /* White Balance/Exposure Statistic Configuration, Part 1 */
146 uint8_t exposurestatregions:1;
147 uint8_t exposurestatsubregions:1;
148 unsigned int /* reserved */ : 14;
149
150 unsigned int whitebalanceminimumy:8;
151 unsigned int whitebalancemaximumy:8;
152
153 /* White Balance/Exposure Statistic Configuration, Part 2 */
154 uint8_t wb_expstatslopeofneutralregionline[
155 NUM_WB_EXP_NEUTRAL_REGION_LINES];
156
157 /* White Balance/Exposure Statistic Configuration, Part 3 */
158 unsigned int wb_expstatcrinterceptofneutralregionline2:12;
159 unsigned int /* reserved */ : 4;
160 unsigned int wb_expstatcbinterceptofneutralreginnline1:12;
161 unsigned int /* reserved */ : 4;
162
163 /* White Balance/Exposure Statistic Configuration, Part 4 */
164 unsigned int wb_expstatcrinterceptofneutralregionline4:12;
165 unsigned int /* reserved */ : 4;
166 unsigned int wb_expstatcbinterceptofneutralregionline3:12;
167 unsigned int /* reserved */ : 4;
168
169 /* White Balance/Exposure Statistic Output Buffer Header */
170 unsigned int wb_expmetricheaderpattern:8;
171 unsigned int /* reserved */ : 24;
172
173 /* White Balance/Exposure Statistic Output Buffers-MUST
174 * BE 64 bit ALIGNED */
175 void *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
176} __attribute__((packed, aligned(4)));
177
178struct vfe_stats_af_cfg {
179 uint32_t header;
180
181 /* Autofocus Statistic Selection */
182 uint8_t af_enable:1;
183 uint8_t af_busprioritysel:1;
184 unsigned int af_buspriorityval:4;
185 unsigned int /* reserved */ : 26;
186
187 /* Autofocus Statistic Configuration, Part 1 */
188 unsigned int af_singlewinvoffset:12;
189 unsigned int /* reserved */ : 4;
190 unsigned int af_singlewinhoffset:12;
191 unsigned int /* reserved */ : 3;
192 uint8_t af_winmode:1;
193
194 /* Autofocus Statistic Configuration, Part 2 */
195 unsigned int af_singglewinvh:11;
196 unsigned int /* reserved */ : 5;
197 unsigned int af_singlewinhw:11;
198 unsigned int /* reserved */ : 5;
199
200 /* Autofocus Statistic Configuration, Parts 3-6 */
201 uint8_t af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
202
203 /* Autofocus Statistic Configuration, Part 7 */
204 signed int af_metrichpfcoefa00:5;
205 signed int af_metrichpfcoefa04:5;
206 unsigned int af_metricmaxval:11;
207 uint8_t af_metricsel:1;
208 unsigned int /* reserved */ : 10;
209
210 /* Autofocus Statistic Configuration, Part 8 */
211 signed int af_metrichpfcoefa20:5;
212 signed int af_metrichpfcoefa21:5;
213 signed int af_metrichpfcoefa22:5;
214 signed int af_metrichpfcoefa23:5;
215 signed int af_metrichpfcoefa24:5;
216 unsigned int /* reserved */ : 7;
217
218 /* Autofocus Statistic Output Buffer Header */
219 unsigned int af_metrichp:8;
220 unsigned int /* reserved */ : 24;
221
222 /* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
223 void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
224} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
225
226struct msm_camera_frame_msg {
227 unsigned long output_y_address;
228 unsigned long output_cbcr_address;
229
230 unsigned int blacklevelevenColumn:23;
231 uint16_t reserved1:9;
232 unsigned int blackleveloddColumn:23;
233 uint16_t reserved2:9;
234
235 uint16_t greendefectpixelcount:8;
236 uint16_t reserved3:8;
237 uint16_t redbluedefectpixelcount:8;
238 uint16_t reserved4:8;
239} __attribute__((packed, aligned(4)));
240
241/* New one for 7k */
242struct msm_vfe_command_7k {
243 uint16_t queue;
244 uint16_t length;
245 void *value;
246};
247
248struct stop_event {
249 wait_queue_head_t wait;
250 int state;
251 int timeout;
252};
253
254
255#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x.c b/drivers/staging/dream/camera/msm_vfe8x.c
deleted file mode 100644
index d87d56f914de..000000000000
--- a/drivers/staging/dream/camera/msm_vfe8x.c
+++ /dev/null
@@ -1,736 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4#include <linux/slab.h>
5#include <linux/uaccess.h>
6#include <linux/interrupt.h>
7#include <mach/irqs.h>
8#include "msm_vfe8x_proc.h"
9
10#define ON 1
11#define OFF 0
12
13struct mutex vfe_lock;
14static void *vfe_syncdata;
15
16static int vfe_enable(struct camera_enable_cmd *enable)
17{
18 int rc = 0;
19 return rc;
20}
21
22static int vfe_disable(struct camera_enable_cmd *enable,
23 struct platform_device *dev)
24{
25 int rc = 0;
26
27 vfe_stop();
28
29 msm_camio_disable(dev);
30 return rc;
31}
32
33static void vfe_release(struct platform_device *dev)
34{
35 msm_camio_disable(dev);
36 vfe_cmd_release(dev);
37
38 mutex_lock(&vfe_lock);
39 vfe_syncdata = NULL;
40 mutex_unlock(&vfe_lock);
41}
42
43static void vfe_config_axi(int mode,
44 struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
45{
46 struct msm_pmem_region *regptr;
47 int i, j;
48 uint32_t *p1, *p2;
49
50 if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
51 regptr = ad->region;
52 for (i = 0;
53 i < ad->bufnum1; i++) {
54
55 p1 = &(ao->output1.outputY.outFragments[i][0]);
56 p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
57
58 for (j = 0;
59 j < ao->output1.fragmentCount; j++) {
60
61 *p1 = regptr->paddr + regptr->y_off;
62 p1++;
63
64 *p2 = regptr->paddr + regptr->cbcr_off;
65 p2++;
66 }
67 regptr++;
68 }
69 } /* if OUTPUT1 or Both */
70
71 if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
72
73 regptr = &(ad->region[ad->bufnum1]);
74 CDBG("bufnum2 = %d\n", ad->bufnum2);
75
76 for (i = 0;
77 i < ad->bufnum2; i++) {
78
79 p1 = &(ao->output2.outputY.outFragments[i][0]);
80 p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
81
82 CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
83 regptr->paddr, regptr->y_off, regptr->cbcr_off);
84
85 for (j = 0;
86 j < ao->output2.fragmentCount; j++) {
87
88 *p1 = regptr->paddr + regptr->y_off;
89 CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
90 p1++;
91
92 *p2 = regptr->paddr + regptr->cbcr_off;
93 CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
94 p2++;
95 }
96 regptr++;
97 }
98 }
99}
100
101static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
102{
103 int rc = 0;
104
105 CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
106
107 switch (cmd->id) {
108 case VFE_CMD_ID_RESET:
109 msm_camio_vfe_blk_reset();
110 msm_camio_camif_pad_reg_reset_2();
111 vfe_reset();
112 break;
113
114 case VFE_CMD_ID_START: {
115 struct vfe_cmd_start start;
116 if (copy_from_user(&start,
117 (void __user *) cmd->value, cmd->length))
118 rc = -EFAULT;
119
120 /* msm_camio_camif_pad_reg_reset_2(); */
121 msm_camio_camif_pad_reg_reset();
122 vfe_start(&start);
123 }
124 break;
125
126 case VFE_CMD_ID_CAMIF_CONFIG: {
127 struct vfe_cmd_camif_config camif;
128 if (copy_from_user(&camif,
129 (void __user *) cmd->value, cmd->length))
130 rc = -EFAULT;
131
132 vfe_camif_config(&camif);
133 }
134 break;
135
136 case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
137 struct vfe_cmd_black_level_config bl;
138 if (copy_from_user(&bl,
139 (void __user *) cmd->value, cmd->length))
140 rc = -EFAULT;
141
142 vfe_black_level_config(&bl);
143 }
144 break;
145
146 case VFE_CMD_ID_ROLL_OFF_CONFIG: {
147 struct vfe_cmd_roll_off_config rolloff;
148 if (copy_from_user(&rolloff,
149 (void __user *) cmd->value, cmd->length))
150 rc = -EFAULT;
151
152 vfe_roll_off_config(&rolloff);
153 }
154 break;
155
156 case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
157 struct vfe_cmd_demux_channel_gain_config demuxc;
158 if (copy_from_user(&demuxc,
159 (void __user *) cmd->value, cmd->length))
160 rc = -EFAULT;
161
162 /* demux is always enabled. */
163 vfe_demux_channel_gain_config(&demuxc);
164 }
165 break;
166
167 case VFE_CMD_ID_DEMOSAIC_CONFIG: {
168 struct vfe_cmd_demosaic_config demosaic;
169 if (copy_from_user(&demosaic,
170 (void __user *) cmd->value, cmd->length))
171 rc = -EFAULT;
172
173 vfe_demosaic_config(&demosaic);
174 }
175 break;
176
177 case VFE_CMD_ID_FOV_CROP_CONFIG:
178 case VFE_CMD_ID_FOV_CROP_UPDATE: {
179 struct vfe_cmd_fov_crop_config fov;
180 if (copy_from_user(&fov,
181 (void __user *) cmd->value, cmd->length))
182 rc = -EFAULT;
183
184 vfe_fov_crop_config(&fov);
185 }
186 break;
187
188 case VFE_CMD_ID_MAIN_SCALER_CONFIG:
189 case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
190 struct vfe_cmd_main_scaler_config mainds;
191 if (copy_from_user(&mainds,
192 (void __user *) cmd->value, cmd->length))
193 rc = -EFAULT;
194
195 vfe_main_scaler_config(&mainds);
196 }
197 break;
198
199 case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
200 case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
201 struct vfe_cmd_white_balance_config wb;
202 if (copy_from_user(&wb,
203 (void __user *) cmd->value, cmd->length))
204 rc = -EFAULT;
205
206 vfe_white_balance_config(&wb);
207 }
208 break;
209
210 case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
211 case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
212 struct vfe_cmd_color_correction_config cc;
213 if (copy_from_user(&cc,
214 (void __user *) cmd->value, cmd->length))
215 rc = -EFAULT;
216
217 vfe_color_correction_config(&cc);
218 }
219 break;
220
221 case VFE_CMD_ID_LA_CONFIG: {
222 struct vfe_cmd_la_config la;
223 if (copy_from_user(&la,
224 (void __user *) cmd->value, cmd->length))
225 rc = -EFAULT;
226
227 vfe_la_config(&la);
228 }
229 break;
230
231 case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
232 struct vfe_cmd_rgb_gamma_config rgb;
233 if (copy_from_user(&rgb,
234 (void __user *) cmd->value, cmd->length))
235 rc = -EFAULT;
236
237 rc = vfe_rgb_gamma_config(&rgb);
238 }
239 break;
240
241 case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
242 case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
243 struct vfe_cmd_chroma_enhan_config chrom;
244 if (copy_from_user(&chrom,
245 (void __user *) cmd->value, cmd->length))
246 rc = -EFAULT;
247
248 vfe_chroma_enhan_config(&chrom);
249 }
250 break;
251
252 case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
253 case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
254 struct vfe_cmd_chroma_suppression_config chromsup;
255 if (copy_from_user(&chromsup,
256 (void __user *) cmd->value, cmd->length))
257 rc = -EFAULT;
258
259 vfe_chroma_sup_config(&chromsup);
260 }
261 break;
262
263 case VFE_CMD_ID_ASF_CONFIG: {
264 struct vfe_cmd_asf_config asf;
265 if (copy_from_user(&asf,
266 (void __user *) cmd->value, cmd->length))
267 rc = -EFAULT;
268
269 vfe_asf_config(&asf);
270 }
271 break;
272
273 case VFE_CMD_ID_SCALER2Y_CONFIG:
274 case VFE_CMD_ID_SCALER2Y_UPDATE: {
275 struct vfe_cmd_scaler2_config ds2y;
276 if (copy_from_user(&ds2y,
277 (void __user *) cmd->value, cmd->length))
278 rc = -EFAULT;
279
280 vfe_scaler2y_config(&ds2y);
281 }
282 break;
283
284 case VFE_CMD_ID_SCALER2CbCr_CONFIG:
285 case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
286 struct vfe_cmd_scaler2_config ds2cbcr;
287 if (copy_from_user(&ds2cbcr,
288 (void __user *) cmd->value, cmd->length))
289 rc = -EFAULT;
290
291 vfe_scaler2cbcr_config(&ds2cbcr);
292 }
293 break;
294
295 case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
296 struct vfe_cmd_chroma_subsample_config sub;
297 if (copy_from_user(&sub,
298 (void __user *) cmd->value, cmd->length))
299 rc = -EFAULT;
300
301 vfe_chroma_subsample_config(&sub);
302 }
303 break;
304
305 case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
306 struct vfe_cmd_frame_skip_config fskip;
307 if (copy_from_user(&fskip,
308 (void __user *) cmd->value, cmd->length))
309 rc = -EFAULT;
310
311 vfe_frame_skip_config(&fskip);
312 }
313 break;
314
315 case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
316 struct vfe_cmd_output_clamp_config clamp;
317 if (copy_from_user(&clamp,
318 (void __user *) cmd->value, cmd->length))
319 rc = -EFAULT;
320
321 vfe_output_clamp_config(&clamp);
322 }
323 break;
324
325 /* module update commands */
326 case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
327 struct vfe_cmd_black_level_config blk;
328 if (copy_from_user(&blk,
329 (void __user *) cmd->value, cmd->length))
330 rc = -EFAULT;
331
332 vfe_black_level_update(&blk);
333 }
334 break;
335
336 case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
337 struct vfe_cmd_demux_channel_gain_config dmu;
338 if (copy_from_user(&dmu,
339 (void __user *) cmd->value, cmd->length))
340 rc = -EFAULT;
341
342 vfe_demux_channel_gain_update(&dmu);
343 }
344 break;
345
346 case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
347 struct vfe_cmd_demosaic_bpc_update demo_bpc;
348 if (copy_from_user(&demo_bpc,
349 (void __user *) cmd->value, cmd->length))
350 rc = -EFAULT;
351
352 vfe_demosaic_bpc_update(&demo_bpc);
353 }
354 break;
355
356 case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
357 struct vfe_cmd_demosaic_abf_update demo_abf;
358 if (copy_from_user(&demo_abf,
359 (void __user *) cmd->value, cmd->length))
360 rc = -EFAULT;
361
362 vfe_demosaic_abf_update(&demo_abf);
363 }
364 break;
365
366 case VFE_CMD_ID_LA_UPDATE: {
367 struct vfe_cmd_la_config la;
368 if (copy_from_user(&la,
369 (void __user *) cmd->value, cmd->length))
370 rc = -EFAULT;
371
372 vfe_la_update(&la);
373 }
374 break;
375
376 case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
377 struct vfe_cmd_rgb_gamma_config rgb;
378 if (copy_from_user(&rgb,
379 (void __user *) cmd->value, cmd->length))
380 rc = -EFAULT;
381
382 rc = vfe_rgb_gamma_update(&rgb);
383 }
384 break;
385
386 case VFE_CMD_ID_ASF_UPDATE: {
387 struct vfe_cmd_asf_update asf;
388 if (copy_from_user(&asf,
389 (void __user *) cmd->value, cmd->length))
390 rc = -EFAULT;
391
392 vfe_asf_update(&asf);
393 }
394 break;
395
396 case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
397 struct vfe_cmd_frame_skip_update fskip;
398 if (copy_from_user(&fskip,
399 (void __user *) cmd->value, cmd->length))
400 rc = -EFAULT;
401
402 vfe_frame_skip_update(&fskip);
403 }
404 break;
405
406 case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
407 struct vfe_cmds_camif_frame fup;
408 if (copy_from_user(&fup,
409 (void __user *) cmd->value, cmd->length))
410 rc = -EFAULT;
411
412 vfe_camif_frame_update(&fup);
413 }
414 break;
415
416 /* stats update commands */
417 case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
418 struct vfe_cmd_stats_af_update afup;
419 if (copy_from_user(&afup,
420 (void __user *) cmd->value, cmd->length))
421 rc = -EFAULT;
422
423 vfe_stats_update_af(&afup);
424 }
425 break;
426
427 case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
428 struct vfe_cmd_stats_wb_exp_update wbexp;
429 if (copy_from_user(&wbexp,
430 (void __user *) cmd->value, cmd->length))
431 rc = -EFAULT;
432
433 vfe_stats_update_wb_exp(&wbexp);
434 }
435 break;
436
437 /* control of start, stop, update, etc... */
438 case VFE_CMD_ID_STOP:
439 vfe_stop();
440 break;
441
442 case VFE_CMD_ID_GET_HW_VERSION:
443 break;
444
445 /* stats */
446 case VFE_CMD_ID_STATS_SETTING: {
447 struct vfe_cmd_stats_setting stats;
448 if (copy_from_user(&stats,
449 (void __user *) cmd->value, cmd->length))
450 rc = -EFAULT;
451
452 vfe_stats_setting(&stats);
453 }
454 break;
455
456 case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
457 struct vfe_cmd_stats_af_start af;
458 if (copy_from_user(&af,
459 (void __user *) cmd->value, cmd->length))
460 rc = -EFAULT;
461
462 vfe_stats_start_af(&af);
463 }
464 break;
465
466 case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
467 vfe_stats_af_stop();
468 break;
469
470 case VFE_CMD_ID_STATS_WB_EXP_START: {
471 struct vfe_cmd_stats_wb_exp_start awexp;
472 if (copy_from_user(&awexp,
473 (void __user *) cmd->value, cmd->length))
474 rc = -EFAULT;
475
476 vfe_stats_start_wb_exp(&awexp);
477 }
478 break;
479
480 case VFE_CMD_ID_STATS_WB_EXP_STOP:
481 vfe_stats_wb_exp_stop();
482 break;
483
484 case VFE_CMD_ID_ASYNC_TIMER_SETTING:
485 break;
486
487 case VFE_CMD_ID_UPDATE:
488 vfe_update();
489 break;
490
491 /* test gen */
492 case VFE_CMD_ID_TEST_GEN_START:
493 break;
494
495/*
496 acknowledge from upper layer
497 these are not in general command.
498
499 case VFE_CMD_ID_OUTPUT1_ACK:
500 break;
501 case VFE_CMD_ID_OUTPUT2_ACK:
502 break;
503 case VFE_CMD_ID_EPOCH1_ACK:
504 break;
505 case VFE_CMD_ID_EPOCH2_ACK:
506 break;
507 case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
508 break;
509 case VFE_CMD_ID_STATS_WB_EXP_ACK:
510 break;
511*/
512
513 default:
514 break;
515 } /* switch */
516
517 return rc;
518}
519
520static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
521{
522 struct msm_pmem_region *regptr;
523 struct msm_vfe_command_8k vfecmd;
524
525 uint32_t i;
526
527 void *cmd_data = NULL;
528 long rc = 0;
529
530 struct vfe_cmd_axi_output_config *axio = NULL;
531 struct vfe_cmd_stats_setting *scfg = NULL;
532
533 if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
534 cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
535
536 if (copy_from_user(&vfecmd,
537 (void __user *)(cmd->value),
538 sizeof(struct msm_vfe_command_8k)))
539 return -EFAULT;
540 }
541
542 CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
543
544 switch (cmd->cmd_type) {
545 case CMD_GENERAL:
546 rc = vfe_proc_general(&vfecmd);
547 break;
548
549 case CMD_STATS_ENABLE:
550 case CMD_STATS_AXI_CFG: {
551 struct axidata *axid;
552
553 axid = data;
554 if (!axid)
555 return -EFAULT;
556
557 scfg =
558 kmalloc(sizeof(struct vfe_cmd_stats_setting),
559 GFP_ATOMIC);
560 if (!scfg)
561 return -ENOMEM;
562
563 if (copy_from_user(scfg,
564 (void __user *)(vfecmd.value),
565 vfecmd.length)) {
566
567 kfree(scfg);
568 return -EFAULT;
569 }
570
571 regptr = axid->region;
572 if (axid->bufnum1 > 0) {
573 for (i = 0; i < axid->bufnum1; i++) {
574 scfg->awbBuffer[i] =
575 (uint32_t)(regptr->paddr);
576 regptr++;
577 }
578 }
579
580 if (axid->bufnum2 > 0) {
581 for (i = 0; i < axid->bufnum2; i++) {
582 scfg->afBuffer[i] =
583 (uint32_t)(regptr->paddr);
584 regptr++;
585 }
586 }
587
588 vfe_stats_config(scfg);
589 }
590 break;
591
592 case CMD_STATS_AF_AXI_CFG: {
593 }
594 break;
595
596 case CMD_FRAME_BUF_RELEASE: {
597 /* preview buffer release */
598 struct msm_frame *b;
599 unsigned long p;
600 struct vfe_cmd_output_ack fack;
601
602 if (!data)
603 return -EFAULT;
604
605 b = (struct msm_frame *)(cmd->value);
606 p = *(unsigned long *)data;
607
608 b->path = MSM_FRAME_ENC;
609
610 fack.ybufaddr[0] =
611 (uint32_t)(p + b->y_off);
612
613 fack.chromabufaddr[0] =
614 (uint32_t)(p + b->cbcr_off);
615
616 if (b->path == MSM_FRAME_PREV_1)
617 vfe_output1_ack(&fack);
618
619 if (b->path == MSM_FRAME_ENC ||
620 b->path == MSM_FRAME_PREV_2)
621 vfe_output2_ack(&fack);
622 }
623 break;
624
625 case CMD_SNAP_BUF_RELEASE: {
626 }
627 break;
628
629 case CMD_STATS_BUF_RELEASE: {
630 struct vfe_cmd_stats_wb_exp_ack sack;
631
632 if (!data)
633 return -EFAULT;
634
635 sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
636 vfe_stats_wb_exp_ack(&sack);
637 }
638 break;
639
640 case CMD_AXI_CFG_OUT1: {
641 struct axidata *axid;
642
643 axid = data;
644 if (!axid)
645 return -EFAULT;
646
647 axio = memdup_user((void __user *)(vfecmd.value),
648 sizeof(struct vfe_cmd_axi_output_config));
649 if (IS_ERR(axio))
650 return PTR_ERR(axio);
651
652 vfe_config_axi(OUTPUT_1, axid, axio);
653 vfe_axi_output_config(axio);
654 }
655 break;
656
657 case CMD_AXI_CFG_OUT2:
658 case CMD_RAW_PICT_AXI_CFG: {
659 struct axidata *axid;
660
661 axid = data;
662 if (!axid)
663 return -EFAULT;
664
665 axio = memdup_user((void __user *)(vfecmd.value),
666 sizeof(struct vfe_cmd_axi_output_config));
667 if (IS_ERR(axio))
668 return PTR_ERR(axio);
669
670 vfe_config_axi(OUTPUT_2, axid, axio);
671
672 axio->outputDataSize = 0;
673 vfe_axi_output_config(axio);
674 }
675 break;
676
677 case CMD_AXI_CFG_SNAP_O1_AND_O2: {
678 struct axidata *axid;
679 axid = data;
680 if (!axid)
681 return -EFAULT;
682
683 axio = memdup_user((void __user *)(vfecmd.value),
684 sizeof(struct vfe_cmd_axi_output_config));
685 if (IS_ERR(axio))
686 return PTR_ERR(axio);
687
688 vfe_config_axi(OUTPUT_1_AND_2,
689 axid, axio);
690 vfe_axi_output_config(axio);
691 cmd_data = axio;
692 }
693 break;
694
695 default:
696 break;
697 } /* switch */
698
699 kfree(scfg);
700
701 kfree(axio);
702
703/*
704 if (cmd->length > 256 &&
705 cmd_data &&
706 (cmd->cmd_type == CMD_GENERAL ||
707 cmd->cmd_type == CMD_STATS_DISABLE)) {
708 kfree(cmd_data);
709 }
710*/
711 return rc;
712}
713
714static int vfe_init(struct msm_vfe_callback *presp,
715 struct platform_device *dev)
716{
717 int rc = 0;
718
719 rc = vfe_cmd_init(presp, dev, vfe_syncdata);
720 if (rc < 0)
721 return rc;
722
723 /* Bring up all the required GPIOs and Clocks */
724 return msm_camio_enable(dev);
725}
726
727void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
728{
729 mutex_init(&vfe_lock);
730 fptr->vfe_init = vfe_init;
731 fptr->vfe_enable = vfe_enable;
732 fptr->vfe_config = vfe_config;
733 fptr->vfe_disable = vfe_disable;
734 fptr->vfe_release = vfe_release;
735 vfe_syncdata = data;
736}
diff --git a/drivers/staging/dream/camera/msm_vfe8x.h b/drivers/staging/dream/camera/msm_vfe8x.h
deleted file mode 100644
index 28a70a9e5ed7..000000000000
--- a/drivers/staging/dream/camera/msm_vfe8x.h
+++ /dev/null
@@ -1,895 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4#ifndef __MSM_VFE8X_H__
5#define __MSM_VFE8X_H__
6
7#define TRUE 1
8#define FALSE 0
9#define boolean uint8_t
10
11enum VFE_STATE {
12 VFE_STATE_IDLE,
13 VFE_STATE_ACTIVE
14};
15
16enum vfe_cmd_id {
17 /*
18 *Important! Command_ID are arranged in order.
19 *Don't change!*/
20 VFE_CMD_ID_START,
21 VFE_CMD_ID_RESET,
22
23 /* bus and camif config */
24 VFE_CMD_ID_AXI_INPUT_CONFIG,
25 VFE_CMD_ID_CAMIF_CONFIG,
26 VFE_CMD_ID_AXI_OUTPUT_CONFIG,
27
28 /* module config */
29 VFE_CMD_ID_BLACK_LEVEL_CONFIG,
30 VFE_CMD_ID_ROLL_OFF_CONFIG,
31 VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
32 VFE_CMD_ID_DEMOSAIC_CONFIG,
33 VFE_CMD_ID_FOV_CROP_CONFIG,
34 VFE_CMD_ID_MAIN_SCALER_CONFIG,
35 VFE_CMD_ID_WHITE_BALANCE_CONFIG,
36 VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
37 VFE_CMD_ID_LA_CONFIG,
38 VFE_CMD_ID_RGB_GAMMA_CONFIG,
39 VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
40 VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
41 VFE_CMD_ID_ASF_CONFIG,
42 VFE_CMD_ID_SCALER2Y_CONFIG,
43 VFE_CMD_ID_SCALER2CbCr_CONFIG,
44 VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
45 VFE_CMD_ID_FRAME_SKIP_CONFIG,
46 VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
47
48 /* test gen */
49 VFE_CMD_ID_TEST_GEN_START,
50
51 VFE_CMD_ID_UPDATE,
52
53 /* ackownledge from upper layer */
54 VFE_CMD_ID_OUTPUT1_ACK,
55 VFE_CMD_ID_OUTPUT2_ACK,
56 VFE_CMD_ID_EPOCH1_ACK,
57 VFE_CMD_ID_EPOCH2_ACK,
58 VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
59 VFE_CMD_ID_STATS_WB_EXP_ACK,
60
61 /* module update commands */
62 VFE_CMD_ID_BLACK_LEVEL_UPDATE,
63 VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
64 VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
65 VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
66 VFE_CMD_ID_FOV_CROP_UPDATE,
67 VFE_CMD_ID_WHITE_BALANCE_UPDATE,
68 VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
69 VFE_CMD_ID_LA_UPDATE,
70 VFE_CMD_ID_RGB_GAMMA_UPDATE,
71 VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
72 VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
73 VFE_CMD_ID_MAIN_SCALER_UPDATE,
74 VFE_CMD_ID_SCALER2CbCr_UPDATE,
75 VFE_CMD_ID_SCALER2Y_UPDATE,
76 VFE_CMD_ID_ASF_UPDATE,
77 VFE_CMD_ID_FRAME_SKIP_UPDATE,
78 VFE_CMD_ID_CAMIF_FRAME_UPDATE,
79
80 /* stats update commands */
81 VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
82 VFE_CMD_ID_STATS_WB_EXP_UPDATE,
83
84 /* control of start, stop, update, etc... */
85 VFE_CMD_ID_STOP,
86 VFE_CMD_ID_GET_HW_VERSION,
87
88 /* stats */
89 VFE_CMD_ID_STATS_SETTING,
90 VFE_CMD_ID_STATS_AUTOFOCUS_START,
91 VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
92 VFE_CMD_ID_STATS_WB_EXP_START,
93 VFE_CMD_ID_STATS_WB_EXP_STOP,
94
95 VFE_CMD_ID_ASYNC_TIMER_SETTING,
96
97 /* max id */
98 VFE_CMD_ID_MAX
99};
100
101struct vfe_cmd_hw_version {
102 uint32_t minorVersion;
103 uint32_t majorVersion;
104 uint32_t coreVersion;
105};
106
107enum VFE_CAMIF_SYNC_EDGE {
108 VFE_CAMIF_SYNC_EDGE_ActiveHigh,
109 VFE_CAMIF_SYNC_EDGE_ActiveLow
110};
111
112enum VFE_CAMIF_SYNC_MODE {
113 VFE_CAMIF_SYNC_MODE_APS,
114 VFE_CAMIF_SYNC_MODE_EFS,
115 VFE_CAMIF_SYNC_MODE_ELS,
116 VFE_CAMIF_SYNC_MODE_ILLEGAL
117};
118
119struct vfe_cmds_camif_efs {
120 uint8_t efsendofline;
121 uint8_t efsstartofline;
122 uint8_t efsendofframe;
123 uint8_t efsstartofframe;
124};
125
126struct vfe_cmds_camif_frame {
127 uint16_t pixelsPerLine;
128 uint16_t linesPerFrame;
129};
130
131struct vfe_cmds_camif_window {
132 uint16_t firstpixel;
133 uint16_t lastpixel;
134 uint16_t firstline;
135 uint16_t lastline;
136};
137
138enum CAMIF_SUBSAMPLE_FRAME_SKIP {
139 CAMIF_SUBSAMPLE_FRAME_SKIP_0,
140 CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
141 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
142 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
143 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
144 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
145 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
146 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
147 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
148 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
149 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
150 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
151 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
152 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
153 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
154 CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
155};
156
157struct vfe_cmds_camif_subsample {
158 uint16_t pixelskipmask;
159 uint16_t lineskipmask;
160 enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
161 uint8_t frameskipmode;
162 uint8_t pixelskipwrap;
163};
164
165struct vfe_cmds_camif_epoch {
166 uint8_t enable;
167 uint16_t lineindex;
168};
169
170struct vfe_cmds_camif_cfg {
171 enum VFE_CAMIF_SYNC_EDGE vSyncEdge;
172 enum VFE_CAMIF_SYNC_EDGE hSyncEdge;
173 enum VFE_CAMIF_SYNC_MODE syncMode;
174 uint8_t vfeSubSampleEnable;
175 uint8_t busSubSampleEnable;
176 uint8_t irqSubSampleEnable;
177 uint8_t binningEnable;
178 uint8_t misrEnable;
179};
180
181struct vfe_cmd_camif_config {
182 struct vfe_cmds_camif_cfg camifConfig;
183 struct vfe_cmds_camif_efs EFS;
184 struct vfe_cmds_camif_frame frame;
185 struct vfe_cmds_camif_window window;
186 struct vfe_cmds_camif_subsample subsample;
187 struct vfe_cmds_camif_epoch epoch1;
188 struct vfe_cmds_camif_epoch epoch2;
189};
190
191enum VFE_AXI_OUTPUT_MODE {
192 VFE_AXI_OUTPUT_MODE_Output1,
193 VFE_AXI_OUTPUT_MODE_Output2,
194 VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
195 VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
196 VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
197 VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
198 VFE_AXI_LAST_OUTPUT_MODE_ENUM
199};
200
201enum VFE_RAW_WR_PATH_SEL {
202 VFE_RAW_OUTPUT_DISABLED,
203 VFE_RAW_OUTPUT_ENC_CBCR_PATH,
204 VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
205 VFE_RAW_OUTPUT_PATH_INVALID
206};
207
208enum VFE_RAW_PIXEL_DATA_SIZE {
209 VFE_RAW_PIXEL_DATA_SIZE_8BIT,
210 VFE_RAW_PIXEL_DATA_SIZE_10BIT,
211 VFE_RAW_PIXEL_DATA_SIZE_12BIT,
212};
213
214#define VFE_AXI_OUTPUT_BURST_LENGTH 4
215#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
216#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT 3
217
218struct vfe_cmds_axi_out_per_component {
219 uint16_t imageWidth;
220 uint16_t imageHeight;
221 uint16_t outRowCount;
222 uint16_t outRowIncrement;
223 uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
224 [VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
225};
226
227struct vfe_cmds_axi_per_output_path {
228 uint8_t fragmentCount;
229 struct vfe_cmds_axi_out_per_component outputY;
230 struct vfe_cmds_axi_out_per_component outputCbcr;
231};
232
233enum VFE_AXI_BURST_LENGTH {
234 VFE_AXI_BURST_LENGTH_IS_2 = 2,
235 VFE_AXI_BURST_LENGTH_IS_4 = 4,
236 VFE_AXI_BURST_LENGTH_IS_8 = 8,
237 VFE_AXI_BURST_LENGTH_IS_16 = 16
238};
239
240struct vfe_cmd_axi_output_config {
241 enum VFE_AXI_BURST_LENGTH burstLength;
242 enum VFE_AXI_OUTPUT_MODE outputMode;
243 enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
244 struct vfe_cmds_axi_per_output_path output1;
245 struct vfe_cmds_axi_per_output_path output2;
246};
247
248struct vfe_cmd_fov_crop_config {
249 uint8_t enable;
250 uint16_t firstPixel;
251 uint16_t lastPixel;
252 uint16_t firstLine;
253 uint16_t lastLine;
254};
255
256struct vfe_cmds_main_scaler_stripe_init {
257 uint16_t MNCounterInit;
258 uint16_t phaseInit;
259};
260
261struct vfe_cmds_scaler_one_dimension {
262 uint8_t enable;
263 uint16_t inputSize;
264 uint16_t outputSize;
265 uint32_t phaseMultiplicationFactor;
266 uint8_t interpolationResolution;
267};
268
269struct vfe_cmd_main_scaler_config {
270 uint8_t enable;
271 struct vfe_cmds_scaler_one_dimension hconfig;
272 struct vfe_cmds_scaler_one_dimension vconfig;
273 struct vfe_cmds_main_scaler_stripe_init MNInitH;
274 struct vfe_cmds_main_scaler_stripe_init MNInitV;
275};
276
277struct vfe_cmd_scaler2_config {
278 uint8_t enable;
279 struct vfe_cmds_scaler_one_dimension hconfig;
280 struct vfe_cmds_scaler_one_dimension vconfig;
281};
282
283struct vfe_cmd_frame_skip_config {
284 uint8_t output1Period;
285 uint32_t output1Pattern;
286 uint8_t output2Period;
287 uint32_t output2Pattern;
288};
289
290struct vfe_cmd_frame_skip_update {
291 uint32_t output1Pattern;
292 uint32_t output2Pattern;
293};
294
295struct vfe_cmd_output_clamp_config {
296 uint8_t minCh0;
297 uint8_t minCh1;
298 uint8_t minCh2;
299 uint8_t maxCh0;
300 uint8_t maxCh1;
301 uint8_t maxCh2;
302};
303
304struct vfe_cmd_chroma_subsample_config {
305 uint8_t enable;
306 uint8_t cropEnable;
307 uint8_t vsubSampleEnable;
308 uint8_t hsubSampleEnable;
309 uint8_t vCosited;
310 uint8_t hCosited;
311 uint8_t vCositedPhase;
312 uint8_t hCositedPhase;
313 uint16_t cropWidthFirstPixel;
314 uint16_t cropWidthLastPixel;
315 uint16_t cropHeightFirstLine;
316 uint16_t cropHeightLastLine;
317};
318
319enum VFE_START_INPUT_SOURCE {
320 VFE_START_INPUT_SOURCE_CAMIF,
321 VFE_START_INPUT_SOURCE_TESTGEN,
322 VFE_START_INPUT_SOURCE_AXI,
323 VFE_START_INPUT_SOURCE_INVALID
324};
325
326enum VFE_START_OPERATION_MODE {
327 VFE_START_OPERATION_MODE_CONTINUOUS,
328 VFE_START_OPERATION_MODE_SNAPSHOT
329};
330
331enum VFE_START_PIXEL_PATTERN {
332 VFE_BAYER_RGRGRG,
333 VFE_BAYER_GRGRGR,
334 VFE_BAYER_BGBGBG,
335 VFE_BAYER_GBGBGB,
336 VFE_YUV_YCbYCr,
337 VFE_YUV_YCrYCb,
338 VFE_YUV_CbYCrY,
339 VFE_YUV_CrYCbY
340};
341
342enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
343 VFE_BAYER_RAW,
344 VFE_YUV_INTERLEAVED,
345 VFE_YUV_PSEUDO_PLANAR_Y,
346 VFE_YUV_PSEUDO_PLANAR_CBCR
347};
348
349enum VFE_YUV_INPUT_COSITING_MODE {
350 VFE_YUV_COSITED,
351 VFE_YUV_INTERPOLATED
352};
353
354struct vfe_cmd_start {
355 enum VFE_START_INPUT_SOURCE inputSource;
356 enum VFE_START_OPERATION_MODE operationMode;
357 uint8_t snapshotCount;
358 enum VFE_START_PIXEL_PATTERN pixel;
359 enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
360};
361
362struct vfe_cmd_output_ack {
363 uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
364 uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
365};
366
367#define VFE_STATS_BUFFER_COUNT 3
368
369struct vfe_cmd_stats_setting {
370 uint16_t frameHDimension;
371 uint16_t frameVDimension;
372 uint8_t afBusPrioritySelection;
373 uint8_t afBusPriority;
374 uint8_t awbBusPrioritySelection;
375 uint8_t awbBusPriority;
376 uint8_t histBusPrioritySelection;
377 uint8_t histBusPriority;
378 uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
379 uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
380 uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
381};
382
383struct vfe_cmd_stats_af_start {
384 uint8_t enable;
385 uint8_t windowMode;
386 uint16_t windowHOffset;
387 uint16_t windowVOffset;
388 uint16_t windowWidth;
389 uint16_t windowHeight;
390 uint8_t gridForMultiWindows[16];
391 uint8_t metricSelection;
392 int16_t metricMax;
393 int8_t highPassCoef[7];
394 int8_t bufferHeader;
395};
396
397struct vfe_cmd_stats_af_update {
398 uint8_t windowMode;
399 uint16_t windowHOffset;
400 uint16_t windowVOffset;
401 uint16_t windowWidth;
402 uint16_t windowHeight;
403};
404
405struct vfe_cmd_stats_wb_exp_start {
406 uint8_t enable;
407 uint8_t wbExpRegions;
408 uint8_t wbExpSubRegion;
409 uint8_t awbYMin;
410 uint8_t awbYMax;
411 int8_t awbMCFG[4];
412 int16_t awbCCFG[4];
413 int8_t axwHeader;
414};
415
416struct vfe_cmd_stats_wb_exp_update {
417 uint8_t wbExpRegions;
418 uint8_t wbExpSubRegion;
419 int8_t awbYMin;
420 int8_t awbYMax;
421 int8_t awbMCFG[4];
422 int16_t awbCCFG[4];
423};
424
425struct vfe_cmd_stats_af_ack {
426 uint32_t nextAFOutputBufferAddr;
427};
428
429struct vfe_cmd_stats_wb_exp_ack {
430 uint32_t nextWbExpOutputBufferAddr;
431};
432
433struct vfe_cmd_black_level_config {
434 uint8_t enable;
435 uint16_t evenEvenAdjustment;
436 uint16_t evenOddAdjustment;
437 uint16_t oddEvenAdjustment;
438 uint16_t oddOddAdjustment;
439};
440
441/* 13*1 */
442#define VFE_ROLL_OFF_INIT_TABLE_SIZE 13
443/* 13*16 */
444#define VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
445
446struct vfe_cmd_roll_off_config {
447 uint8_t enable;
448 uint16_t gridWidth;
449 uint16_t gridHeight;
450 uint16_t yDelta;
451 uint8_t gridXIndex;
452 uint8_t gridYIndex;
453 uint16_t gridPixelXIndex;
454 uint16_t gridPixelYIndex;
455 uint16_t yDeltaAccum;
456 uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
457 uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
458 uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
459 uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
460 int16_t deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
461 int16_t deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
462 int16_t deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
463 int16_t deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
464};
465
466struct vfe_cmd_demux_channel_gain_config {
467 uint16_t ch0EvenGain;
468 uint16_t ch0OddGain;
469 uint16_t ch1Gain;
470 uint16_t ch2Gain;
471};
472
473struct vfe_cmds_demosaic_abf {
474 uint8_t enable;
475 uint8_t forceOn;
476 uint8_t shift;
477 uint16_t lpThreshold;
478 uint16_t max;
479 uint16_t min;
480 uint8_t ratio;
481};
482
483struct vfe_cmds_demosaic_bpc {
484 uint8_t enable;
485 uint16_t fmaxThreshold;
486 uint16_t fminThreshold;
487 uint16_t redDiffThreshold;
488 uint16_t blueDiffThreshold;
489 uint16_t greenDiffThreshold;
490};
491
492struct vfe_cmd_demosaic_config {
493 uint8_t enable;
494 uint8_t slopeShift;
495 struct vfe_cmds_demosaic_abf abfConfig;
496 struct vfe_cmds_demosaic_bpc bpcConfig;
497};
498
499struct vfe_cmd_demosaic_bpc_update {
500 struct vfe_cmds_demosaic_bpc bpcUpdate;
501};
502
503struct vfe_cmd_demosaic_abf_update {
504 struct vfe_cmds_demosaic_abf abfUpdate;
505};
506
507struct vfe_cmd_white_balance_config {
508 uint8_t enable;
509 uint16_t ch2Gain;
510 uint16_t ch1Gain;
511 uint16_t ch0Gain;
512};
513
514enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
515 COEF_IS_Q7_SIGNED,
516 COEF_IS_Q8_SIGNED,
517 COEF_IS_Q9_SIGNED,
518 COEF_IS_Q10_SIGNED
519};
520
521struct vfe_cmd_color_correction_config {
522 uint8_t enable;
523 enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
524 int16_t C0;
525 int16_t C1;
526 int16_t C2;
527 int16_t C3;
528 int16_t C4;
529 int16_t C5;
530 int16_t C6;
531 int16_t C7;
532 int16_t C8;
533 int16_t K0;
534 int16_t K1;
535 int16_t K2;
536};
537
538#define VFE_LA_TABLE_LENGTH 256
539struct vfe_cmd_la_config {
540 uint8_t enable;
541 int16_t table[VFE_LA_TABLE_LENGTH];
542};
543
544#define VFE_GAMMA_TABLE_LENGTH 256
545enum VFE_RGB_GAMMA_TABLE_SELECT {
546 RGB_GAMMA_CH0_SELECTED,
547 RGB_GAMMA_CH1_SELECTED,
548 RGB_GAMMA_CH2_SELECTED,
549 RGB_GAMMA_CH0_CH1_SELECTED,
550 RGB_GAMMA_CH0_CH2_SELECTED,
551 RGB_GAMMA_CH1_CH2_SELECTED,
552 RGB_GAMMA_CH0_CH1_CH2_SELECTED
553};
554
555struct vfe_cmd_rgb_gamma_config {
556 uint8_t enable;
557 enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
558 int16_t table[VFE_GAMMA_TABLE_LENGTH];
559};
560
561struct vfe_cmd_chroma_enhan_config {
562 uint8_t enable;
563 int16_t am;
564 int16_t ap;
565 int16_t bm;
566 int16_t bp;
567 int16_t cm;
568 int16_t cp;
569 int16_t dm;
570 int16_t dp;
571 int16_t kcr;
572 int16_t kcb;
573 int16_t RGBtoYConversionV0;
574 int16_t RGBtoYConversionV1;
575 int16_t RGBtoYConversionV2;
576 uint8_t RGBtoYConversionOffset;
577};
578
579struct vfe_cmd_chroma_suppression_config {
580 uint8_t enable;
581 uint8_t m1;
582 uint8_t m3;
583 uint8_t n1;
584 uint8_t n3;
585 uint8_t nn1;
586 uint8_t mm1;
587};
588
589struct vfe_cmd_asf_config {
590 uint8_t enable;
591 uint8_t smoothFilterEnabled;
592 uint8_t sharpMode;
593 uint8_t smoothCoefCenter;
594 uint8_t smoothCoefSurr;
595 uint8_t normalizeFactor;
596 uint8_t sharpK1;
597 uint8_t sharpK2;
598 uint8_t sharpThreshE1;
599 int8_t sharpThreshE2;
600 int8_t sharpThreshE3;
601 int8_t sharpThreshE4;
602 int8_t sharpThreshE5;
603 int8_t filter1Coefficients[9];
604 int8_t filter2Coefficients[9];
605 uint8_t cropEnable;
606 uint16_t cropFirstPixel;
607 uint16_t cropLastPixel;
608 uint16_t cropFirstLine;
609 uint16_t cropLastLine;
610};
611
612struct vfe_cmd_asf_update {
613 uint8_t enable;
614 uint8_t smoothFilterEnabled;
615 uint8_t sharpMode;
616 uint8_t smoothCoefCenter;
617 uint8_t smoothCoefSurr;
618 uint8_t normalizeFactor;
619 uint8_t sharpK1;
620 uint8_t sharpK2;
621 uint8_t sharpThreshE1;
622 int8_t sharpThreshE2;
623 int8_t sharpThreshE3;
624 int8_t sharpThreshE4;
625 int8_t sharpThreshE5;
626 int8_t filter1Coefficients[9];
627 int8_t filter2Coefficients[9];
628 uint8_t cropEnable;
629};
630
631enum VFE_TEST_GEN_SYNC_EDGE {
632 VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
633 VFE_TEST_GEN_SYNC_EDGE_ActiveLow
634};
635
636struct vfe_cmd_test_gen_start {
637 uint8_t pixelDataSelect;
638 uint8_t systematicDataSelect;
639 enum VFE_TEST_GEN_SYNC_EDGE hsyncEdge;
640 enum VFE_TEST_GEN_SYNC_EDGE vsyncEdge;
641 uint16_t numFrame;
642 enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
643 uint16_t imageWidth;
644 uint16_t imageHeight;
645 uint32_t startOfFrameOffset;
646 uint32_t endOfFrameNOffset;
647 uint16_t startOfLineOffset;
648 uint16_t endOfLineNOffset;
649 uint16_t hbi;
650 uint8_t vblEnable;
651 uint16_t vbl;
652 uint8_t startOfFrameDummyLine;
653 uint8_t endOfFrameDummyLine;
654 uint8_t unicolorBarEnable;
655 uint8_t colorBarsSplitEnable;
656 uint8_t unicolorBarSelect;
657 enum VFE_START_PIXEL_PATTERN colorBarsPixelPattern;
658 uint8_t colorBarsRotatePeriod;
659 uint16_t testGenRandomSeed;
660};
661
662struct vfe_cmd_bus_pm_start {
663 uint8_t output2YWrPmEnable;
664 uint8_t output2CbcrWrPmEnable;
665 uint8_t output1YWrPmEnable;
666 uint8_t output1CbcrWrPmEnable;
667};
668
669struct vfe_cmd_camif_frame_update {
670 struct vfe_cmds_camif_frame camifFrame;
671};
672
673struct vfe_cmd_sync_timer_setting {
674 uint8_t whichSyncTimer;
675 uint8_t operation;
676 uint8_t polarity;
677 uint16_t repeatCount;
678 uint16_t hsyncCount;
679 uint32_t pclkCount;
680 uint32_t outputDuration;
681};
682
683struct vfe_cmd_async_timer_setting {
684 uint8_t whichAsyncTimer;
685 uint8_t operation;
686 uint8_t polarity;
687 uint16_t repeatCount;
688 uint16_t inactiveCount;
689 uint32_t activeCount;
690};
691
692struct vfe_frame_skip_counts {
693 uint32_t totalFrameCount;
694 uint32_t output1Count;
695 uint32_t output2Count;
696};
697
698enum VFE_AXI_RD_UNPACK_HBI_SEL {
699 VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
700 VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
701 VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
702 VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
703 VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
704 VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
705 VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
706 VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
707};
708
709struct vfe_cmd_axi_input_config {
710 uint32_t fragAddr[4];
711 uint8_t totalFragmentCount;
712 uint16_t ySize;
713 uint16_t xOffset;
714 uint16_t xSize;
715 uint16_t rowIncrement;
716 uint16_t numOfRows;
717 enum VFE_AXI_BURST_LENGTH burstLength;
718 uint8_t unpackPhase;
719 enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
720 enum VFE_RAW_PIXEL_DATA_SIZE pixelSize;
721 uint8_t padRepeatCountLeft;
722 uint8_t padRepeatCountRight;
723 uint8_t padRepeatCountTop;
724 uint8_t padRepeatCountBottom;
725 uint8_t padLeftComponentSelectCycle0;
726 uint8_t padLeftComponentSelectCycle1;
727 uint8_t padLeftComponentSelectCycle2;
728 uint8_t padLeftComponentSelectCycle3;
729 uint8_t padLeftStopCycle0;
730 uint8_t padLeftStopCycle1;
731 uint8_t padLeftStopCycle2;
732 uint8_t padLeftStopCycle3;
733 uint8_t padRightComponentSelectCycle0;
734 uint8_t padRightComponentSelectCycle1;
735 uint8_t padRightComponentSelectCycle2;
736 uint8_t padRightComponentSelectCycle3;
737 uint8_t padRightStopCycle0;
738 uint8_t padRightStopCycle1;
739 uint8_t padRightStopCycle2;
740 uint8_t padRightStopCycle3;
741 uint8_t padTopLineCount;
742 uint8_t padBottomLineCount;
743};
744
745struct vfe_interrupt_status {
746 uint8_t camifErrorIrq;
747 uint8_t camifSofIrq;
748 uint8_t camifEolIrq;
749 uint8_t camifEofIrq;
750 uint8_t camifEpoch1Irq;
751 uint8_t camifEpoch2Irq;
752 uint8_t camifOverflowIrq;
753 uint8_t ceIrq;
754 uint8_t regUpdateIrq;
755 uint8_t resetAckIrq;
756 uint8_t encYPingpongIrq;
757 uint8_t encCbcrPingpongIrq;
758 uint8_t viewYPingpongIrq;
759 uint8_t viewCbcrPingpongIrq;
760 uint8_t rdPingpongIrq;
761 uint8_t afPingpongIrq;
762 uint8_t awbPingpongIrq;
763 uint8_t histPingpongIrq;
764 uint8_t encIrq;
765 uint8_t viewIrq;
766 uint8_t busOverflowIrq;
767 uint8_t afOverflowIrq;
768 uint8_t awbOverflowIrq;
769 uint8_t syncTimer0Irq;
770 uint8_t syncTimer1Irq;
771 uint8_t syncTimer2Irq;
772 uint8_t asyncTimer0Irq;
773 uint8_t asyncTimer1Irq;
774 uint8_t asyncTimer2Irq;
775 uint8_t asyncTimer3Irq;
776 uint8_t axiErrorIrq;
777 uint8_t violationIrq;
778 uint8_t anyErrorIrqs;
779 uint8_t anyOutput1PathIrqs;
780 uint8_t anyOutput2PathIrqs;
781 uint8_t anyOutputPathIrqs;
782 uint8_t anyAsyncTimerIrqs;
783 uint8_t anySyncTimerIrqs;
784 uint8_t anyIrqForActiveStatesOnly;
785};
786
787enum VFE_MESSAGE_ID {
788 VFE_MSG_ID_RESET_ACK,
789 VFE_MSG_ID_START_ACK,
790 VFE_MSG_ID_STOP_ACK,
791 VFE_MSG_ID_UPDATE_ACK,
792 VFE_MSG_ID_OUTPUT1,
793 VFE_MSG_ID_OUTPUT2,
794 VFE_MSG_ID_SNAPSHOT_DONE,
795 VFE_MSG_ID_STATS_AUTOFOCUS,
796 VFE_MSG_ID_STATS_WB_EXP,
797 VFE_MSG_ID_EPOCH1,
798 VFE_MSG_ID_EPOCH2,
799 VFE_MSG_ID_SYNC_TIMER0_DONE,
800 VFE_MSG_ID_SYNC_TIMER1_DONE,
801 VFE_MSG_ID_SYNC_TIMER2_DONE,
802 VFE_MSG_ID_ASYNC_TIMER0_DONE,
803 VFE_MSG_ID_ASYNC_TIMER1_DONE,
804 VFE_MSG_ID_ASYNC_TIMER2_DONE,
805 VFE_MSG_ID_ASYNC_TIMER3_DONE,
806 VFE_MSG_ID_AF_OVERFLOW,
807 VFE_MSG_ID_AWB_OVERFLOW,
808 VFE_MSG_ID_AXI_ERROR,
809 VFE_MSG_ID_CAMIF_OVERFLOW,
810 VFE_MSG_ID_VIOLATION,
811 VFE_MSG_ID_CAMIF_ERROR,
812 VFE_MSG_ID_BUS_OVERFLOW,
813};
814
815struct vfe_msg_stats_autofocus {
816 uint32_t afBuffer;
817 uint32_t frameCounter;
818};
819
820struct vfe_msg_stats_wb_exp {
821 uint32_t awbBuffer;
822 uint32_t frameCounter;
823};
824
825struct vfe_frame_bpc_info {
826 uint32_t greenDefectPixelCount;
827 uint32_t redBlueDefectPixelCount;
828};
829
830struct vfe_frame_asf_info {
831 uint32_t asfMaxEdge;
832 uint32_t asfHbiCount;
833};
834
835struct vfe_msg_camif_status {
836 uint8_t camifState;
837 uint32_t pixelCount;
838 uint32_t lineCount;
839};
840
841struct vfe_bus_pm_per_path {
842 uint32_t yWrPmStats0;
843 uint32_t yWrPmStats1;
844 uint32_t cbcrWrPmStats0;
845 uint32_t cbcrWrPmStats1;
846};
847
848struct vfe_bus_performance_monitor {
849 struct vfe_bus_pm_per_path encPathPmInfo;
850 struct vfe_bus_pm_per_path viewPathPmInfo;
851};
852
853struct vfe_irq_thread_msg {
854 uint32_t vfeIrqStatus;
855 uint32_t camifStatus;
856 uint32_t demosaicStatus;
857 uint32_t asfMaxEdge;
858 struct vfe_bus_performance_monitor pmInfo;
859};
860
861struct vfe_msg_output {
862 uint32_t yBuffer;
863 uint32_t cbcrBuffer;
864 struct vfe_frame_bpc_info bpcInfo;
865 struct vfe_frame_asf_info asfInfo;
866 uint32_t frameCounter;
867 struct vfe_bus_pm_per_path pmData;
868};
869
870struct vfe_message {
871 enum VFE_MESSAGE_ID _d;
872 union {
873 struct vfe_msg_output msgOutput1;
874 struct vfe_msg_output msgOutput2;
875 struct vfe_msg_stats_autofocus msgStatsAf;
876 struct vfe_msg_stats_wb_exp msgStatsWbExp;
877 struct vfe_msg_camif_status msgCamifError;
878 struct vfe_bus_performance_monitor msgBusOverflow;
879 } _u;
880};
881
882/* New one for 8k */
883struct msm_vfe_command_8k {
884 int32_t id;
885 uint16_t length;
886 void *value;
887};
888
889struct vfe_frame_extra {
890 struct vfe_frame_bpc_info bpcInfo;
891 struct vfe_frame_asf_info asfInfo;
892 uint32_t frameCounter;
893 struct vfe_bus_pm_per_path pmData;
894};
895#endif /* __MSM_VFE8X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.c b/drivers/staging/dream/camera/msm_vfe8x_proc.c
deleted file mode 100644
index f80ef967ba87..000000000000
--- a/drivers/staging/dream/camera/msm_vfe8x_proc.c
+++ /dev/null
@@ -1,4003 +0,0 @@
1/*
2* Copyright (C) 2008-2009 QUALCOMM Incorporated.
3*/
4#include <linux/slab.h>
5#include <linux/interrupt.h>
6#include <linux/spinlock.h>
7#include <linux/io.h>
8#include <linux/list.h>
9#include <linux/delay.h>
10#include <linux/platform_device.h>
11#include "msm_vfe8x_proc.h"
12#include <media/msm_camera.h>
13
14struct msm_vfe8x_ctrl {
15 /* bit 1:0 ENC_IRQ_MASK = 0x11:
16 * generate IRQ when both y and cbcr frame is ready. */
17
18 /* bit 1:0 VIEW_IRQ_MASK= 0x11:
19 * generate IRQ when both y and cbcr frame is ready. */
20 struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal;
21 struct vfe_module_enable vfeModuleEnableLocal;
22 struct vfe_camif_cfg_data vfeCamifConfigLocal;
23 struct vfe_interrupt_mask vfeImaskLocal;
24 struct vfe_stats_cmd_data vfeStatsCmdLocal;
25 struct vfe_bus_cfg_data vfeBusConfigLocal;
26 struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal;
27 struct vfe_bus_cmd_data vfeBusCmdLocal;
28 enum vfe_interrupt_name vfeInterruptNameLocal;
29 uint32_t vfeLaBankSel;
30 struct vfe_gamma_lut_sel vfeGammaLutSel;
31
32 boolean vfeStartAckPendingFlag;
33 boolean vfeStopAckPending;
34 boolean vfeResetAckPending;
35 boolean vfeUpdateAckPending;
36
37 enum VFE_AXI_OUTPUT_MODE axiOutputMode;
38 enum VFE_START_OPERATION_MODE vfeOperationMode;
39
40 uint32_t vfeSnapShotCount;
41 uint32_t vfeRequestedSnapShotCount;
42 boolean vfeStatsPingPongReloadFlag;
43 uint32_t vfeFrameId;
44
45 struct vfe_cmd_frame_skip_config vfeFrameSkip;
46 uint32_t vfeFrameSkipPattern;
47 uint8_t vfeFrameSkipCount;
48 uint8_t vfeFrameSkipPeriod;
49
50 boolean vfeTestGenStartFlag;
51 uint32_t vfeImaskPacked;
52 uint32_t vfeImaskCompositePacked;
53 enum VFE_RAW_PIXEL_DATA_SIZE axiInputDataSize;
54 struct vfe_irq_thread_msg vfeIrqThreadMsgLocal;
55
56 struct vfe_output_path_combo viewPath;
57 struct vfe_output_path_combo encPath;
58 struct vfe_frame_skip_counts vfeDroppedFrameCounts;
59 struct vfe_stats_control afStatsControl;
60 struct vfe_stats_control awbStatsControl;
61
62 enum VFE_STATE vstate;
63
64 spinlock_t ack_lock;
65 spinlock_t state_lock;
66 spinlock_t io_lock;
67
68 struct msm_vfe_callback *resp;
69 uint32_t extlen;
70 void *extdata;
71
72 spinlock_t tasklet_lock;
73 struct list_head tasklet_q;
74
75 int vfeirq;
76 void __iomem *vfebase;
77
78 void *syncdata;
79};
80static struct msm_vfe8x_ctrl *ctrl;
81static irqreturn_t vfe_parse_irq(int irq_num, void *data);
82
83struct isr_queue_cmd {
84 struct list_head list;
85 struct vfe_interrupt_status vfeInterruptStatus;
86 struct vfe_frame_asf_info vfeAsfFrameInfo;
87 struct vfe_frame_bpc_info vfeBpcFrameInfo;
88 struct vfe_msg_camif_status vfeCamifStatusLocal;
89 struct vfe_bus_performance_monitor vfePmData;
90};
91
92static void vfe_prog_hw(uint8_t *hwreg,
93 uint32_t *inptr, uint32_t regcnt)
94{
95 /* unsigned long flags; */
96 uint32_t i;
97 uint32_t *p;
98
99 /* @todo This is causing issues, need further investigate */
100 /* spin_lock_irqsave(&ctrl->io_lock, flags); */
101
102 p = (uint32_t *)(hwreg);
103 for (i = 0; i < (regcnt >> 2); i++)
104 writel(*inptr++, p++);
105 /* *p++ = *inptr++; */
106
107 /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
108}
109
110static void vfe_read_reg_values(uint8_t *hwreg,
111 uint32_t *dest, uint32_t count)
112{
113 /* unsigned long flags; */
114 uint32_t *temp;
115 uint32_t i;
116
117 /* @todo This is causing issues, need further investigate */
118 /* spin_lock_irqsave(&ctrl->io_lock, flags); */
119
120 temp = (uint32_t *)(hwreg);
121 for (i = 0; i < count; i++)
122 *dest++ = *temp++;
123
124 /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
125}
126
127static struct vfe_irqenable vfe_read_irq_mask(void)
128{
129 /* unsigned long flags; */
130 uint32_t *temp;
131 struct vfe_irqenable rc;
132
133 memset(&rc, 0, sizeof(rc));
134
135 /* @todo This is causing issues, need further investigate */
136 /* spin_lock_irqsave(&ctrl->io_lock, flags); */
137 temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_MASK);
138
139 rc = *((struct vfe_irqenable *)temp);
140 /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
141
142 return rc;
143}
144
145static void
146vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath,
147 struct vfe_output_path_combo *epath)
148{
149 vpath->yPath.hwRegPingAddress = (uint8_t *)
150 (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR);
151 vpath->yPath.hwRegPongAddress = (uint8_t *)
152 (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR);
153 vpath->cbcrPath.hwRegPingAddress = (uint8_t *)
154 (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR);
155 vpath->cbcrPath.hwRegPongAddress = (uint8_t *)
156 (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR);
157
158 epath->yPath.hwRegPingAddress = (uint8_t *)
159 (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR);
160 epath->yPath.hwRegPongAddress = (uint8_t *)
161 (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR);
162 epath->cbcrPath.hwRegPingAddress = (uint8_t *)
163 (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR);
164 epath->cbcrPath.hwRegPongAddress = (uint8_t *)
165 (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR);
166}
167
168static void vfe_axi_output(struct vfe_cmd_axi_output_config *in,
169 struct vfe_output_path_combo *out1,
170 struct vfe_output_path_combo *out2, uint16_t out)
171{
172 struct vfe_axi_out_cfg cmd;
173
174 uint16_t temp;
175 uint32_t burstLength;
176
177 /* force it to burst length 4, hardware does not support it. */
178 burstLength = 1;
179
180 /* AXI Output 2 Y Configuration*/
181 /* VFE_BUS_ENC_Y_WR_PING_ADDR */
182 cmd.out2YPingAddr = out2->yPath.addressBuffer[0];
183
184 /* VFE_BUS_ENC_Y_WR_PONG_ADDR */
185 cmd.out2YPongAddr = out2->yPath.addressBuffer[1];
186
187 /* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */
188 cmd.out2YImageHeight = in->output2.outputY.imageHeight;
189 /* convert the image width and row increment to be in
190 * unit of 64bit (8 bytes) */
191 temp = (in->output2.outputY.imageWidth + (out - 1)) /
192 out;
193 cmd.out2YImageWidthin64bit = temp;
194
195 /* VFE_BUS_ENC_Y_WR_BUFFER_CFG */
196 cmd.out2YBurstLength = burstLength;
197 cmd.out2YNumRows = in->output2.outputY.outRowCount;
198 temp = (in->output2.outputY.outRowIncrement + (out - 1)) /
199 out;
200 cmd.out2YRowIncrementIn64bit = temp;
201
202 /* AXI Output 2 Cbcr Configuration*/
203 /* VFE_BUS_ENC_Cbcr_WR_PING_ADDR */
204 cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0];
205
206 /* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR */
207 cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1];
208
209 /* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */
210 cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight;
211 temp = (in->output2.outputCbcr.imageWidth + (out - 1)) /
212 out;
213 cmd.out2CbcrImageWidthIn64bit = temp;
214
215 /* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */
216 cmd.out2CbcrBurstLength = burstLength;
217 cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount;
218 temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) /
219 out;
220 cmd.out2CbcrRowIncrementIn64bit = temp;
221
222 /* AXI Output 1 Y Configuration */
223 /* VFE_BUS_VIEW_Y_WR_PING_ADDR */
224 cmd.out1YPingAddr = out1->yPath.addressBuffer[0];
225
226 /* VFE_BUS_VIEW_Y_WR_PONG_ADDR */
227 cmd.out1YPongAddr = out1->yPath.addressBuffer[1];
228
229 /* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */
230 cmd.out1YImageHeight = in->output1.outputY.imageHeight;
231 temp = (in->output1.outputY.imageWidth + (out - 1)) /
232 out;
233 cmd.out1YImageWidthin64bit = temp;
234
235 /* VFE_BUS_VIEW_Y_WR_BUFFER_CFG */
236 cmd.out1YBurstLength = burstLength;
237 cmd.out1YNumRows = in->output1.outputY.outRowCount;
238
239 temp =
240 (in->output1.outputY.outRowIncrement +
241 (out - 1)) / out;
242 cmd.out1YRowIncrementIn64bit = temp;
243
244 /* AXI Output 1 Cbcr Configuration*/
245 cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0];
246
247 /* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR */
248 cmd.out1CbcrPongAddr =
249 out1->cbcrPath.addressBuffer[1];
250
251 /* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */
252 cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight;
253 temp = (in->output1.outputCbcr.imageWidth +
254 (out - 1)) / out;
255 cmd.out1CbcrImageWidthIn64bit = temp;
256
257 cmd.out1CbcrBurstLength = burstLength;
258 cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount;
259 temp =
260 (in->output1.outputCbcr.outRowIncrement +
261 (out - 1)) / out;
262
263 cmd.out1CbcrRowIncrementIn64bit = temp;
264
265 vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR,
266 (uint32_t *)&cmd, sizeof(cmd));
267}
268
269static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in)
270{
271 struct vfe_axi_bus_cfg cmd;
272
273 cmd.stripeRdPathEn = in->stripeRdPathEn;
274 cmd.encYWrPathEn = in->encYWrPathEn;
275 cmd.encCbcrWrPathEn = in->encCbcrWrPathEn;
276 cmd.viewYWrPathEn = in->viewYWrPathEn;
277 cmd.viewCbcrWrPathEn = in->viewCbcrWrPathEn;
278 cmd.rawPixelDataSize = (uint32_t)in->rawPixelDataSize;
279 cmd.rawWritePathSelect = (uint32_t)in->rawWritePathSelect;
280
281 /* program vfe_bus_cfg */
282 writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG);
283}
284
285static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in)
286{
287 struct VFE_CAMIFConfigType cfg;
288
289 memset(&cfg, 0, sizeof(cfg));
290
291 cfg.VSyncEdge =
292 in->camifCfgFromCmd.vSyncEdge;
293
294 cfg.HSyncEdge =
295 in->camifCfgFromCmd.hSyncEdge;
296
297 cfg.syncMode =
298 in->camifCfgFromCmd.syncMode;
299
300 cfg.vfeSubsampleEnable =
301 in->camifCfgFromCmd.vfeSubSampleEnable;
302
303 cfg.busSubsampleEnable =
304 in->camifCfgFromCmd.busSubSampleEnable;
305
306 cfg.camif2vfeEnable =
307 in->camif2OutputEnable;
308
309 cfg.camif2busEnable =
310 in->camif2BusEnable;
311
312 cfg.irqSubsampleEnable =
313 in->camifCfgFromCmd.irqSubSampleEnable;
314
315 cfg.binningEnable =
316 in->camifCfgFromCmd.binningEnable;
317
318 cfg.misrEnable =
319 in->camifCfgFromCmd.misrEnable;
320
321 /* program camif_config */
322 writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG);
323}
324
325static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in)
326{
327 struct vfe_buscmd cmd;
328 memset(&cmd, 0, sizeof(cmd));
329
330 cmd.stripeReload = in->stripeReload;
331 cmd.busPingpongReload = in->busPingpongReload;
332 cmd.statsPingpongReload = in->statsPingpongReload;
333
334 writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD);
335
336 CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd)));
337
338 /* this is needed, as the control bits are pulse based.
339 * Don't want to reload bus pingpong again. */
340 in->busPingpongReload = 0;
341 in->statsPingpongReload = 0;
342 in->stripeReload = 0;
343}
344
345static void vfe_reg_module_cfg(struct vfe_module_enable *in)
346{
347 struct vfe_mod_enable ena;
348
349 memset(&ena, 0, sizeof(ena));
350
351 ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable;
352 ena.lensRollOffEnable = in->lensRollOffEnable;
353 ena.demuxEnable = in->demuxEnable;
354 ena.chromaUpsampleEnable = in->chromaUpsampleEnable;
355 ena.demosaicEnable = in->demosaicEnable;
356 ena.statsEnable = in->statsEnable;
357 ena.cropEnable = in->cropEnable;
358 ena.mainScalerEnable = in->mainScalerEnable;
359 ena.whiteBalanceEnable = in->whiteBalanceEnable;
360 ena.colorCorrectionEnable = in->colorCorrectionEnable;
361 ena.yHistEnable = in->yHistEnable;
362 ena.skinToneEnable = in->skinToneEnable;
363 ena.lumaAdaptationEnable = in->lumaAdaptationEnable;
364 ena.rgbLUTEnable = in->rgbLUTEnable;
365 ena.chromaEnhanEnable = in->chromaEnhanEnable;
366 ena.asfEnable = in->asfEnable;
367 ena.chromaSuppressionEnable = in->chromaSuppressionEnable;
368 ena.chromaSubsampleEnable = in->chromaSubsampleEnable;
369 ena.scaler2YEnable = in->scaler2YEnable;
370 ena.scaler2CbcrEnable = in->scaler2CbcrEnable;
371
372 writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG);
373}
374
375static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel)
376{
377 /* set bit 8 for auto increment. */
378 uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT;
379
380 value += (uint32_t)bankSel;
381 /* CDBG("dmi cfg input bank is 0x%x\n", bankSel); */
382
383 writel(value, ctrl->vfebase + VFE_DMI_CFG);
384 writel(0, ctrl->vfebase + VFE_DMI_ADDR);
385}
386
387static void vfe_write_lens_roll_off_table(
388 struct vfe_cmd_roll_off_config *in)
389{
390 uint16_t i;
391 uint32_t data;
392
393 uint16_t *initGr = in->initTableGr;
394 uint16_t *initGb = in->initTableGb;
395 uint16_t *initB = in->initTableB;
396 uint16_t *initR = in->initTableR;
397
398 int16_t *pDeltaGr = in->deltaTableGr;
399 int16_t *pDeltaGb = in->deltaTableGb;
400 int16_t *pDeltaB = in->deltaTableB;
401 int16_t *pDeltaR = in->deltaTableR;
402
403 vfe_program_dmi_cfg(ROLLOFF_RAM);
404
405 /* first pack and write init table */
406 for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) {
407 data = (((uint32_t)(*initR)) & 0x0000FFFF) |
408 (((uint32_t)(*initGr)) << 16);
409 initR++;
410 initGr++;
411
412 writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
413
414 data = (((uint32_t)(*initB)) & 0x0000FFFF) |
415 (((uint32_t)(*initGr))<<16);
416 initB++;
417 initGb++;
418
419 writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
420 }
421
422 /* there are gaps between the init table and delta table,
423 * set the offset for delta table. */
424 writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET,
425 ctrl->vfebase + VFE_DMI_ADDR);
426
427 /* pack and write delta table */
428 for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) {
429 data = (((int32_t)(*pDeltaR)) & 0x0000FFFF) |
430 (((int32_t)(*pDeltaGr))<<16);
431 pDeltaR++;
432 pDeltaGr++;
433
434 writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
435
436 data = (((int32_t)(*pDeltaB)) & 0x0000FFFF) |
437 (((int32_t)(*pDeltaGb))<<16);
438 pDeltaB++;
439 pDeltaGb++;
440
441 writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
442 }
443
444 /* After DMI transfer, to make it safe, need to set the
445 * DMI_CFG to unselect any SRAM
446 */
447 /* unselect the SRAM Bank. */
448 writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
449}
450
451static void vfe_set_default_reg_values(void)
452{
453 writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0);
454 writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1);
455 writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE);
456
457 /* default frame drop period and pattern */
458 writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
459 writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
460 writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
461 writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
462 writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG);
463 writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG);
464 writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
465 writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
466 writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG);
467 writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG);
468}
469
470static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd)
471{
472 writel(period, ctrl->vfebase + VFE_DEMUX_CFG);
473 writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG);
474 writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG);
475}
476
477static void vfe_pm_stop(void)
478{
479 writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD);
480}
481
482static void vfe_program_bus_rd_irq_en(uint32_t value)
483{
484 writel(value, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
485}
486
487static void vfe_camif_go(void)
488{
489 writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
490}
491
492static void vfe_camif_stop_immediately(void)
493{
494 writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND);
495 writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE);
496}
497
498static void vfe_program_reg_update_cmd(uint32_t value)
499{
500 writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD);
501}
502
503static void vfe_program_bus_cmd(uint32_t value)
504{
505 writel(value, ctrl->vfebase + VFE_BUS_CMD);
506}
507
508static void vfe_program_global_reset_cmd(uint32_t value)
509{
510 writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
511}
512
513static void vfe_program_axi_cmd(uint32_t value)
514{
515 writel(value, ctrl->vfebase + VFE_AXI_CMD);
516}
517
518static void vfe_program_irq_composite_mask(uint32_t value)
519{
520 writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
521}
522
523static inline void vfe_program_irq_mask(uint32_t value)
524{
525 writel(value, ctrl->vfebase + VFE_IRQ_MASK);
526}
527
528static void vfe_program_chroma_upsample_cfg(uint32_t value)
529{
530 writel(value, ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
531}
532
533static uint32_t vfe_read_axi_status(void)
534{
535 return readl(ctrl->vfebase + VFE_AXI_STATUS);
536}
537
538static uint32_t vfe_read_pm_status_in_raw_capture(void)
539{
540 return readl(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
541}
542
543static void
544vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl,
545 struct vfe_stats_control *awbControl)
546{
547 afControl->hwRegPingAddress = (uint8_t *)
548 (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
549 afControl->hwRegPongAddress = (uint8_t *)
550 (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
551
552 awbControl->hwRegPingAddress = (uint8_t *)
553 (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
554 awbControl->hwRegPongAddress = (uint8_t *)
555 (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
556}
557
558static uint32_t vfe_read_camif_status(void)
559{
560 return readl(ctrl->vfebase + CAMIF_STATUS);
561}
562
563static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in)
564{
565 struct VFE_GammaLutSelect_ConfigCmdType cmd;
566
567 memset(&cmd, 0, sizeof(cmd));
568
569 cmd.ch0BankSelect = in->ch0BankSelect;
570 cmd.ch1BankSelect = in->ch1BankSelect;
571 cmd.ch2BankSelect = in->ch2BankSelect;
572 CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd));
573 vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL,
574 (uint32_t *)&cmd, sizeof(cmd));
575}
576
577static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in)
578{
579 struct VFE_StatsCmdType stats;
580 memset(&stats, 0, sizeof(stats));
581
582 stats.autoFocusEnable = in->autoFocusEnable;
583 stats.axwEnable = in->axwEnable;
584 stats.histEnable = in->histEnable;
585 stats.clearHistEnable = in->clearHistEnable;
586 stats.histAutoClearEnable = in->histAutoClearEnable;
587 stats.colorConversionEnable = in->colorConversionEnable;
588
589 writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD);
590}
591
592static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in)
593{
594 struct VFE_Bus_Pm_ConfigCmdType cmd;
595 memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType));
596
597 cmd.output2YWrPmEnable = in->output2YWrPmEnable;
598 cmd.output2CbcrWrPmEnable = in->output2CbcrWrPmEnable;
599 cmd.output1YWrPmEnable = in->output1YWrPmEnable;
600 cmd.output1CbcrWrPmEnable = in->output1CbcrWrPmEnable;
601
602 vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG,
603 (uint32_t *)&cmd, sizeof(cmd));
604}
605
606static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in)
607{
608 in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn;
609 in->output1YWrPmEnable = ctrl->vfeBusConfigLocal.viewYWrPathEn;
610 in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn;
611 in->output2YWrPmEnable = ctrl->vfeBusConfigLocal.encYWrPathEn;
612
613 if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable)
614 ctrl->viewPath.pmEnabled = TRUE;
615
616 if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable)
617 ctrl->encPath.pmEnabled = TRUE;
618
619 vfe_pm_start(in);
620
621 writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD);
622}
623
624static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data)
625{
626 struct vfe_irqenable packedData;
627
628 memset(&packedData, 0, sizeof(packedData));
629
630 packedData.camifErrorIrq = data.camifErrorIrq;
631 packedData.camifSofIrq = data.camifSofIrq;
632 packedData.camifEolIrq = data.camifEolIrq;
633 packedData.camifEofIrq = data.camifEofIrq;
634 packedData.camifEpoch1Irq = data.camifEpoch1Irq;
635 packedData.camifEpoch2Irq = data.camifEpoch2Irq;
636 packedData.camifOverflowIrq = data.camifOverflowIrq;
637 packedData.ceIrq = data.ceIrq;
638 packedData.regUpdateIrq = data.regUpdateIrq;
639 packedData.resetAckIrq = data.resetAckIrq;
640 packedData.encYPingpongIrq = data.encYPingpongIrq;
641 packedData.encCbcrPingpongIrq = data.encCbcrPingpongIrq;
642 packedData.viewYPingpongIrq = data.viewYPingpongIrq;
643 packedData.viewCbcrPingpongIrq = data.viewCbcrPingpongIrq;
644 packedData.rdPingpongIrq = data.rdPingpongIrq;
645 packedData.afPingpongIrq = data.afPingpongIrq;
646 packedData.awbPingpongIrq = data.awbPingpongIrq;
647 packedData.histPingpongIrq = data.histPingpongIrq;
648 packedData.encIrq = data.encIrq;
649 packedData.viewIrq = data.viewIrq;
650 packedData.busOverflowIrq = data.busOverflowIrq;
651 packedData.afOverflowIrq = data.afOverflowIrq;
652 packedData.awbOverflowIrq = data.awbOverflowIrq;
653 packedData.syncTimer0Irq = data.syncTimer0Irq;
654 packedData.syncTimer1Irq = data.syncTimer1Irq;
655 packedData.syncTimer2Irq = data.syncTimer2Irq;
656 packedData.asyncTimer0Irq = data.asyncTimer0Irq;
657 packedData.asyncTimer1Irq = data.asyncTimer1Irq;
658 packedData.asyncTimer2Irq = data.asyncTimer2Irq;
659 packedData.asyncTimer3Irq = data.asyncTimer3Irq;
660 packedData.axiErrorIrq = data.axiErrorIrq;
661 packedData.violationIrq = data.violationIrq;
662
663 return *((uint32_t *)&packedData);
664}
665
666static uint32_t
667vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data)
668{
669 struct VFE_Irq_Composite_MaskType packedData;
670
671 memset(&packedData, 0, sizeof(packedData));
672
673 packedData.encIrqComMaskBits = data.encIrqComMask;
674 packedData.viewIrqComMaskBits = data.viewIrqComMask;
675 packedData.ceDoneSelBits = data.ceDoneSel;
676
677 return *((uint32_t *)&packedData);
678}
679
680static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
681 enum vfe_resp_msg type, void *data, void **ext, int32_t *elen)
682{
683 switch (type) {
684 case VFE_MSG_OUTPUT1: {
685 pinfo->y_phy =
686 ((struct vfe_message *)data)->_u.msgOutput1.yBuffer;
687 pinfo->cbcr_phy =
688 ((struct vfe_message *)data)->_u.msgOutput1.cbcrBuffer;
689
690 ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
691 ((struct vfe_message *)data)->_u.msgOutput1.bpcInfo;
692
693 ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
694 ((struct vfe_message *)data)->_u.msgOutput1.asfInfo;
695
696 ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
697 ((struct vfe_message *)data)->_u.msgOutput1.frameCounter;
698
699 ((struct vfe_frame_extra *)ctrl->extdata)->pmData =
700 ((struct vfe_message *)data)->_u.msgOutput1.pmData;
701
702 *ext = ctrl->extdata;
703 *elen = ctrl->extlen;
704 }
705 break;
706
707 case VFE_MSG_OUTPUT2: {
708 pinfo->y_phy =
709 ((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
710 pinfo->cbcr_phy =
711 ((struct vfe_message *)data)->_u.msgOutput2.cbcrBuffer;
712
713 CDBG("vfe_addr_convert, pinfo->y_phy = 0x%x\n", pinfo->y_phy);
714 CDBG("vfe_addr_convert, pinfo->cbcr_phy = 0x%x\n",
715 pinfo->cbcr_phy);
716
717 ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
718 ((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
719
720 ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
721 ((struct vfe_message *)data)->_u.msgOutput2.asfInfo;
722
723 ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
724 ((struct vfe_message *)data)->_u.msgOutput2.frameCounter;
725
726 ((struct vfe_frame_extra *)ctrl->extdata)->pmData =
727 ((struct vfe_message *)data)->_u.msgOutput2.pmData;
728
729 *ext = ctrl->extdata;
730 *elen = ctrl->extlen;
731 }
732 break;
733
734 case VFE_MSG_STATS_AF:
735 pinfo->sbuf_phy =
736 ((struct vfe_message *)data)->_u.msgStatsAf.afBuffer;
737 break;
738
739 case VFE_MSG_STATS_WE:
740 pinfo->sbuf_phy =
741 ((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer;
742 break;
743
744 default:
745 break;
746 } /* switch */
747}
748
749static void
750vfe_proc_ops(enum VFE_MESSAGE_ID id, void *msg, size_t len)
751{
752 struct msm_vfe_resp *rp;
753
754 /* In 8k, OUTPUT1 & OUTPUT2 messages arrive before
755 * SNAPSHOT_DONE. We don't send such messages to user */
756
757 CDBG("ctrl->vfeOperationMode = %d, msgId = %d\n",
758 ctrl->vfeOperationMode, id);
759
760 if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) &&
761 (id == VFE_MSG_ID_OUTPUT1 || id == VFE_MSG_ID_OUTPUT2)) {
762 return;
763 }
764
765 rp = ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp), ctrl->syncdata);
766 if (!rp) {
767 CDBG("rp: cannot allocate buffer\n");
768 return;
769 }
770
771 CDBG("vfe_proc_ops, msgId = %d\n", id);
772
773 rp->evt_msg.type = MSM_CAMERA_MSG;
774 rp->evt_msg.msg_id = id;
775 rp->evt_msg.len = len;
776 rp->evt_msg.data = msg;
777
778 switch (rp->evt_msg.msg_id) {
779 case VFE_MSG_ID_SNAPSHOT_DONE:
780 rp->type = VFE_MSG_SNAPSHOT;
781 break;
782
783 case VFE_MSG_ID_OUTPUT1:
784 rp->type = VFE_MSG_OUTPUT1;
785 vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT1,
786 rp->evt_msg.data, &(rp->extdata),
787 &(rp->extlen));
788 break;
789
790 case VFE_MSG_ID_OUTPUT2:
791 rp->type = VFE_MSG_OUTPUT2;
792 vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT2,
793 rp->evt_msg.data, &(rp->extdata),
794 &(rp->extlen));
795 break;
796
797 case VFE_MSG_ID_STATS_AUTOFOCUS:
798 rp->type = VFE_MSG_STATS_AF;
799 vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_AF,
800 rp->evt_msg.data, NULL, NULL);
801 break;
802
803 case VFE_MSG_ID_STATS_WB_EXP:
804 rp->type = VFE_MSG_STATS_WE;
805 vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_WE,
806 rp->evt_msg.data, NULL, NULL);
807 break;
808
809 default:
810 rp->type = VFE_MSG_GENERAL;
811 break;
812 }
813
814 ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata);
815}
816
817static void vfe_send_msg_no_payload(enum VFE_MESSAGE_ID id)
818{
819 struct vfe_message *msg;
820
821 msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
822 if (!msg)
823 return;
824
825 msg->_d = id;
826 vfe_proc_ops(id, msg, 0);
827}
828
829static void vfe_send_bus_overflow_msg(void)
830{
831 struct vfe_message *msg;
832 msg =
833 kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
834 if (!msg)
835 return;
836
837 msg->_d = VFE_MSG_ID_BUS_OVERFLOW;
838#if 0
839 memcpy(&(msg->_u.msgBusOverflow),
840 &ctrl->vfePmData, sizeof(ctrl->vfePmData));
841#endif
842
843 vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW,
844 msg, sizeof(struct vfe_message));
845}
846
847static void vfe_send_camif_error_msg(void)
848{
849#if 0
850 struct vfe_message *msg;
851 msg =
852 kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
853 if (!msg)
854 return;
855
856 msg->_d = VFE_MSG_ID_CAMIF_ERROR;
857 memcpy(&(msg->_u.msgCamifError),
858 &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal));
859
860 vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR,
861 msg, sizeof(struct vfe_message));
862#endif
863}
864
865static void vfe_process_error_irq(
866 struct vfe_interrupt_status *irqstatus)
867{
868 /* all possible error irq. Note error irqs are not enabled, it is
869 * checked only when other interrupts are present. */
870 if (irqstatus->afOverflowIrq)
871 vfe_send_msg_no_payload(VFE_MSG_ID_AF_OVERFLOW);
872
873 if (irqstatus->awbOverflowIrq)
874 vfe_send_msg_no_payload(VFE_MSG_ID_AWB_OVERFLOW);
875
876 if (irqstatus->axiErrorIrq)
877 vfe_send_msg_no_payload(VFE_MSG_ID_AXI_ERROR);
878
879 if (irqstatus->busOverflowIrq)
880 vfe_send_bus_overflow_msg();
881
882 if (irqstatus->camifErrorIrq)
883 vfe_send_camif_error_msg();
884
885 if (irqstatus->camifOverflowIrq)
886 vfe_send_msg_no_payload(VFE_MSG_ID_CAMIF_OVERFLOW);
887
888 if (irqstatus->violationIrq)
889 ;
890}
891
892static void vfe_process_camif_sof_irq(void)
893{
894 /* increment the frame id number. */
895 ctrl->vfeFrameId++;
896
897 CDBG("camif_sof_irq, frameId = %d\n",
898 ctrl->vfeFrameId);
899
900 /* In snapshot mode, if frame skip is programmed,
901 * need to check it accordingly to stop camif at
902 * correct frame boundary. For the dropped frames,
903 * there won't be any output path irqs, but there is
904 * still SOF irq, which can help us determine when
905 * to stop the camif.
906 */
907 if (ctrl->vfeOperationMode) {
908 if ((1 << ctrl->vfeFrameSkipCount) &
909 ctrl->vfeFrameSkipPattern) {
910
911 ctrl->vfeSnapShotCount--;
912 if (ctrl->vfeSnapShotCount == 0)
913 /* terminate vfe pipeline at frame boundary. */
914 writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
915 ctrl->vfebase + CAMIF_COMMAND);
916 }
917
918 /* update frame skip counter for bit checking. */
919 ctrl->vfeFrameSkipCount++;
920 if (ctrl->vfeFrameSkipCount ==
921 (ctrl->vfeFrameSkipPeriod + 1))
922 ctrl->vfeFrameSkipCount = 0;
923 }
924}
925
926static int vfe_get_af_pingpong_status(void)
927{
928 uint32_t busPingPongStatus;
929 int rc = 0;
930
931 busPingPongStatus =
932 readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
933
934 if ((busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT) == 0)
935 return -EFAULT;
936
937 return rc;
938}
939
940static uint32_t vfe_read_af_buf_addr(boolean pipo)
941{
942 if (pipo == FALSE)
943 return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
944 else
945 return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
946}
947
948static void
949vfe_update_af_buf_addr(boolean pipo, uint32_t addr)
950{
951 if (pipo == FALSE)
952 writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
953 else
954 writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
955}
956
957static void
958vfe_send_af_stats_msg(uint32_t afBufAddress)
959{
960 /* unsigned long flags; */
961 struct vfe_message *msg;
962 msg =
963 kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
964 if (!msg)
965 return;
966
967 /* fill message with right content. */
968 /* @todo This is causing issues, need further investigate */
969 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
970 if (ctrl->vstate != VFE_STATE_ACTIVE) {
971 kfree(msg);
972 goto af_stats_done;
973 }
974
975 msg->_d = VFE_MSG_ID_STATS_AUTOFOCUS;
976 msg->_u.msgStatsAf.afBuffer = afBufAddress;
977 msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId;
978
979 vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS,
980 msg, sizeof(struct vfe_message));
981
982 ctrl->afStatsControl.ackPending = TRUE;
983
984af_stats_done:
985 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
986 return;
987}
988
989static void vfe_process_stats_af_irq(void)
990{
991 boolean bufferAvailable;
992
993 if (!(ctrl->afStatsControl.ackPending)) {
994
995 /* read hardware status. */
996 ctrl->afStatsControl.pingPongStatus =
997 vfe_get_af_pingpong_status();
998
999 bufferAvailable =
1000 (ctrl->afStatsControl.pingPongStatus) ^ 1;
1001
1002 ctrl->afStatsControl.bufToRender =
1003 vfe_read_af_buf_addr(bufferAvailable);
1004
1005 /* update the same buffer address (ping or pong) */
1006 vfe_update_af_buf_addr(bufferAvailable,
1007 ctrl->afStatsControl.nextFrameAddrBuf);
1008
1009 vfe_send_af_stats_msg(ctrl->afStatsControl.bufToRender);
1010 } else
1011 ctrl->afStatsControl.droppedStatsFrameCount++;
1012}
1013
1014static boolean vfe_get_awb_pingpong_status(void)
1015{
1016 uint32_t busPingPongStatus;
1017
1018 busPingPongStatus =
1019 readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
1020
1021 if ((busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT) == 0)
1022 return FALSE;
1023
1024 return TRUE;
1025}
1026
1027static uint32_t
1028vfe_read_awb_buf_addr(boolean pingpong)
1029{
1030 if (pingpong == FALSE)
1031 return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
1032 else
1033 return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
1034}
1035
1036static void vfe_update_awb_buf_addr(
1037 boolean pingpong, uint32_t addr)
1038{
1039 if (pingpong == FALSE)
1040 writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
1041 else
1042 writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
1043}
1044
1045static void vfe_send_awb_stats_msg(uint32_t awbBufAddress)
1046{
1047 /* unsigned long flags; */
1048 struct vfe_message *msg;
1049
1050 msg =
1051 kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
1052 if (!msg)
1053 return;
1054
1055 /* fill message with right content. */
1056 /* @todo This is causing issues, need further investigate */
1057 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
1058 if (ctrl->vstate != VFE_STATE_ACTIVE) {
1059 kfree(msg);
1060 goto awb_stats_done;
1061 }
1062
1063 msg->_d = VFE_MSG_ID_STATS_WB_EXP;
1064 msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress;
1065 msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId;
1066
1067 vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP,
1068 msg, sizeof(struct vfe_message));
1069
1070 ctrl->awbStatsControl.ackPending = TRUE;
1071
1072awb_stats_done:
1073 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
1074 return;
1075}
1076
1077static void vfe_process_stats_awb_irq(void)
1078{
1079 boolean bufferAvailable;
1080
1081 if (!(ctrl->awbStatsControl.ackPending)) {
1082
1083 ctrl->awbStatsControl.pingPongStatus =
1084 vfe_get_awb_pingpong_status();
1085
1086 bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1;
1087
1088 ctrl->awbStatsControl.bufToRender =
1089 vfe_read_awb_buf_addr(bufferAvailable);
1090
1091 vfe_update_awb_buf_addr(bufferAvailable,
1092 ctrl->awbStatsControl.nextFrameAddrBuf);
1093
1094 vfe_send_awb_stats_msg(ctrl->awbStatsControl.bufToRender);
1095
1096 } else
1097 ctrl->awbStatsControl.droppedStatsFrameCount++;
1098}
1099
1100static void vfe_process_sync_timer_irq(
1101 struct vfe_interrupt_status *irqstatus)
1102{
1103 if (irqstatus->syncTimer0Irq)
1104 vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER0_DONE);
1105
1106 if (irqstatus->syncTimer1Irq)
1107 vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER1_DONE);
1108
1109 if (irqstatus->syncTimer2Irq)
1110 vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER2_DONE);
1111}
1112
1113static void vfe_process_async_timer_irq(
1114 struct vfe_interrupt_status *irqstatus)
1115{
1116
1117 if (irqstatus->asyncTimer0Irq)
1118 vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
1119
1120 if (irqstatus->asyncTimer1Irq)
1121 vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER1_DONE);
1122
1123 if (irqstatus->asyncTimer2Irq)
1124 vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER2_DONE);
1125
1126 if (irqstatus->asyncTimer3Irq)
1127 vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER3_DONE);
1128}
1129
1130static void vfe_send_violation_msg(void)
1131{
1132 vfe_send_msg_no_payload(VFE_MSG_ID_VIOLATION);
1133}
1134
1135static void vfe_send_async_timer_msg(void)
1136{
1137 vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
1138}
1139
1140static void vfe_write_gamma_table(uint8_t channel,
1141 boolean bank, int16_t *pTable)
1142{
1143 uint16_t i;
1144
1145 enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED;
1146
1147 switch (channel) {
1148 case 0:
1149 if (bank == 0)
1150 dmiRamSel = RGBLUT_RAM_CH0_BANK0;
1151 else
1152 dmiRamSel = RGBLUT_RAM_CH0_BANK1;
1153 break;
1154
1155 case 1:
1156 if (bank == 0)
1157 dmiRamSel = RGBLUT_RAM_CH1_BANK0;
1158 else
1159 dmiRamSel = RGBLUT_RAM_CH1_BANK1;
1160 break;
1161
1162 case 2:
1163 if (bank == 0)
1164 dmiRamSel = RGBLUT_RAM_CH2_BANK0;
1165 else
1166 dmiRamSel = RGBLUT_RAM_CH2_BANK1;
1167 break;
1168
1169 default:
1170 break;
1171 }
1172
1173 vfe_program_dmi_cfg(dmiRamSel);
1174
1175 for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) {
1176 writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
1177 pTable++;
1178 }
1179
1180 /* After DMI transfer, need to set the DMI_CFG to unselect any SRAM
1181 unselect the SRAM Bank. */
1182 writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
1183}
1184
1185static void vfe_prog_hw_testgen_cmd(uint32_t value)
1186{
1187 writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD);
1188}
1189
1190static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out)
1191{
1192 uint32_t *temp;
1193
1194 memset(out, 0, sizeof(struct vfe_irq_thread_msg));
1195
1196 temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS);
1197 out->vfeIrqStatus = readl(temp);
1198
1199 temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS);
1200 out->camifStatus = readl(temp);
1201 writel(0x7, ctrl->vfebase + CAMIF_COMMAND);
1202 writel(0x3, ctrl->vfebase + CAMIF_COMMAND);
1203 CDBG("camifStatus = 0x%x\n", out->camifStatus);
1204
1205/*
1206 temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS);
1207 out->demosaicStatus = readl(temp);
1208
1209 temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE);
1210 out->asfMaxEdge = readl(temp);
1211
1212 temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0);
1213*/
1214
1215#if 0
1216 out->pmInfo.encPathPmInfo.yWrPmStats0 = readl(temp++);
1217 out->pmInfo.encPathPmInfo.yWrPmStats1 = readl(temp++);
1218 out->pmInfo.encPathPmInfo.cbcrWrPmStats0 = readl(temp++);
1219 out->pmInfo.encPathPmInfo.cbcrWrPmStats1 = readl(temp++);
1220 out->pmInfo.viewPathPmInfo.yWrPmStats0 = readl(temp++);
1221 out->pmInfo.viewPathPmInfo.yWrPmStats1 = readl(temp++);
1222 out->pmInfo.viewPathPmInfo.cbcrWrPmStats0 = readl(temp++);
1223 out->pmInfo.viewPathPmInfo.cbcrWrPmStats1 = readl(temp);
1224#endif /* if 0 Jeff */
1225}
1226
1227static struct vfe_interrupt_status
1228vfe_parse_interrupt_status(uint32_t irqStatusIn)
1229{
1230 struct vfe_irqenable hwstat;
1231 struct vfe_interrupt_status ret;
1232 boolean temp;
1233
1234 memset(&hwstat, 0, sizeof(hwstat));
1235 memset(&ret, 0, sizeof(ret));
1236
1237 hwstat = *((struct vfe_irqenable *)(&irqStatusIn));
1238
1239 ret.camifErrorIrq = hwstat.camifErrorIrq;
1240 ret.camifSofIrq = hwstat.camifSofIrq;
1241 ret.camifEolIrq = hwstat.camifEolIrq;
1242 ret.camifEofIrq = hwstat.camifEofIrq;
1243 ret.camifEpoch1Irq = hwstat.camifEpoch1Irq;
1244 ret.camifEpoch2Irq = hwstat.camifEpoch2Irq;
1245 ret.camifOverflowIrq = hwstat.camifOverflowIrq;
1246 ret.ceIrq = hwstat.ceIrq;
1247 ret.regUpdateIrq = hwstat.regUpdateIrq;
1248 ret.resetAckIrq = hwstat.resetAckIrq;
1249 ret.encYPingpongIrq = hwstat.encYPingpongIrq;
1250 ret.encCbcrPingpongIrq = hwstat.encCbcrPingpongIrq;
1251 ret.viewYPingpongIrq = hwstat.viewYPingpongIrq;
1252 ret.viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq;
1253 ret.rdPingpongIrq = hwstat.rdPingpongIrq;
1254 ret.afPingpongIrq = hwstat.afPingpongIrq;
1255 ret.awbPingpongIrq = hwstat.awbPingpongIrq;
1256 ret.histPingpongIrq = hwstat.histPingpongIrq;
1257 ret.encIrq = hwstat.encIrq;
1258 ret.viewIrq = hwstat.viewIrq;
1259 ret.busOverflowIrq = hwstat.busOverflowIrq;
1260 ret.afOverflowIrq = hwstat.afOverflowIrq;
1261 ret.awbOverflowIrq = hwstat.awbOverflowIrq;
1262 ret.syncTimer0Irq = hwstat.syncTimer0Irq;
1263 ret.syncTimer1Irq = hwstat.syncTimer1Irq;
1264 ret.syncTimer2Irq = hwstat.syncTimer2Irq;
1265 ret.asyncTimer0Irq = hwstat.asyncTimer0Irq;
1266 ret.asyncTimer1Irq = hwstat.asyncTimer1Irq;
1267 ret.asyncTimer2Irq = hwstat.asyncTimer2Irq;
1268 ret.asyncTimer3Irq = hwstat.asyncTimer3Irq;
1269 ret.axiErrorIrq = hwstat.axiErrorIrq;
1270 ret.violationIrq = hwstat.violationIrq;
1271
1272 /* logic OR of any error bits
1273 * although each irq corresponds to a bit, the data type here is a
1274 * boolean already. hence use logic operation.
1275 */
1276 temp =
1277 ret.camifErrorIrq ||
1278 ret.camifOverflowIrq ||
1279 ret.afOverflowIrq ||
1280 ret.awbPingpongIrq ||
1281 ret.busOverflowIrq ||
1282 ret.axiErrorIrq ||
1283 ret.violationIrq;
1284
1285 ret.anyErrorIrqs = temp;
1286
1287 /* logic OR of any output path bits*/
1288 temp =
1289 ret.encYPingpongIrq ||
1290 ret.encCbcrPingpongIrq ||
1291 ret.encIrq;
1292
1293 ret.anyOutput2PathIrqs = temp;
1294
1295 temp =
1296 ret.viewYPingpongIrq ||
1297 ret.viewCbcrPingpongIrq ||
1298 ret.viewIrq;
1299
1300 ret.anyOutput1PathIrqs = temp;
1301
1302 ret.anyOutputPathIrqs =
1303 ret.anyOutput1PathIrqs ||
1304 ret.anyOutput2PathIrqs;
1305
1306 /* logic OR of any sync timer bits*/
1307 temp =
1308 ret.syncTimer0Irq ||
1309 ret.syncTimer1Irq ||
1310 ret.syncTimer2Irq;
1311
1312 ret.anySyncTimerIrqs = temp;
1313
1314 /* logic OR of any async timer bits*/
1315 temp =
1316 ret.asyncTimer0Irq ||
1317 ret.asyncTimer1Irq ||
1318 ret.asyncTimer2Irq ||
1319 ret.asyncTimer3Irq;
1320
1321 ret.anyAsyncTimerIrqs = temp;
1322
1323 /* bool for all interrupts that are not allowed in idle state */
1324 temp =
1325 ret.anyErrorIrqs ||
1326 ret.anyOutputPathIrqs ||
1327 ret.anySyncTimerIrqs ||
1328 ret.regUpdateIrq ||
1329 ret.awbPingpongIrq ||
1330 ret.afPingpongIrq ||
1331 ret.camifSofIrq ||
1332 ret.camifEpoch2Irq ||
1333 ret.camifEpoch1Irq;
1334
1335 ret.anyIrqForActiveStatesOnly =
1336 temp;
1337
1338 return ret;
1339}
1340
1341static struct vfe_frame_asf_info
1342vfe_get_asf_frame_info(struct vfe_irq_thread_msg *in)
1343{
1344 struct vfe_asf_info asfInfoTemp;
1345 struct vfe_frame_asf_info rc;
1346
1347 memset(&rc, 0, sizeof(rc));
1348 memset(&asfInfoTemp, 0, sizeof(asfInfoTemp));
1349
1350 asfInfoTemp =
1351 *((struct vfe_asf_info *)(&(in->asfMaxEdge)));
1352
1353 rc.asfHbiCount = asfInfoTemp.HBICount;
1354 rc.asfMaxEdge = asfInfoTemp.maxEdge;
1355
1356 return rc;
1357}
1358
1359static struct vfe_frame_bpc_info
1360vfe_get_demosaic_frame_info(struct vfe_irq_thread_msg *in)
1361{
1362 struct vfe_bps_info bpcInfoTemp;
1363 struct vfe_frame_bpc_info rc;
1364
1365 memset(&rc, 0, sizeof(rc));
1366 memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp));
1367
1368 bpcInfoTemp =
1369 *((struct vfe_bps_info *)(&(in->demosaicStatus)));
1370
1371 rc.greenDefectPixelCount =
1372 bpcInfoTemp.greenBadPixelCount;
1373
1374 rc.redBlueDefectPixelCount =
1375 bpcInfoTemp.RedBlueBadPixelCount;
1376
1377 return rc;
1378}
1379
1380static struct vfe_msg_camif_status
1381vfe_get_camif_status(struct vfe_irq_thread_msg *in)
1382{
1383 struct vfe_camif_stats camifStatusTemp;
1384 struct vfe_msg_camif_status rc;
1385
1386 memset(&rc, 0, sizeof(rc));
1387 memset(&camifStatusTemp, 0, sizeof(camifStatusTemp));
1388
1389 camifStatusTemp =
1390 *((struct vfe_camif_stats *)(&(in->camifStatus)));
1391
1392 rc.camifState = (boolean)camifStatusTemp.camifHalt;
1393 rc.lineCount = camifStatusTemp.lineCount;
1394 rc.pixelCount = camifStatusTemp.pixelCount;
1395
1396 return rc;
1397}
1398
1399static struct vfe_bus_performance_monitor
1400vfe_get_performance_monitor_data(struct vfe_irq_thread_msg *in)
1401{
1402 struct vfe_bus_performance_monitor rc;
1403 memset(&rc, 0, sizeof(rc));
1404
1405 rc.encPathPmInfo.yWrPmStats0 =
1406 in->pmInfo.encPathPmInfo.yWrPmStats0;
1407 rc.encPathPmInfo.yWrPmStats1 =
1408 in->pmInfo.encPathPmInfo.yWrPmStats1;
1409 rc.encPathPmInfo.cbcrWrPmStats0 =
1410 in->pmInfo.encPathPmInfo.cbcrWrPmStats0;
1411 rc.encPathPmInfo.cbcrWrPmStats1 =
1412 in->pmInfo.encPathPmInfo.cbcrWrPmStats1;
1413 rc.viewPathPmInfo.yWrPmStats0 =
1414 in->pmInfo.viewPathPmInfo.yWrPmStats0;
1415 rc.viewPathPmInfo.yWrPmStats1 =
1416 in->pmInfo.viewPathPmInfo.yWrPmStats1;
1417 rc.viewPathPmInfo.cbcrWrPmStats0 =
1418 in->pmInfo.viewPathPmInfo.cbcrWrPmStats0;
1419 rc.viewPathPmInfo.cbcrWrPmStats1 =
1420 in->pmInfo.viewPathPmInfo.cbcrWrPmStats1;
1421
1422 return rc;
1423}
1424
1425static void vfe_process_reg_update_irq(void)
1426{
1427 CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n",
1428 ctrl->vfeStartAckPendingFlag);
1429 if (ctrl->vfeStartAckPendingFlag == TRUE) {
1430 vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
1431 ctrl->vfeStartAckPendingFlag = FALSE;
1432 } else
1433 vfe_send_msg_no_payload(VFE_MSG_ID_UPDATE_ACK);
1434}
1435
1436static void vfe_process_reset_irq(void)
1437{
1438 /* unsigned long flags; */
1439
1440 /* @todo This is causing issues, need further investigate */
1441 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
1442 ctrl->vstate = VFE_STATE_IDLE;
1443 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
1444
1445 if (ctrl->vfeStopAckPending == TRUE) {
1446 ctrl->vfeStopAckPending = FALSE;
1447 vfe_send_msg_no_payload(VFE_MSG_ID_STOP_ACK);
1448 } else {
1449 vfe_set_default_reg_values();
1450 vfe_send_msg_no_payload(VFE_MSG_ID_RESET_ACK);
1451 }
1452}
1453
1454static void vfe_process_pingpong_irq(struct vfe_output_path *in,
1455 uint8_t fragmentCount)
1456{
1457 uint16_t circularIndex;
1458 uint32_t nextFragmentAddr;
1459
1460 /* get next fragment address from circular buffer */
1461 circularIndex = (in->fragIndex) % (2 * fragmentCount);
1462 nextFragmentAddr = in->addressBuffer[circularIndex];
1463
1464 in->fragIndex = circularIndex + 1;
1465
1466 /* use next fragment to program hardware ping/pong address. */
1467 if (in->hwCurrentFlag == ping) {
1468 writel(nextFragmentAddr, in->hwRegPingAddress);
1469 in->hwCurrentFlag = pong;
1470
1471 } else {
1472 writel(nextFragmentAddr, in->hwRegPongAddress);
1473 in->hwCurrentFlag = ping;
1474 }
1475}
1476
1477static void vfe_send_output2_msg(
1478 struct vfe_msg_output *pPayload)
1479{
1480 /* unsigned long flags; */
1481 struct vfe_message *msg;
1482
1483 msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
1484 if (!msg)
1485 return;
1486
1487 /* fill message with right content. */
1488 /* @todo This is causing issues, need further investigate */
1489 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
1490 if (ctrl->vstate != VFE_STATE_ACTIVE) {
1491 kfree(msg);
1492 goto output2_msg_done;
1493 }
1494
1495 msg->_d = VFE_MSG_ID_OUTPUT2;
1496
1497 memcpy(&(msg->_u.msgOutput2),
1498 (void *)pPayload, sizeof(struct vfe_msg_output));
1499
1500 vfe_proc_ops(VFE_MSG_ID_OUTPUT2,
1501 msg, sizeof(struct vfe_message));
1502
1503 ctrl->encPath.ackPending = TRUE;
1504
1505 if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
1506 (ctrl->vfeOperationMode ==
1507 VFE_START_OPERATION_MODE_SNAPSHOT))
1508 ctrl->encPath.ackPending = TRUE;
1509
1510output2_msg_done:
1511 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
1512 return;
1513}
1514
1515static void vfe_send_output1_msg(
1516 struct vfe_msg_output *pPayload)
1517{
1518 /* unsigned long flags; */
1519 struct vfe_message *msg;
1520
1521 msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
1522 if (!msg)
1523 return;
1524
1525 /* @todo This is causing issues, need further investigate */
1526 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
1527 if (ctrl->vstate != VFE_STATE_ACTIVE) {
1528 kfree(msg);
1529 goto output1_msg_done;
1530 }
1531
1532 msg->_d = VFE_MSG_ID_OUTPUT1;
1533 memmove(&(msg->_u),
1534 (void *)pPayload, sizeof(struct vfe_msg_output));
1535
1536 vfe_proc_ops(VFE_MSG_ID_OUTPUT1,
1537 msg, sizeof(struct vfe_message));
1538
1539 ctrl->viewPath.ackPending = TRUE;
1540
1541 if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
1542 (ctrl->vfeOperationMode ==
1543 VFE_START_OPERATION_MODE_SNAPSHOT))
1544 ctrl->viewPath.ackPending = TRUE;
1545
1546output1_msg_done:
1547 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
1548 return;
1549}
1550
1551static void vfe_send_output_msg(boolean whichOutputPath,
1552 uint32_t yPathAddr, uint32_t cbcrPathAddr)
1553{
1554 struct vfe_msg_output msgPayload;
1555
1556 msgPayload.yBuffer = yPathAddr;
1557 msgPayload.cbcrBuffer = cbcrPathAddr;
1558
1559 /* asf info is common for both output1 and output2 */
1560#if 0
1561 msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount;
1562 msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge;
1563
1564 /* demosaic info is common for both output1 and output2 */
1565 msgPayload.bpcInfo.greenDefectPixelCount =
1566 ctrl->vfeBpcFrameInfo.greenDefectPixelCount;
1567 msgPayload.bpcInfo.redBlueDefectPixelCount =
1568 ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount;
1569#endif /* if 0 */
1570
1571 /* frame ID is common for both paths. */
1572 msgPayload.frameCounter = ctrl->vfeFrameId;
1573
1574 if (whichOutputPath) {
1575 /* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */
1576 vfe_send_output2_msg(&msgPayload);
1577 } else {
1578 /* msgPayload.pmData = ctrl->vfePmData.viewPathPmInfo; */
1579 vfe_send_output1_msg(&msgPayload);
1580 }
1581}
1582
1583static void vfe_process_frame_done_irq_multi_frag(
1584 struct vfe_output_path_combo *in)
1585{
1586 uint32_t yAddress, cbcrAddress;
1587 uint16_t idx;
1588 uint32_t *ptrY;
1589 uint32_t *ptrCbcr;
1590 const uint32_t *ptrSrc;
1591 uint8_t i;
1592
1593 if (!in->ackPending) {
1594
1595 idx = (in->currentFrame) * (in->fragCount);
1596
1597 /* Send output message. */
1598 yAddress = in->yPath.addressBuffer[idx];
1599 cbcrAddress = in->cbcrPath.addressBuffer[idx];
1600
1601 /* copy next frame to current frame. */
1602 ptrSrc = in->nextFrameAddrBuf;
1603 ptrY = (uint32_t *)&(in->yPath.addressBuffer[idx]);
1604 ptrCbcr = (uint32_t *)&(in->cbcrPath.addressBuffer[idx]);
1605
1606 /* Copy Y address */
1607 for (i = 0; i < in->fragCount; i++)
1608 *ptrY++ = *ptrSrc++;
1609
1610 /* Copy Cbcr address */
1611 for (i = 0; i < in->fragCount; i++)
1612 *ptrCbcr++ = *ptrSrc++;
1613
1614 vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress);
1615
1616 } else {
1617 if (in->whichOutputPath == 0)
1618 ctrl->vfeDroppedFrameCounts.output1Count++;
1619
1620 if (in->whichOutputPath == 1)
1621 ctrl->vfeDroppedFrameCounts.output2Count++;
1622 }
1623
1624 /* toggle current frame. */
1625 in->currentFrame = in->currentFrame^1;
1626
1627 if (ctrl->vfeOperationMode)
1628 in->snapshotPendingCount--;
1629}
1630
1631static void vfe_process_frame_done_irq_no_frag_io(
1632 struct vfe_output_path_combo *in, uint32_t *pNextAddr,
1633 uint32_t *pdestRenderAddr)
1634{
1635 uint32_t busPingPongStatus;
1636 uint32_t tempAddress;
1637
1638 /* 1. read hw status register. */
1639 busPingPongStatus =
1640 readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
1641
1642 CDBG("hardware status is 0x%x\n", busPingPongStatus);
1643
1644 /* 2. determine ping or pong */
1645 /* use cbcr status */
1646 busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit));
1647
1648 /* 3. read out address and update address */
1649 if (busPingPongStatus == 0) {
1650 /* hw is working on ping, render pong buffer */
1651 /* a. read out pong address */
1652 /* read out y address. */
1653 tempAddress = readl(in->yPath.hwRegPongAddress);
1654
1655 CDBG("pong 1 addr = 0x%x\n", tempAddress);
1656 *pdestRenderAddr++ = tempAddress;
1657 /* read out cbcr address. */
1658 tempAddress = readl(in->cbcrPath.hwRegPongAddress);
1659
1660 CDBG("pong 2 addr = 0x%x\n", tempAddress);
1661 *pdestRenderAddr = tempAddress;
1662
1663 /* b. update pong address */
1664 writel(*pNextAddr++, in->yPath.hwRegPongAddress);
1665 writel(*pNextAddr, in->cbcrPath.hwRegPongAddress);
1666 } else {
1667 /* hw is working on pong, render ping buffer */
1668
1669 /* a. read out ping address */
1670 tempAddress = readl(in->yPath.hwRegPingAddress);
1671 CDBG("ping 1 addr = 0x%x\n", tempAddress);
1672 *pdestRenderAddr++ = tempAddress;
1673 tempAddress = readl(in->cbcrPath.hwRegPingAddress);
1674
1675 CDBG("ping 2 addr = 0x%x\n", tempAddress);
1676 *pdestRenderAddr = tempAddress;
1677
1678 /* b. update ping address */
1679 writel(*pNextAddr++, in->yPath.hwRegPingAddress);
1680 CDBG("NextAddress = 0x%x\n", *pNextAddr);
1681 writel(*pNextAddr, in->cbcrPath.hwRegPingAddress);
1682 }
1683}
1684
1685static void vfe_process_frame_done_irq_no_frag(
1686 struct vfe_output_path_combo *in)
1687{
1688 uint32_t addressToRender[2];
1689 static uint32_t fcnt;
1690
1691 if (fcnt++ < 3)
1692 return;
1693
1694 if (!in->ackPending) {
1695 vfe_process_frame_done_irq_no_frag_io(in,
1696 in->nextFrameAddrBuf, addressToRender);
1697
1698 /* use addressToRender to send out message. */
1699 vfe_send_output_msg(in->whichOutputPath,
1700 addressToRender[0], addressToRender[1]);
1701
1702 } else {
1703 /* ackPending is still there, accumulate dropped frame count.
1704 * These count can be read through ioctrl command. */
1705 CDBG("waiting frame ACK\n");
1706
1707 if (in->whichOutputPath == 0)
1708 ctrl->vfeDroppedFrameCounts.output1Count++;
1709
1710 if (in->whichOutputPath == 1)
1711 ctrl->vfeDroppedFrameCounts.output2Count++;
1712 }
1713
1714 /* in case of multishot when upper layer did not ack, there will still
1715 * be a snapshot done msg sent out, even though the number of frames
1716 * sent out may be less than the desired number of frames. snapshot
1717 * done msg would be helpful to indicate that vfe pipeline has stop,
1718 * and in good known state.
1719 */
1720 if (ctrl->vfeOperationMode)
1721 in->snapshotPendingCount--;
1722}
1723
1724static void vfe_process_output_path_irq(
1725 struct vfe_interrupt_status *irqstatus)
1726{
1727 /* unsigned long flags; */
1728
1729 /* process the view path interrupts */
1730 if (irqstatus->anyOutput1PathIrqs) {
1731 if (ctrl->viewPath.multiFrag) {
1732
1733 if (irqstatus->viewCbcrPingpongIrq)
1734 vfe_process_pingpong_irq(
1735 &(ctrl->viewPath.cbcrPath),
1736 ctrl->viewPath.fragCount);
1737
1738 if (irqstatus->viewYPingpongIrq)
1739 vfe_process_pingpong_irq(
1740 &(ctrl->viewPath.yPath),
1741 ctrl->viewPath.fragCount);
1742
1743 if (irqstatus->viewIrq)
1744 vfe_process_frame_done_irq_multi_frag(
1745 &ctrl->viewPath);
1746
1747 } else {
1748 /* typical case for no fragment,
1749 only frame done irq is enabled. */
1750 if (irqstatus->viewIrq)
1751 vfe_process_frame_done_irq_no_frag(
1752 &ctrl->viewPath);
1753 }
1754 }
1755
1756 /* process the encoder path interrupts */
1757 if (irqstatus->anyOutput2PathIrqs) {
1758 if (ctrl->encPath.multiFrag) {
1759 if (irqstatus->encCbcrPingpongIrq)
1760 vfe_process_pingpong_irq(
1761 &(ctrl->encPath.cbcrPath),
1762 ctrl->encPath.fragCount);
1763
1764 if (irqstatus->encYPingpongIrq)
1765 vfe_process_pingpong_irq(&(ctrl->encPath.yPath),
1766 ctrl->encPath.fragCount);
1767
1768 if (irqstatus->encIrq)
1769 vfe_process_frame_done_irq_multi_frag(
1770 &ctrl->encPath);
1771
1772 } else {
1773 if (irqstatus->encIrq)
1774 vfe_process_frame_done_irq_no_frag(
1775 &ctrl->encPath);
1776 }
1777 }
1778
1779 if (ctrl->vfeOperationMode) {
1780 if ((ctrl->encPath.snapshotPendingCount == 0) &&
1781 (ctrl->viewPath.snapshotPendingCount == 0)) {
1782
1783 /* @todo This is causing issues, further investigate */
1784 /* spin_lock_irqsave(&ctrl->state_lock, flags); */
1785 ctrl->vstate = VFE_STATE_IDLE;
1786 /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
1787
1788 vfe_send_msg_no_payload(VFE_MSG_ID_SNAPSHOT_DONE);
1789 vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
1790 vfe_pm_stop();
1791 }
1792 }
1793}
1794
1795static void vfe_do_tasklet(unsigned long data)
1796{
1797 unsigned long flags;
1798
1799 struct isr_queue_cmd *qcmd = NULL;
1800
1801 CDBG("=== vfe_do_tasklet start === \n");
1802
1803 spin_lock_irqsave(&ctrl->tasklet_lock, flags);
1804 qcmd = list_first_entry(&ctrl->tasklet_q,
1805 struct isr_queue_cmd, list);
1806
1807 if (!qcmd) {
1808 spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
1809 return;
1810 }
1811
1812 list_del(&qcmd->list);
1813 spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
1814
1815 if (qcmd->vfeInterruptStatus.regUpdateIrq) {
1816 CDBG("irq regUpdateIrq\n");
1817 vfe_process_reg_update_irq();
1818 }
1819
1820 if (qcmd->vfeInterruptStatus.resetAckIrq) {
1821 CDBG("irq resetAckIrq\n");
1822 vfe_process_reset_irq();
1823 }
1824
1825 spin_lock_irqsave(&ctrl->state_lock, flags);
1826 if (ctrl->vstate != VFE_STATE_ACTIVE) {
1827 spin_unlock_irqrestore(&ctrl->state_lock, flags);
1828 return;
1829 }
1830 spin_unlock_irqrestore(&ctrl->state_lock, flags);
1831
1832#if 0
1833 if (qcmd->vfeInterruptStatus.camifEpoch1Irq)
1834 vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH1);
1835
1836 if (qcmd->vfeInterruptStatus.camifEpoch2Irq)
1837 vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH2);
1838#endif /* Jeff */
1839
1840 /* next, check output path related interrupts. */
1841 if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) {
1842 CDBG("irq anyOutputPathIrqs\n");
1843 vfe_process_output_path_irq(&qcmd->vfeInterruptStatus);
1844 }
1845
1846 if (qcmd->vfeInterruptStatus.afPingpongIrq)
1847 vfe_process_stats_af_irq();
1848
1849 if (qcmd->vfeInterruptStatus.awbPingpongIrq)
1850 vfe_process_stats_awb_irq();
1851
1852 /* any error irqs*/
1853 if (qcmd->vfeInterruptStatus.anyErrorIrqs)
1854 vfe_process_error_irq(&qcmd->vfeInterruptStatus);
1855
1856#if 0
1857 if (qcmd->vfeInterruptStatus.anySyncTimerIrqs)
1858 vfe_process_sync_timer_irq();
1859
1860 if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs)
1861 vfe_process_async_timer_irq();
1862#endif /* Jeff */
1863
1864 if (qcmd->vfeInterruptStatus.camifSofIrq) {
1865 CDBG("irq camifSofIrq\n");
1866 vfe_process_camif_sof_irq();
1867 }
1868
1869 kfree(qcmd);
1870 CDBG("=== vfe_do_tasklet end === \n");
1871}
1872
1873DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0);
1874
1875static irqreturn_t vfe_parse_irq(int irq_num, void *data)
1876{
1877 unsigned long flags;
1878 uint32_t irqStatusLocal;
1879 struct vfe_irq_thread_msg irq;
1880 struct isr_queue_cmd *qcmd;
1881
1882 CDBG("vfe_parse_irq\n");
1883
1884 vfe_read_irq_status(&irq);
1885
1886 if (irq.vfeIrqStatus == 0) {
1887 CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n");
1888 return IRQ_HANDLED;
1889 }
1890
1891 qcmd = kzalloc(sizeof(struct isr_queue_cmd),
1892 GFP_ATOMIC);
1893 if (!qcmd) {
1894 CDBG("vfe_parse_irq: qcmd malloc failed!\n");
1895 return IRQ_HANDLED;
1896 }
1897
1898 spin_lock_irqsave(&ctrl->ack_lock, flags);
1899
1900 if (ctrl->vfeStopAckPending)
1901 irqStatusLocal =
1902 (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus);
1903 else
1904 irqStatusLocal =
1905 ((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) &
1906 irq.vfeIrqStatus);
1907
1908 spin_unlock_irqrestore(&ctrl->ack_lock, flags);
1909
1910 /* first parse the interrupt status to local data structures. */
1911 qcmd->vfeInterruptStatus = vfe_parse_interrupt_status(irqStatusLocal);
1912 qcmd->vfeAsfFrameInfo = vfe_get_asf_frame_info(&irq);
1913 qcmd->vfeBpcFrameInfo = vfe_get_demosaic_frame_info(&irq);
1914 qcmd->vfeCamifStatusLocal = vfe_get_camif_status(&irq);
1915 qcmd->vfePmData = vfe_get_performance_monitor_data(&irq);
1916
1917 spin_lock_irqsave(&ctrl->tasklet_lock, flags);
1918 list_add_tail(&qcmd->list, &ctrl->tasklet_q);
1919 spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
1920 tasklet_schedule(&vfe_tasklet);
1921
1922 /* clear the pending interrupt of the same kind.*/
1923 writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR);
1924
1925 return IRQ_HANDLED;
1926}
1927
1928int vfe_cmd_init(struct msm_vfe_callback *presp,
1929 struct platform_device *pdev, void *sdata)
1930{
1931 struct resource *vfemem, *vfeirq, *vfeio;
1932 int rc;
1933
1934 vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1935 if (!vfemem) {
1936 CDBG("no mem resource?\n");
1937 return -ENODEV;
1938 }
1939
1940 vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1941 if (!vfeirq) {
1942 CDBG("no irq resource?\n");
1943 return -ENODEV;
1944 }
1945
1946 vfeio = request_mem_region(vfemem->start,
1947 resource_size(vfemem), pdev->name);
1948 if (!vfeio) {
1949 CDBG("VFE region already claimed\n");
1950 return -EBUSY;
1951 }
1952
1953 ctrl =
1954 kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL);
1955 if (!ctrl) {
1956 rc = -ENOMEM;
1957 goto cmd_init_failed1;
1958 }
1959
1960 ctrl->vfeirq = vfeirq->start;
1961
1962 ctrl->vfebase =
1963 ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
1964 if (!ctrl->vfebase) {
1965 rc = -ENOMEM;
1966 goto cmd_init_failed2;
1967 }
1968
1969 rc = request_irq(ctrl->vfeirq, vfe_parse_irq,
1970 IRQF_TRIGGER_RISING, "vfe", 0);
1971 if (rc < 0)
1972 goto cmd_init_failed2;
1973
1974 if (presp && presp->vfe_resp)
1975 ctrl->resp = presp;
1976 else {
1977 rc = -EINVAL;
1978 goto cmd_init_failed3;
1979 }
1980
1981 ctrl->extdata =
1982 kmalloc(sizeof(struct vfe_frame_extra), GFP_KERNEL);
1983 if (!ctrl->extdata) {
1984 rc = -ENOMEM;
1985 goto cmd_init_failed3;
1986 }
1987
1988 spin_lock_init(&ctrl->ack_lock);
1989 spin_lock_init(&ctrl->state_lock);
1990 spin_lock_init(&ctrl->io_lock);
1991
1992 ctrl->extlen = sizeof(struct vfe_frame_extra);
1993
1994 spin_lock_init(&ctrl->tasklet_lock);
1995 INIT_LIST_HEAD(&ctrl->tasklet_q);
1996
1997 ctrl->syncdata = sdata;
1998 return 0;
1999
2000cmd_init_failed3:
2001 disable_irq(ctrl->vfeirq);
2002 free_irq(ctrl->vfeirq, 0);
2003 iounmap(ctrl->vfebase);
2004cmd_init_failed2:
2005 kfree(ctrl);
2006cmd_init_failed1:
2007 release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
2008 return rc;
2009}
2010
2011void vfe_cmd_release(struct platform_device *dev)
2012{
2013 struct resource *mem;
2014
2015 disable_irq(ctrl->vfeirq);
2016 free_irq(ctrl->vfeirq, 0);
2017
2018 iounmap(ctrl->vfebase);
2019 mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
2020 release_mem_region(mem->start, (mem->end - mem->start) + 1);
2021
2022 ctrl->extlen = 0;
2023
2024 kfree(ctrl->extdata);
2025 kfree(ctrl);
2026}
2027
2028void vfe_stats_af_stop(void)
2029{
2030 ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE;
2031 ctrl->vfeImaskLocal.afPingpongIrq = FALSE;
2032}
2033
2034void vfe_stop(void)
2035{
2036 boolean vfeAxiBusy;
2037 uint32_t vfeAxiStauts;
2038
2039 /* for reset hw modules, and send msg when reset_irq comes.*/
2040 ctrl->vfeStopAckPending = TRUE;
2041
2042 ctrl->vfeStatsPingPongReloadFlag = FALSE;
2043 vfe_pm_stop();
2044
2045 /* disable all interrupts. */
2046 vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS);
2047
2048 /* in either continuous or snapshot mode, stop command can be issued
2049 * at any time.
2050 */
2051 vfe_camif_stop_immediately();
2052 vfe_program_axi_cmd(AXI_HALT);
2053 vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
2054
2055 vfeAxiBusy = TRUE;
2056
2057 while (vfeAxiBusy) {
2058 vfeAxiStauts = vfe_read_axi_status();
2059 if ((vfeAxiStauts & AXI_STATUS_BUSY_MASK) != 0)
2060 vfeAxiBusy = FALSE;
2061 }
2062
2063 vfe_program_axi_cmd(AXI_HALT_CLEAR);
2064
2065 /* clear all pending interrupts */
2066 writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
2067
2068 /* enable reset_ack and async timer interrupt only while stopping
2069 * the pipeline.
2070 */
2071 vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING);
2072
2073 vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD);
2074}
2075
2076void vfe_update(void)
2077{
2078 ctrl->vfeModuleEnableLocal.statsEnable =
2079 ctrl->vfeStatsCmdLocal.autoFocusEnable |
2080 ctrl->vfeStatsCmdLocal.axwEnable;
2081
2082 vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
2083
2084 vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
2085
2086 ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
2087 vfe_program_irq_mask(ctrl->vfeImaskPacked);
2088
2089 if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) &&
2090 (ctrl->vfeStatsPingPongReloadFlag == FALSE)) {
2091 ctrl->vfeStatsPingPongReloadFlag = TRUE;
2092
2093 ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
2094 vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
2095 }
2096
2097 vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER);
2098}
2099
2100int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in)
2101{
2102 int rc = 0;
2103
2104 ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
2105
2106 switch (in->channelSelect) {
2107 case RGB_GAMMA_CH0_SELECTED:
2108 ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
2109 vfe_write_gamma_table(0,
2110 ctrl->vfeGammaLutSel.ch0BankSelect, in->table);
2111 break;
2112
2113 case RGB_GAMMA_CH1_SELECTED:
2114 ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
2115 vfe_write_gamma_table(1,
2116 ctrl->vfeGammaLutSel.ch1BankSelect, in->table);
2117 break;
2118
2119 case RGB_GAMMA_CH2_SELECTED:
2120 ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
2121 vfe_write_gamma_table(2,
2122 ctrl->vfeGammaLutSel.ch2BankSelect, in->table);
2123 break;
2124
2125 case RGB_GAMMA_CH0_CH1_SELECTED:
2126 ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
2127 ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
2128 vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
2129 in->table);
2130 vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
2131 in->table);
2132 break;
2133
2134 case RGB_GAMMA_CH0_CH2_SELECTED:
2135 ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
2136 ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
2137 vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
2138 in->table);
2139 vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
2140 in->table);
2141 break;
2142
2143 case RGB_GAMMA_CH1_CH2_SELECTED:
2144 ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
2145 ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
2146 vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
2147 in->table);
2148 vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
2149 in->table);
2150 break;
2151
2152 case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
2153 ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
2154 ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
2155 ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
2156 vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
2157 in->table);
2158 vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
2159 in->table);
2160 vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
2161 in->table);
2162 break;
2163
2164 default:
2165 return -EINVAL;
2166 } /* switch */
2167
2168 /* update the gammaLutSel register. */
2169 vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
2170
2171 return rc;
2172}
2173
2174int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in)
2175{
2176 int rc = 0;
2177
2178 ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
2179
2180 switch (in->channelSelect) {
2181 case RGB_GAMMA_CH0_SELECTED:
2182vfe_write_gamma_table(0, 0, in->table);
2183break;
2184
2185 case RGB_GAMMA_CH1_SELECTED:
2186 vfe_write_gamma_table(1, 0, in->table);
2187 break;
2188
2189 case RGB_GAMMA_CH2_SELECTED:
2190 vfe_write_gamma_table(2, 0, in->table);
2191 break;
2192
2193 case RGB_GAMMA_CH0_CH1_SELECTED:
2194 vfe_write_gamma_table(0, 0, in->table);
2195 vfe_write_gamma_table(1, 0, in->table);
2196 break;
2197
2198 case RGB_GAMMA_CH0_CH2_SELECTED:
2199 vfe_write_gamma_table(0, 0, in->table);
2200 vfe_write_gamma_table(2, 0, in->table);
2201 break;
2202
2203 case RGB_GAMMA_CH1_CH2_SELECTED:
2204 vfe_write_gamma_table(1, 0, in->table);
2205 vfe_write_gamma_table(2, 0, in->table);
2206 break;
2207
2208 case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
2209 vfe_write_gamma_table(0, 0, in->table);
2210 vfe_write_gamma_table(1, 0, in->table);
2211 vfe_write_gamma_table(2, 0, in->table);
2212 break;
2213
2214 default:
2215 rc = -EINVAL;
2216 break;
2217 } /* switch */
2218
2219 return rc;
2220}
2221
2222void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in)
2223{
2224 ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr;
2225 ctrl->afStatsControl.ackPending = FALSE;
2226}
2227
2228void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in)
2229{
2230 ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr;
2231 ctrl->awbStatsControl.ackPending = FALSE;
2232}
2233
2234void vfe_output2_ack(struct vfe_cmd_output_ack *in)
2235{
2236 const uint32_t *psrc;
2237 uint32_t *pdest;
2238 uint8_t i;
2239
2240 pdest = ctrl->encPath.nextFrameAddrBuf;
2241
2242 CDBG("output2_ack: ack addr = 0x%x\n", in->ybufaddr[0]);
2243
2244 psrc = in->ybufaddr;
2245 for (i = 0; i < ctrl->encPath.fragCount; i++)
2246 *pdest++ = *psrc++;
2247
2248 psrc = in->chromabufaddr;
2249 for (i = 0; i < ctrl->encPath.fragCount; i++)
2250 *pdest++ = *psrc++;
2251
2252 ctrl->encPath.ackPending = FALSE;
2253}
2254
2255void vfe_output1_ack(struct vfe_cmd_output_ack *in)
2256{
2257 const uint32_t *psrc;
2258 uint32_t *pdest;
2259 uint8_t i;
2260
2261 pdest = ctrl->viewPath.nextFrameAddrBuf;
2262
2263 psrc = in->ybufaddr;
2264 for (i = 0; i < ctrl->viewPath.fragCount; i++)
2265 *pdest++ = *psrc++;
2266
2267 psrc = in->chromabufaddr;
2268 for (i = 0; i < ctrl->viewPath.fragCount; i++)
2269 *pdest++ = *psrc++;
2270
2271 ctrl->viewPath.ackPending = FALSE;
2272}
2273
2274void vfe_start(struct vfe_cmd_start *in)
2275{
2276 unsigned long flags;
2277 uint32_t pmstatus = 0;
2278 boolean rawmode;
2279 uint32_t demperiod = 0;
2280 uint32_t demeven = 0;
2281 uint32_t demodd = 0;
2282
2283 /* derived from other commands. (camif config, axi output config,
2284 * etc)
2285 */
2286 struct vfe_cfg hwcfg;
2287 struct vfe_upsample_cfg chromupcfg;
2288
2289 CDBG("vfe_start operationMode = %d\n", in->operationMode);
2290
2291 memset(&hwcfg, 0, sizeof(hwcfg));
2292 memset(&chromupcfg, 0, sizeof(chromupcfg));
2293
2294 switch (in->pixel) {
2295 case VFE_BAYER_RGRGRG:
2296 demperiod = 1;
2297 demeven = 0xC9;
2298 demodd = 0xAC;
2299 break;
2300
2301 case VFE_BAYER_GRGRGR:
2302 demperiod = 1;
2303 demeven = 0x9C;
2304 demodd = 0xCA;
2305 break;
2306
2307 case VFE_BAYER_BGBGBG:
2308 demperiod = 1;
2309 demeven = 0xCA;
2310 demodd = 0x9C;
2311 break;
2312
2313 case VFE_BAYER_GBGBGB:
2314 demperiod = 1;
2315 demeven = 0xAC;
2316 demodd = 0xC9;
2317 break;
2318
2319 case VFE_YUV_YCbYCr:
2320 demperiod = 3;
2321 demeven = 0x9CAC;
2322 demodd = 0x9CAC;
2323 break;
2324
2325 case VFE_YUV_YCrYCb:
2326 demperiod = 3;
2327 demeven = 0xAC9C;
2328 demodd = 0xAC9C;
2329 break;
2330
2331 case VFE_YUV_CbYCrY:
2332 demperiod = 3;
2333 demeven = 0xC9CA;
2334 demodd = 0xC9CA;
2335 break;
2336
2337 case VFE_YUV_CrYCbY:
2338 demperiod = 3;
2339 demeven = 0xCAC9;
2340 demodd = 0xCAC9;
2341 break;
2342
2343 default:
2344 return;
2345 }
2346
2347 vfe_config_demux(demperiod, demeven, demodd);
2348
2349 vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
2350
2351 /* save variables to local. */
2352 ctrl->vfeOperationMode = in->operationMode;
2353 if (ctrl->vfeOperationMode ==
2354 VFE_START_OPERATION_MODE_SNAPSHOT) {
2355 /* in snapshot mode, initialize snapshot count*/
2356 ctrl->vfeSnapShotCount = in->snapshotCount;
2357
2358 /* save the requested count, this is temporarily done, to
2359 help with HJR / multishot. */
2360 ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount;
2361
2362 CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount);
2363
2364 /* Assumption is to have the same pattern and period for both
2365 paths, if both paths are used. */
2366 if (ctrl->viewPath.pathEnabled) {
2367 ctrl->viewPath.snapshotPendingCount =
2368 in->snapshotCount;
2369
2370 ctrl->vfeFrameSkipPattern =
2371 ctrl->vfeFrameSkip.output1Pattern;
2372 ctrl->vfeFrameSkipPeriod =
2373 ctrl->vfeFrameSkip.output1Period;
2374 }
2375
2376 if (ctrl->encPath.pathEnabled) {
2377 ctrl->encPath.snapshotPendingCount =
2378 in->snapshotCount;
2379
2380 ctrl->vfeFrameSkipPattern =
2381 ctrl->vfeFrameSkip.output2Pattern;
2382 ctrl->vfeFrameSkipPeriod =
2383 ctrl->vfeFrameSkip.output2Period;
2384 }
2385 }
2386
2387 /* enable color conversion for bayer sensor
2388 if stats enabled, need to do color conversion. */
2389 if (in->pixel <= VFE_BAYER_GBGBGB)
2390 ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE;
2391
2392 vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
2393
2394 if (in->pixel >= VFE_YUV_YCbYCr)
2395 ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE;
2396
2397 ctrl->vfeModuleEnableLocal.demuxEnable = TRUE;
2398
2399 /* if any stats module is enabled, the main bit is enabled. */
2400 ctrl->vfeModuleEnableLocal.statsEnable =
2401 ctrl->vfeStatsCmdLocal.autoFocusEnable |
2402 ctrl->vfeStatsCmdLocal.axwEnable;
2403
2404 vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
2405
2406 /* in case of offline processing, do not need to config camif. Having
2407 * bus output enabled in camif_config register might confuse the
2408 * hardware?
2409 */
2410 if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) {
2411 vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal);
2412 } else {
2413 /* offline processing, enable axi read */
2414 ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE;
2415 ctrl->vfeBusCmdLocal.stripeReload = TRUE;
2416 ctrl->vfeBusConfigLocal.rawPixelDataSize =
2417 ctrl->axiInputDataSize;
2418 }
2419
2420 vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal);
2421
2422 /* directly from start command */
2423 hwcfg.pixelPattern = in->pixel;
2424 hwcfg.inputSource = in->inputSource;
2425 writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG);
2426
2427 /* regardless module enabled or not, it does not hurt
2428 * to program the cositing mode. */
2429 chromupcfg.chromaCositingForYCbCrInputs =
2430 in->yuvInputCositingMode;
2431
2432 writel(*(uint32_t *)&(chromupcfg),
2433 ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
2434
2435 /* MISR to monitor the axi read. */
2436 writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0);
2437
2438 /* clear all pending interrupts. */
2439 writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
2440
2441 /* define how composite interrupt work. */
2442 ctrl->vfeImaskCompositePacked =
2443 vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal);
2444
2445 vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked);
2446
2447 /* enable all necessary interrupts. */
2448 ctrl->vfeImaskLocal.camifSofIrq = TRUE;
2449 ctrl->vfeImaskLocal.regUpdateIrq = TRUE;
2450 ctrl->vfeImaskLocal.resetAckIrq = TRUE;
2451
2452 ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
2453 vfe_program_irq_mask(ctrl->vfeImaskPacked);
2454
2455 /* enable bus performance monitor */
2456 vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal);
2457
2458 /* trigger vfe reg update */
2459 ctrl->vfeStartAckPendingFlag = TRUE;
2460
2461 /* write bus command to trigger reload of ping pong buffer. */
2462 ctrl->vfeBusCmdLocal.busPingpongReload = TRUE;
2463
2464 if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) {
2465 ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
2466 ctrl->vfeStatsPingPongReloadFlag = TRUE;
2467 }
2468
2469 writel(VFE_REG_UPDATE_TRIGGER,
2470 ctrl->vfebase + VFE_REG_UPDATE_CMD);
2471
2472 /* program later than the reg update. */
2473 vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
2474
2475 if ((in->inputSource ==
2476 VFE_START_INPUT_SOURCE_CAMIF) ||
2477 (in->inputSource ==
2478 VFE_START_INPUT_SOURCE_TESTGEN))
2479 writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
2480
2481 /* start test gen if it is enabled */
2482 if (ctrl->vfeTestGenStartFlag == TRUE) {
2483 ctrl->vfeTestGenStartFlag = FALSE;
2484 vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO);
2485 }
2486
2487 CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode);
2488 if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) {
2489 /* raw dump mode */
2490 rawmode = TRUE;
2491
2492 while (rawmode) {
2493 pmstatus =
2494 readl(ctrl->vfebase +
2495 VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
2496
2497 if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0)
2498 rawmode = FALSE;
2499 }
2500
2501 vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
2502 ctrl->vfeStartAckPendingFlag = FALSE;
2503 }
2504
2505 spin_lock_irqsave(&ctrl->state_lock, flags);
2506 ctrl->vstate = VFE_STATE_ACTIVE;
2507 spin_unlock_irqrestore(&ctrl->state_lock, flags);
2508}
2509
2510void vfe_la_update(struct vfe_cmd_la_config *in)
2511{
2512 int16_t *pTable;
2513 enum VFE_DMI_RAM_SEL dmiRamSel;
2514 int i;
2515
2516 pTable = in->table;
2517 ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
2518
2519 /* toggle the bank to be used. */
2520 ctrl->vfeLaBankSel ^= 1;
2521
2522 if (ctrl->vfeLaBankSel == 0)
2523 dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
2524 else
2525 dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
2526
2527 /* configure the DMI_CFG to select right sram */
2528 vfe_program_dmi_cfg(dmiRamSel);
2529
2530 for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
2531 writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
2532 pTable++;
2533 }
2534
2535 /* After DMI transfer, to make it safe, need to set
2536 * the DMI_CFG to unselect any SRAM */
2537 writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
2538 writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
2539}
2540
2541void vfe_la_config(struct vfe_cmd_la_config *in)
2542{
2543 uint16_t i;
2544 int16_t *pTable;
2545 enum VFE_DMI_RAM_SEL dmiRamSel;
2546
2547 pTable = in->table;
2548 ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
2549
2550 if (ctrl->vfeLaBankSel == 0)
2551 dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
2552 else
2553 dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
2554
2555 /* configure the DMI_CFG to select right sram */
2556 vfe_program_dmi_cfg(dmiRamSel);
2557
2558 for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
2559 writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
2560 pTable++;
2561 }
2562
2563 /* After DMI transfer, to make it safe, need to set the
2564 * DMI_CFG to unselect any SRAM */
2565 writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
2566
2567 /* can only be bank 0 or bank 1 for now. */
2568 writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
2569 CDBG("VFE Luma adaptation bank selection is 0x%x\n",
2570 *(uint32_t *)&ctrl->vfeLaBankSel);
2571}
2572
2573void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in)
2574{
2575 struct VFE_TestGen_ConfigCmdType cmd;
2576
2577 memset(&cmd, 0, sizeof(cmd));
2578
2579 cmd.numFrame = in->numFrame;
2580 cmd.pixelDataSelect = in->pixelDataSelect;
2581 cmd.systematicDataSelect = in->systematicDataSelect;
2582 cmd.pixelDataSize = (uint32_t)in->pixelDataSize;
2583 cmd.hsyncEdge = (uint32_t)in->hsyncEdge;
2584 cmd.vsyncEdge = (uint32_t)in->vsyncEdge;
2585 cmd.imageWidth = in->imageWidth;
2586 cmd.imageHeight = in->imageHeight;
2587 cmd.sofOffset = in->startOfFrameOffset;
2588 cmd.eofNOffset = in->endOfFrameNOffset;
2589 cmd.solOffset = in->startOfLineOffset;
2590 cmd.eolNOffset = in->endOfLineNOffset;
2591 cmd.hBlankInterval = in->hbi;
2592 cmd.vBlankInterval = in->vbl;
2593 cmd.vBlankIntervalEnable = in->vblEnable;
2594 cmd.sofDummy = in->startOfFrameDummyLine;
2595 cmd.eofDummy = in->endOfFrameDummyLine;
2596 cmd.unicolorBarSelect = in->unicolorBarSelect;
2597 cmd.unicolorBarEnable = in->unicolorBarEnable;
2598 cmd.splitEnable = in->colorBarsSplitEnable;
2599 cmd.pixelPattern = (uint32_t)in->colorBarsPixelPattern;
2600 cmd.rotatePeriod = in->colorBarsRotatePeriod;
2601 cmd.randomSeed = in->testGenRandomSeed;
2602
2603 vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG,
2604 (uint32_t *) &cmd, sizeof(cmd));
2605}
2606
2607void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in)
2608{
2609 struct VFE_FRAME_SKIP_UpdateCmdType cmd;
2610
2611 cmd.yPattern = in->output1Pattern;
2612 cmd.cbcrPattern = in->output1Pattern;
2613 vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN,
2614 (uint32_t *)&cmd, sizeof(cmd));
2615
2616 cmd.yPattern = in->output2Pattern;
2617 cmd.cbcrPattern = in->output2Pattern;
2618 vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN,
2619 (uint32_t *)&cmd, sizeof(cmd));
2620}
2621
2622void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in)
2623{
2624 struct vfe_frame_skip_cfg cmd;
2625 memset(&cmd, 0, sizeof(cmd));
2626
2627 ctrl->vfeFrameSkip = *in;
2628
2629 cmd.output2YPeriod = in->output2Period;
2630 cmd.output2CbCrPeriod = in->output2Period;
2631 cmd.output2YPattern = in->output2Pattern;
2632 cmd.output2CbCrPattern = in->output2Pattern;
2633 cmd.output1YPeriod = in->output1Period;
2634 cmd.output1CbCrPeriod = in->output1Period;
2635 cmd.output1YPattern = in->output1Pattern;
2636 cmd.output1CbCrPattern = in->output1Pattern;
2637
2638 vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG,
2639 (uint32_t *)&cmd, sizeof(cmd));
2640}
2641
2642void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in)
2643{
2644 struct vfe_output_clamp_cfg cmd;
2645 memset(&cmd, 0, sizeof(cmd));
2646
2647 cmd.yChanMax = in->maxCh0;
2648 cmd.cbChanMax = in->maxCh1;
2649 cmd.crChanMax = in->maxCh2;
2650
2651 cmd.yChanMin = in->minCh0;
2652 cmd.cbChanMin = in->minCh1;
2653 cmd.crChanMin = in->minCh2;
2654
2655 vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd,
2656 sizeof(cmd));
2657}
2658
2659void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in)
2660{
2661 struct vfe_camifframe_update cmd;
2662
2663 memset(&cmd, 0, sizeof(cmd));
2664
2665 cmd.pixelsPerLine = in->pixelsPerLine;
2666 cmd.linesPerFrame = in->linesPerFrame;
2667
2668 vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd,
2669 sizeof(cmd));
2670}
2671
2672void vfe_color_correction_config(
2673 struct vfe_cmd_color_correction_config *in)
2674{
2675 struct vfe_color_correction_cfg cmd;
2676
2677 memset(&cmd, 0, sizeof(cmd));
2678 ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable;
2679
2680 cmd.c0 = in->C0;
2681 cmd.c1 = in->C1;
2682 cmd.c2 = in->C2;
2683 cmd.c3 = in->C3;
2684 cmd.c4 = in->C4;
2685 cmd.c5 = in->C5;
2686 cmd.c6 = in->C6;
2687 cmd.c7 = in->C7;
2688 cmd.c8 = in->C8;
2689
2690 cmd.k0 = in->K0;
2691 cmd.k1 = in->K1;
2692 cmd.k2 = in->K2;
2693
2694 cmd.coefQFactor = in->coefQFactor;
2695
2696 vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0,
2697 (uint32_t *)&cmd, sizeof(cmd));
2698}
2699
2700void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in)
2701{
2702struct vfe_demosaic_cfg cmd;
2703 struct vfe_demosaic_abf_cfg cmdabf;
2704 uint32_t temp;
2705
2706 memset(&cmd, 0, sizeof(cmd));
2707 temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
2708
2709 cmd = *((struct vfe_demosaic_cfg *)(&temp));
2710 cmd.abfEnable = in->abfUpdate.enable;
2711 cmd.forceAbfOn = in->abfUpdate.forceOn;
2712 cmd.abfShift = in->abfUpdate.shift;
2713 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
2714 (uint32_t *)&cmd, sizeof(cmd));
2715
2716 cmdabf.lpThreshold = in->abfUpdate.lpThreshold;
2717 cmdabf.ratio = in->abfUpdate.ratio;
2718 cmdabf.minValue = in->abfUpdate.min;
2719 cmdabf.maxValue = in->abfUpdate.max;
2720 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
2721 (uint32_t *)&cmdabf, sizeof(cmdabf));
2722}
2723
2724void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in)
2725{
2726 struct vfe_demosaic_cfg cmd;
2727 struct vfe_demosaic_bpc_cfg cmdbpc;
2728 uint32_t temp;
2729
2730 memset(&cmd, 0, sizeof(cmd));
2731
2732 temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
2733
2734 cmd = *((struct vfe_demosaic_cfg *)(&temp));
2735 cmd.badPixelCorrEnable = in->bpcUpdate.enable;
2736 cmd.fminThreshold = in->bpcUpdate.fminThreshold;
2737 cmd.fmaxThreshold = in->bpcUpdate.fmaxThreshold;
2738
2739 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
2740 (uint32_t *)&cmd, sizeof(cmd));
2741
2742 cmdbpc.blueDiffThreshold = in->bpcUpdate.blueDiffThreshold;
2743 cmdbpc.redDiffThreshold = in->bpcUpdate.redDiffThreshold;
2744 cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold;
2745
2746 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
2747 (uint32_t *)&cmdbpc, sizeof(cmdbpc));
2748}
2749
2750void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in)
2751{
2752 struct vfe_demosaic_cfg cmd;
2753 struct vfe_demosaic_bpc_cfg cmd_bpc;
2754 struct vfe_demosaic_abf_cfg cmd_abf;
2755
2756 memset(&cmd, 0, sizeof(cmd));
2757 memset(&cmd_bpc, 0, sizeof(cmd_bpc));
2758 memset(&cmd_abf, 0, sizeof(cmd_abf));
2759
2760 ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable;
2761
2762 cmd.abfEnable = in->abfConfig.enable;
2763 cmd.badPixelCorrEnable = in->bpcConfig.enable;
2764 cmd.forceAbfOn = in->abfConfig.forceOn;
2765 cmd.abfShift = in->abfConfig.shift;
2766 cmd.fminThreshold = in->bpcConfig.fminThreshold;
2767 cmd.fmaxThreshold = in->bpcConfig.fmaxThreshold;
2768 cmd.slopeShift = in->slopeShift;
2769
2770 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
2771 (uint32_t *)&cmd, sizeof(cmd));
2772
2773 cmd_abf.lpThreshold = in->abfConfig.lpThreshold;
2774 cmd_abf.ratio = in->abfConfig.ratio;
2775 cmd_abf.minValue = in->abfConfig.min;
2776 cmd_abf.maxValue = in->abfConfig.max;
2777
2778 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
2779 (uint32_t *)&cmd_abf, sizeof(cmd_abf));
2780
2781 cmd_bpc.blueDiffThreshold = in->bpcConfig.blueDiffThreshold;
2782 cmd_bpc.redDiffThreshold = in->bpcConfig.redDiffThreshold;
2783 cmd_bpc.greenDiffThreshold = in->bpcConfig.greenDiffThreshold;
2784
2785 vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
2786 (uint32_t *)&cmd_bpc, sizeof(cmd_bpc));
2787}
2788
2789void vfe_demux_channel_gain_update(
2790 struct vfe_cmd_demux_channel_gain_config *in)
2791{
2792 struct vfe_demux_cfg cmd;
2793
2794 memset(&cmd, 0, sizeof(cmd));
2795
2796 cmd.ch0EvenGain = in->ch0EvenGain;
2797 cmd.ch0OddGain = in->ch0OddGain;
2798 cmd.ch1Gain = in->ch1Gain;
2799 cmd.ch2Gain = in->ch2Gain;
2800
2801 vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
2802 (uint32_t *)&cmd, sizeof(cmd));
2803}
2804
2805void vfe_demux_channel_gain_config(
2806 struct vfe_cmd_demux_channel_gain_config *in)
2807{
2808 struct vfe_demux_cfg cmd;
2809
2810 memset(&cmd, 0, sizeof(cmd));
2811
2812 cmd.ch0EvenGain = in->ch0EvenGain;
2813 cmd.ch0OddGain = in->ch0OddGain;
2814 cmd.ch1Gain = in->ch1Gain;
2815 cmd.ch2Gain = in->ch2Gain;
2816
2817 vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
2818 (uint32_t *)&cmd, sizeof(cmd));
2819}
2820
2821void vfe_black_level_update(struct vfe_cmd_black_level_config *in)
2822{
2823 struct vfe_blacklevel_cfg cmd;
2824
2825 memset(&cmd, 0, sizeof(cmd));
2826 ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
2827
2828 cmd.evenEvenAdjustment = in->evenEvenAdjustment;
2829 cmd.evenOddAdjustment = in->evenOddAdjustment;
2830 cmd.oddEvenAdjustment = in->oddEvenAdjustment;
2831 cmd.oddOddAdjustment = in->oddOddAdjustment;
2832
2833 vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
2834 (uint32_t *)&cmd, sizeof(cmd));
2835}
2836
2837void vfe_black_level_config(struct vfe_cmd_black_level_config *in)
2838{
2839 struct vfe_blacklevel_cfg cmd;
2840 memset(&cmd, 0, sizeof(cmd));
2841
2842 ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
2843
2844 cmd.evenEvenAdjustment = in->evenEvenAdjustment;
2845 cmd.evenOddAdjustment = in->evenOddAdjustment;
2846 cmd.oddEvenAdjustment = in->oddEvenAdjustment;
2847 cmd.oddOddAdjustment = in->oddOddAdjustment;
2848
2849 vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
2850 (uint32_t *)&cmd, sizeof(cmd));
2851}
2852
2853void vfe_asf_update(struct vfe_cmd_asf_update *in)
2854{
2855 struct vfe_asf_update cmd;
2856 memset(&cmd, 0, sizeof(cmd));
2857
2858 ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
2859
2860 cmd.smoothEnable = in->smoothFilterEnabled;
2861 cmd.sharpMode = in->sharpMode;
2862 cmd.smoothCoeff1 = in->smoothCoefCenter;
2863 cmd.smoothCoeff0 = in->smoothCoefSurr;
2864 cmd.cropEnable = in->cropEnable;
2865 cmd.sharpThresholdE1 = in->sharpThreshE1;
2866 cmd.sharpDegreeK1 = in->sharpK1;
2867 cmd.sharpDegreeK2 = in->sharpK2;
2868 cmd.normalizeFactor = in->normalizeFactor;
2869 cmd.sharpThresholdE2 = in->sharpThreshE2;
2870 cmd.sharpThresholdE3 = in->sharpThreshE3;
2871 cmd.sharpThresholdE4 = in->sharpThreshE4;
2872 cmd.sharpThresholdE5 = in->sharpThreshE5;
2873 cmd.F1Coeff0 = in->filter1Coefficients[0];
2874 cmd.F1Coeff1 = in->filter1Coefficients[1];
2875 cmd.F1Coeff2 = in->filter1Coefficients[2];
2876 cmd.F1Coeff3 = in->filter1Coefficients[3];
2877 cmd.F1Coeff4 = in->filter1Coefficients[4];
2878 cmd.F1Coeff5 = in->filter1Coefficients[5];
2879 cmd.F1Coeff6 = in->filter1Coefficients[6];
2880 cmd.F1Coeff7 = in->filter1Coefficients[7];
2881 cmd.F1Coeff8 = in->filter1Coefficients[8];
2882 cmd.F2Coeff0 = in->filter2Coefficients[0];
2883 cmd.F2Coeff1 = in->filter2Coefficients[1];
2884 cmd.F2Coeff2 = in->filter2Coefficients[2];
2885 cmd.F2Coeff3 = in->filter2Coefficients[3];
2886 cmd.F2Coeff4 = in->filter2Coefficients[4];
2887 cmd.F2Coeff5 = in->filter2Coefficients[5];
2888 cmd.F2Coeff6 = in->filter2Coefficients[6];
2889 cmd.F2Coeff7 = in->filter2Coefficients[7];
2890 cmd.F2Coeff8 = in->filter2Coefficients[8];
2891
2892 vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
2893 (uint32_t *)&cmd, sizeof(cmd));
2894}
2895
2896void vfe_asf_config(struct vfe_cmd_asf_config *in)
2897{
2898 struct vfe_asf_update cmd;
2899 struct vfe_asfcrop_cfg cmd2;
2900
2901 memset(&cmd, 0, sizeof(cmd));
2902 memset(&cmd2, 0, sizeof(cmd2));
2903
2904 ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
2905
2906 cmd.smoothEnable = in->smoothFilterEnabled;
2907 cmd.sharpMode = in->sharpMode;
2908 cmd.smoothCoeff0 = in->smoothCoefCenter;
2909 cmd.smoothCoeff1 = in->smoothCoefSurr;
2910 cmd.cropEnable = in->cropEnable;
2911 cmd.sharpThresholdE1 = in->sharpThreshE1;
2912 cmd.sharpDegreeK1 = in->sharpK1;
2913 cmd.sharpDegreeK2 = in->sharpK2;
2914 cmd.normalizeFactor = in->normalizeFactor;
2915 cmd.sharpThresholdE2 = in->sharpThreshE2;
2916 cmd.sharpThresholdE3 = in->sharpThreshE3;
2917 cmd.sharpThresholdE4 = in->sharpThreshE4;
2918 cmd.sharpThresholdE5 = in->sharpThreshE5;
2919 cmd.F1Coeff0 = in->filter1Coefficients[0];
2920 cmd.F1Coeff1 = in->filter1Coefficients[1];
2921 cmd.F1Coeff2 = in->filter1Coefficients[2];
2922 cmd.F1Coeff3 = in->filter1Coefficients[3];
2923 cmd.F1Coeff4 = in->filter1Coefficients[4];
2924 cmd.F1Coeff5 = in->filter1Coefficients[5];
2925 cmd.F1Coeff6 = in->filter1Coefficients[6];
2926 cmd.F1Coeff7 = in->filter1Coefficients[7];
2927 cmd.F1Coeff8 = in->filter1Coefficients[8];
2928 cmd.F2Coeff0 = in->filter2Coefficients[0];
2929 cmd.F2Coeff1 = in->filter2Coefficients[1];
2930 cmd.F2Coeff2 = in->filter2Coefficients[2];
2931 cmd.F2Coeff3 = in->filter2Coefficients[3];
2932 cmd.F2Coeff4 = in->filter2Coefficients[4];
2933 cmd.F2Coeff5 = in->filter2Coefficients[5];
2934 cmd.F2Coeff6 = in->filter2Coefficients[6];
2935 cmd.F2Coeff7 = in->filter2Coefficients[7];
2936 cmd.F2Coeff8 = in->filter2Coefficients[8];
2937
2938 vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
2939 (uint32_t *)&cmd, sizeof(cmd));
2940
2941 cmd2.firstLine = in->cropFirstLine;
2942 cmd2.lastLine = in->cropLastLine;
2943 cmd2.firstPixel = in->cropFirstPixel;
2944 cmd2.lastPixel = in->cropLastPixel;
2945
2946 vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG,
2947 (uint32_t *)&cmd2, sizeof(cmd2));
2948}
2949
2950void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in)
2951{
2952 struct vfe_wb_cfg cmd;
2953 memset(&cmd, 0, sizeof(cmd));
2954
2955 ctrl->vfeModuleEnableLocal.whiteBalanceEnable =
2956 in->enable;
2957
2958 cmd.ch0Gain = in->ch0Gain;
2959 cmd.ch1Gain = in->ch1Gain;
2960 cmd.ch2Gain = in->ch2Gain;
2961
2962 vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG,
2963 (uint32_t *)&cmd, sizeof(cmd));
2964}
2965
2966void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in)
2967{
2968 struct vfe_chroma_suppress_cfg cmd;
2969 memset(&cmd, 0, sizeof(cmd));
2970
2971 ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable;
2972
2973 cmd.m1 = in->m1;
2974 cmd.m3 = in->m3;
2975 cmd.n1 = in->n1;
2976 cmd.n3 = in->n3;
2977 cmd.mm1 = in->mm1;
2978 cmd.nn1 = in->nn1;
2979
2980 vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0,
2981 (uint32_t *)&cmd, sizeof(cmd));
2982}
2983
2984void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in)
2985{
2986 struct vfe_rolloff_cfg cmd;
2987 memset(&cmd, 0, sizeof(cmd));
2988
2989 ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable;
2990
2991 cmd.gridWidth = in->gridWidth;
2992 cmd.gridHeight = in->gridHeight;
2993 cmd.yDelta = in->yDelta;
2994 cmd.gridX = in->gridXIndex;
2995 cmd.gridY = in->gridYIndex;
2996 cmd.pixelX = in->gridPixelXIndex;
2997 cmd.pixelY = in->gridPixelYIndex;
2998 cmd.yDeltaAccum = in->yDeltaAccum;
2999
3000 vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0,
3001 (uint32_t *)&cmd, sizeof(cmd));
3002
3003 vfe_write_lens_roll_off_table(in);
3004}
3005
3006void vfe_chroma_subsample_config(
3007 struct vfe_cmd_chroma_subsample_config *in)
3008{
3009 struct vfe_chromasubsample_cfg cmd;
3010 memset(&cmd, 0, sizeof(cmd));
3011
3012 ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable;
3013
3014 cmd.hCositedPhase = in->hCositedPhase;
3015 cmd.vCositedPhase = in->vCositedPhase;
3016 cmd.hCosited = in->hCosited;
3017 cmd.vCosited = in->vCosited;
3018 cmd.hsubSampleEnable = in->hsubSampleEnable;
3019 cmd.vsubSampleEnable = in->vsubSampleEnable;
3020 cmd.cropEnable = in->cropEnable;
3021 cmd.cropWidthLastPixel = in->cropWidthLastPixel;
3022 cmd.cropWidthFirstPixel = in->cropWidthFirstPixel;
3023 cmd.cropHeightLastLine = in->cropHeightLastLine;
3024 cmd.cropHeightFirstLine = in->cropHeightFirstLine;
3025
3026 vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG,
3027 (uint32_t *)&cmd, sizeof(cmd));
3028}
3029
3030void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in)
3031{
3032 struct vfe_chroma_enhance_cfg cmd;
3033 struct vfe_color_convert_cfg cmd2;
3034
3035 memset(&cmd, 0, sizeof(cmd));
3036 memset(&cmd2, 0, sizeof(cmd2));
3037
3038 ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable;
3039
3040 cmd.ap = in->ap;
3041 cmd.am = in->am;
3042 cmd.bp = in->bp;
3043 cmd.bm = in->bm;
3044 cmd.cp = in->cp;
3045 cmd.cm = in->cm;
3046 cmd.dp = in->dp;
3047 cmd.dm = in->dm;
3048 cmd.kcb = in->kcb;
3049 cmd.kcr = in->kcr;
3050
3051 cmd2.v0 = in->RGBtoYConversionV0;
3052 cmd2.v1 = in->RGBtoYConversionV1;
3053 cmd2.v2 = in->RGBtoYConversionV2;
3054 cmd2.ConvertOffset = in->RGBtoYConversionOffset;
3055
3056 vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A,
3057 (uint32_t *)&cmd, sizeof(cmd));
3058
3059 vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0,
3060 (uint32_t *)&cmd2, sizeof(cmd2));
3061}
3062
3063void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in)
3064{
3065 struct vfe_scaler2_cfg cmd;
3066
3067 memset(&cmd, 0, sizeof(cmd));
3068
3069 ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable;
3070
3071 cmd.hEnable = in->hconfig.enable;
3072 cmd.vEnable = in->vconfig.enable;
3073 cmd.inWidth = in->hconfig.inputSize;
3074 cmd.outWidth = in->hconfig.outputSize;
3075 cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor;
3076 cmd.horizInterResolution = in->hconfig.interpolationResolution;
3077 cmd.inHeight = in->vconfig.inputSize;
3078 cmd.outHeight = in->vconfig.outputSize;
3079 cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor;
3080 cmd.vertInterResolution = in->vconfig.interpolationResolution;
3081
3082 vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG,
3083 (uint32_t *)&cmd, sizeof(cmd));
3084}
3085
3086void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in)
3087{
3088 struct vfe_scaler2_cfg cmd;
3089
3090 memset(&cmd, 0, sizeof(cmd));
3091
3092 ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable;
3093
3094 cmd.hEnable = in->hconfig.enable;
3095 cmd.vEnable = in->vconfig.enable;
3096 cmd.inWidth = in->hconfig.inputSize;
3097 cmd.outWidth = in->hconfig.outputSize;
3098 cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor;
3099 cmd.horizInterResolution = in->hconfig.interpolationResolution;
3100 cmd.inHeight = in->vconfig.inputSize;
3101 cmd.outHeight = in->vconfig.outputSize;
3102 cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor;
3103 cmd.vertInterResolution = in->vconfig.interpolationResolution;
3104
3105 vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG,
3106 (uint32_t *)&cmd, sizeof(cmd));
3107}
3108
3109void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in)
3110{
3111 struct vfe_main_scaler_cfg cmd;
3112
3113 memset(&cmd, 0, sizeof(cmd));
3114
3115 ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable;
3116
3117 cmd.hEnable = in->hconfig.enable;
3118 cmd.vEnable = in->vconfig.enable;
3119 cmd.inWidth = in->hconfig.inputSize;
3120 cmd.outWidth = in->hconfig.outputSize;
3121 cmd.horizPhaseMult = in->hconfig.phaseMultiplicationFactor;
3122 cmd.horizInterResolution = in->hconfig.interpolationResolution;
3123 cmd.horizMNInit = in->MNInitH.MNCounterInit;
3124 cmd.horizPhaseInit = in->MNInitH.phaseInit;
3125 cmd.inHeight = in->vconfig.inputSize;
3126 cmd.outHeight = in->vconfig.outputSize;
3127 cmd.vertPhaseMult = in->vconfig.phaseMultiplicationFactor;
3128 cmd.vertInterResolution = in->vconfig.interpolationResolution;
3129 cmd.vertMNInit = in->MNInitV.MNCounterInit;
3130 cmd.vertPhaseInit = in->MNInitV.phaseInit;
3131
3132 vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG,
3133 (uint32_t *)&cmd, sizeof(cmd));
3134}
3135
3136void vfe_stats_wb_exp_stop(void)
3137{
3138 ctrl->vfeStatsCmdLocal.axwEnable = FALSE;
3139 ctrl->vfeImaskLocal.awbPingpongIrq = FALSE;
3140}
3141
3142void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in)
3143{
3144 struct vfe_statsawb_update cmd;
3145 struct vfe_statsawbae_update cmd2;
3146
3147 memset(&cmd, 0, sizeof(cmd));
3148 memset(&cmd2, 0, sizeof(cmd2));
3149
3150 cmd.m1 = in->awbMCFG[0];
3151 cmd.m2 = in->awbMCFG[1];
3152 cmd.m3 = in->awbMCFG[2];
3153 cmd.m4 = in->awbMCFG[3];
3154 cmd.c1 = in->awbCCFG[0];
3155 cmd.c2 = in->awbCCFG[1];
3156 cmd.c3 = in->awbCCFG[2];
3157 cmd.c4 = in->awbCCFG[3];
3158 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
3159 (uint32_t *)&cmd, sizeof(cmd));
3160
3161 cmd2.aeRegionCfg = in->wbExpRegions;
3162 cmd2.aeSubregionCfg = in->wbExpSubRegion;
3163 cmd2.awbYMin = in->awbYMin;
3164 cmd2.awbYMax = in->awbYMax;
3165 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
3166 (uint32_t *)&cmd2, sizeof(cmd2));
3167}
3168
3169void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in)
3170{
3171 struct vfe_statsaf_update cmd;
3172 memset(&cmd, 0, sizeof(cmd));
3173
3174 cmd.windowVOffset = in->windowVOffset;
3175 cmd.windowHOffset = in->windowHOffset;
3176 cmd.windowMode = in->windowMode;
3177 cmd.windowHeight = in->windowHeight;
3178 cmd.windowWidth = in->windowWidth;
3179
3180 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
3181 (uint32_t *)&cmd, sizeof(cmd));
3182}
3183
3184void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in)
3185{
3186 struct vfe_statsawb_update cmd;
3187 struct vfe_statsawbae_update cmd2;
3188 struct vfe_statsaxw_hdr_cfg cmd3;
3189
3190 ctrl->vfeStatsCmdLocal.axwEnable = in->enable;
3191 ctrl->vfeImaskLocal.awbPingpongIrq = TRUE;
3192
3193 memset(&cmd, 0, sizeof(cmd));
3194 memset(&cmd2, 0, sizeof(cmd2));
3195 memset(&cmd3, 0, sizeof(cmd3));
3196
3197 cmd.m1 = in->awbMCFG[0];
3198 cmd.m2 = in->awbMCFG[1];
3199 cmd.m3 = in->awbMCFG[2];
3200 cmd.m4 = in->awbMCFG[3];
3201 cmd.c1 = in->awbCCFG[0];
3202 cmd.c2 = in->awbCCFG[1];
3203 cmd.c3 = in->awbCCFG[2];
3204 cmd.c4 = in->awbCCFG[3];
3205 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
3206 (uint32_t *)&cmd, sizeof(cmd));
3207
3208 cmd2.aeRegionCfg = in->wbExpRegions;
3209 cmd2.aeSubregionCfg = in->wbExpSubRegion;
3210 cmd2.awbYMin = in->awbYMin;
3211 cmd2.awbYMax = in->awbYMax;
3212 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
3213 (uint32_t *)&cmd2, sizeof(cmd2));
3214
3215 cmd3.axwHeader = in->axwHeader;
3216 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER,
3217 (uint32_t *)&cmd3, sizeof(cmd3));
3218}
3219
3220void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in)
3221{
3222 struct vfe_statsaf_update cmd;
3223 struct vfe_statsaf_cfg cmd2;
3224
3225 memset(&cmd, 0, sizeof(cmd));
3226 memset(&cmd2, 0, sizeof(cmd2));
3227
3228ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable;
3229ctrl->vfeImaskLocal.afPingpongIrq = TRUE;
3230
3231 cmd.windowVOffset = in->windowVOffset;
3232 cmd.windowHOffset = in->windowHOffset;
3233 cmd.windowMode = in->windowMode;
3234 cmd.windowHeight = in->windowHeight;
3235 cmd.windowWidth = in->windowWidth;
3236
3237 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
3238 (uint32_t *)&cmd, sizeof(cmd));
3239
3240 cmd2.a00 = in->highPassCoef[0];
3241 cmd2.a04 = in->highPassCoef[1];
3242 cmd2.a20 = in->highPassCoef[2];
3243 cmd2.a21 = in->highPassCoef[3];
3244 cmd2.a22 = in->highPassCoef[4];
3245 cmd2.a23 = in->highPassCoef[5];
3246 cmd2.a24 = in->highPassCoef[6];
3247 cmd2.fvMax = in->metricMax;
3248 cmd2.fvMetric = in->metricSelection;
3249 cmd2.afHeader = in->bufferHeader;
3250 cmd2.entry00 = in->gridForMultiWindows[0];
3251 cmd2.entry01 = in->gridForMultiWindows[1];
3252 cmd2.entry02 = in->gridForMultiWindows[2];
3253 cmd2.entry03 = in->gridForMultiWindows[3];
3254 cmd2.entry10 = in->gridForMultiWindows[4];
3255 cmd2.entry11 = in->gridForMultiWindows[5];
3256 cmd2.entry12 = in->gridForMultiWindows[6];
3257 cmd2.entry13 = in->gridForMultiWindows[7];
3258 cmd2.entry20 = in->gridForMultiWindows[8];
3259 cmd2.entry21 = in->gridForMultiWindows[9];
3260 cmd2.entry22 = in->gridForMultiWindows[10];
3261 cmd2.entry23 = in->gridForMultiWindows[11];
3262 cmd2.entry30 = in->gridForMultiWindows[12];
3263 cmd2.entry31 = in->gridForMultiWindows[13];
3264 cmd2.entry32 = in->gridForMultiWindows[14];
3265 cmd2.entry33 = in->gridForMultiWindows[15];
3266
3267 vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0,
3268 (uint32_t *)&cmd2, sizeof(cmd2));
3269}
3270
3271void vfe_stats_setting(struct vfe_cmd_stats_setting *in)
3272{
3273 struct vfe_statsframe cmd1;
3274 struct vfe_busstats_wrprio cmd2;
3275
3276 memset(&cmd1, 0, sizeof(cmd1));
3277 memset(&cmd2, 0, sizeof(cmd2));
3278
3279 ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
3280 ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
3281 ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
3282
3283 ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
3284 ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
3285 ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
3286
3287 cmd1.lastPixel = in->frameHDimension;
3288 cmd1.lastLine = in->frameVDimension;
3289 vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE,
3290 (uint32_t *)&cmd1, sizeof(cmd1));
3291
3292 cmd2.afBusPriority = in->afBusPriority;
3293 cmd2.awbBusPriority = in->awbBusPriority;
3294 cmd2.histBusPriority = in->histBusPriority;
3295 cmd2.afBusPriorityEn = in->afBusPrioritySelection;
3296 cmd2.awbBusPriorityEn = in->awbBusPrioritySelection;
3297 cmd2.histBusPriorityEn = in->histBusPrioritySelection;
3298
3299 vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY,
3300 (uint32_t *)&cmd2, sizeof(cmd2));
3301
3302 /* Program the bus ping pong address for statistics modules. */
3303 writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
3304 writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
3305 writel(in->awbBuffer[0],
3306 ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
3307 writel(in->awbBuffer[1],
3308 ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
3309 writel(in->histBuffer[0],
3310 ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
3311 writel(in->histBuffer[1],
3312 ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
3313}
3314
3315void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in)
3316{
3317 struct VFE_AxiInputCmdType cmd;
3318 uint32_t xSizeWord, axiRdUnpackPattern;
3319 uint8_t axiInputPpw;
3320 uint32_t busPingpongRdIrqEnable;
3321
3322 ctrl->vfeImaskLocal.rdPingpongIrq = TRUE;
3323
3324 switch (in->pixelSize) {
3325 case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
3326 ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT;
3327 break;
3328
3329 case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
3330 ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT;
3331 break;
3332
3333 case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
3334 default:
3335 ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT;
3336 break;
3337 }
3338
3339 memset(&cmd, 0, sizeof(cmd));
3340
3341 switch (in->pixelSize) {
3342 case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
3343 axiInputPpw = 6;
3344 axiRdUnpackPattern = 0xD43210;
3345 break;
3346
3347 case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
3348 axiInputPpw = 5;
3349 axiRdUnpackPattern = 0xC3210;
3350 break;
3351
3352 case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
3353 default:
3354 axiInputPpw = 8;
3355 axiRdUnpackPattern = 0xF6543210;
3356 break;
3357 }
3358
3359 xSizeWord =
3360 ((((in->xOffset % axiInputPpw) + in->xSize) +
3361 (axiInputPpw-1)) / axiInputPpw) - 1;
3362
3363 cmd.stripeStartAddr0 = in->fragAddr[0];
3364 cmd.stripeStartAddr1 = in->fragAddr[1];
3365 cmd.stripeStartAddr2 = in->fragAddr[2];
3366 cmd.stripeStartAddr3 = in->fragAddr[3];
3367 cmd.ySize = in->ySize;
3368 cmd.yOffsetDelta = 0;
3369 cmd.xSizeWord = xSizeWord;
3370 cmd.burstLength = 1;
3371 cmd.NumOfRows = in->numOfRows;
3372 cmd.RowIncrement =
3373 (in->rowIncrement + (axiInputPpw-1))/axiInputPpw;
3374 cmd.mainUnpackHeight = in->ySize;
3375 cmd.mainUnpackWidth = in->xSize - 1;
3376 cmd.mainUnpackHbiSel = (uint32_t)in->unpackHbi;
3377 cmd.mainUnpackPhase = in->unpackPhase;
3378 cmd.unpackPattern = axiRdUnpackPattern;
3379 cmd.padLeft = in->padRepeatCountLeft;
3380 cmd.padRight = in->padRepeatCountRight;
3381 cmd.padTop = in->padRepeatCountTop;
3382 cmd.padBottom = in->padRepeatCountBottom;
3383 cmd.leftUnpackPattern0 = in->padLeftComponentSelectCycle0;
3384 cmd.leftUnpackPattern1 = in->padLeftComponentSelectCycle1;
3385 cmd.leftUnpackPattern2 = in->padLeftComponentSelectCycle2;
3386 cmd.leftUnpackPattern3 = in->padLeftComponentSelectCycle3;
3387 cmd.leftUnpackStop0 = in->padLeftStopCycle0;
3388 cmd.leftUnpackStop1 = in->padLeftStopCycle1;
3389 cmd.leftUnpackStop2 = in->padLeftStopCycle2;
3390 cmd.leftUnpackStop3 = in->padLeftStopCycle3;
3391 cmd.rightUnpackPattern0 = in->padRightComponentSelectCycle0;
3392 cmd.rightUnpackPattern1 = in->padRightComponentSelectCycle1;
3393 cmd.rightUnpackPattern2 = in->padRightComponentSelectCycle2;
3394 cmd.rightUnpackPattern3 = in->padRightComponentSelectCycle3;
3395 cmd.rightUnpackStop0 = in->padRightStopCycle0;
3396 cmd.rightUnpackStop1 = in->padRightStopCycle1;
3397 cmd.rightUnpackStop2 = in->padRightStopCycle2;
3398 cmd.rightUnpackStop3 = in->padRightStopCycle3;
3399 cmd.topUnapckPattern = in->padTopLineCount;
3400 cmd.bottomUnapckPattern = in->padBottomLineCount;
3401
3402 /* program vfe_bus_cfg */
3403 vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0,
3404 (uint32_t *)&cmd, sizeof(cmd));
3405
3406 /* hacking code, put it to default value */
3407 busPingpongRdIrqEnable = 0xf;
3408
3409 writel(busPingpongRdIrqEnable,
3410 ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
3411}
3412
3413void vfe_stats_config(struct vfe_cmd_stats_setting *in)
3414{
3415 ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
3416 ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
3417 ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
3418
3419 ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
3420 ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
3421 ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
3422
3423 vfe_stats_setting(in);
3424}
3425
3426void vfe_axi_output_config(
3427 struct vfe_cmd_axi_output_config *in)
3428{
3429 /* local variable */
3430 uint32_t *pcircle;
3431 uint32_t *pdest;
3432 uint32_t *psrc;
3433 uint8_t i;
3434 uint8_t fcnt;
3435 uint16_t axioutpw = 8;
3436
3437 /* parameters check, condition and usage mode check */
3438 ctrl->encPath.fragCount = in->output2.fragmentCount;
3439 if (ctrl->encPath.fragCount > 1)
3440 ctrl->encPath.multiFrag = TRUE;
3441
3442 ctrl->viewPath.fragCount = in->output1.fragmentCount;
3443 if (ctrl->viewPath.fragCount > 1)
3444 ctrl->viewPath.multiFrag = TRUE;
3445
3446 /* VFE_BUS_CFG. raw data size */
3447 ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize;
3448
3449 switch (in->outputDataSize) {
3450 case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
3451 axioutpw = 8;
3452 break;
3453
3454 case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
3455 axioutpw = 6;
3456 break;
3457
3458 case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
3459 axioutpw = 5;
3460 break;
3461 }
3462
3463 ctrl->axiOutputMode = in->outputMode;
3464
3465 CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode);
3466
3467 switch (ctrl->axiOutputMode) {
3468 case VFE_AXI_OUTPUT_MODE_Output1: {
3469 ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE;
3470 ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
3471 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3472 VFE_RAW_OUTPUT_DISABLED;
3473
3474 ctrl->encPath.pathEnabled = FALSE;
3475 ctrl->vfeImaskLocal.encIrq = FALSE;
3476 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3477 VFE_COMP_IRQ_BOTH_Y_CBCR;
3478
3479 ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE;
3480 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = FALSE;
3481 ctrl->viewPath.pathEnabled = TRUE;
3482 ctrl->vfeImaskLocal.viewIrq = TRUE;
3483 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3484 VFE_COMP_IRQ_BOTH_Y_CBCR;
3485
3486 ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE;
3487 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
3488
3489 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3490 ctrl->encPath.multiFrag)
3491 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3492
3493 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3494 ctrl->encPath.multiFrag)
3495 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3496
3497 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3498 ctrl->viewPath.multiFrag)
3499 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3500
3501 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3502 ctrl->viewPath.multiFrag)
3503 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3504 } /* VFE_AXI_OUTPUT_MODE_Output1 */
3505 break;
3506
3507 case VFE_AXI_OUTPUT_MODE_Output2: {
3508 ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE;
3509 ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
3510 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3511 VFE_RAW_OUTPUT_DISABLED;
3512
3513 ctrl->encPath.pathEnabled = TRUE;
3514 ctrl->vfeImaskLocal.encIrq = TRUE;
3515 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3516 VFE_COMP_IRQ_BOTH_Y_CBCR;
3517
3518 ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE;
3519 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE;
3520
3521 ctrl->viewPath.pathEnabled = FALSE;
3522 ctrl->vfeImaskLocal.viewIrq = FALSE;
3523 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3524 VFE_COMP_IRQ_BOTH_Y_CBCR;
3525
3526 ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE;
3527 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE;
3528
3529 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3530 ctrl->encPath.multiFrag)
3531 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3532
3533 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3534 ctrl->encPath.multiFrag)
3535 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3536
3537 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3538 ctrl->viewPath.multiFrag)
3539 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3540
3541 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3542 ctrl->viewPath.multiFrag)
3543 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3544 } /* VFE_AXI_OUTPUT_MODE_Output2 */
3545 break;
3546
3547 case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: {
3548 ctrl->vfeCamifConfigLocal.camif2BusEnable = FALSE;
3549 ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
3550 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3551 VFE_RAW_OUTPUT_DISABLED;
3552
3553 ctrl->encPath.pathEnabled = TRUE;
3554 ctrl->vfeImaskLocal.encIrq = TRUE;
3555 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3556 VFE_COMP_IRQ_BOTH_Y_CBCR;
3557
3558 ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE;
3559 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE;
3560 ctrl->viewPath.pathEnabled = TRUE;
3561 ctrl->vfeImaskLocal.viewIrq = TRUE;
3562 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3563 VFE_COMP_IRQ_BOTH_Y_CBCR;
3564
3565 ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE;
3566 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
3567
3568 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3569 ctrl->encPath.multiFrag)
3570 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3571
3572 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3573 ctrl->encPath.multiFrag)
3574 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3575
3576 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3577 ctrl->viewPath.multiFrag)
3578 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3579
3580 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3581 ctrl->viewPath.multiFrag)
3582 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3583 } /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */
3584 break;
3585
3586 case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: {
3587 /* For raw snapshot, we need both ping and pong buffer
3588 * initialized to the same address. Otherwise, if we
3589 * leave the pong buffer to NULL, there will be axi_error.
3590 * Note that ideally we should deal with this at upper layer,
3591 * which is in msm_vfe8x.c */
3592 if (!in->output2.outputCbcr.outFragments[1][0]) {
3593 in->output2.outputCbcr.outFragments[1][0] =
3594 in->output2.outputCbcr.outFragments[0][0];
3595 }
3596
3597 ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE;
3598 ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE;
3599 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3600 VFE_RAW_OUTPUT_ENC_CBCR_PATH;
3601
3602 ctrl->encPath.pathEnabled = TRUE;
3603 ctrl->vfeImaskLocal.encIrq = TRUE;
3604 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3605 VFE_COMP_IRQ_CBCR_ONLY;
3606
3607 ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE;
3608 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE;
3609
3610 ctrl->viewPath.pathEnabled = FALSE;
3611 ctrl->vfeImaskLocal.viewIrq = FALSE;
3612 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3613 VFE_COMP_IRQ_BOTH_Y_CBCR;
3614
3615 ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE;
3616 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = FALSE;
3617
3618 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3619 ctrl->encPath.multiFrag)
3620 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3621
3622 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3623 ctrl->encPath.multiFrag)
3624 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3625
3626 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3627 ctrl->viewPath.multiFrag)
3628 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3629
3630 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3631 ctrl->viewPath.multiFrag)
3632 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3633 } /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */
3634 break;
3635
3636 case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: {
3637 ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE;
3638 ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
3639 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3640 VFE_RAW_OUTPUT_VIEW_CBCR_PATH;
3641
3642 ctrl->encPath.pathEnabled = TRUE;
3643 ctrl->vfeImaskLocal.encIrq = TRUE;
3644 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3645 VFE_COMP_IRQ_BOTH_Y_CBCR;
3646
3647 ctrl->vfeBusConfigLocal.encYWrPathEn = TRUE;
3648 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE;
3649
3650 ctrl->viewPath.pathEnabled = TRUE;
3651 ctrl->vfeImaskLocal.viewIrq = TRUE;
3652 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3653 VFE_COMP_IRQ_CBCR_ONLY;
3654
3655 ctrl->vfeBusConfigLocal.viewYWrPathEn = FALSE;
3656 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
3657
3658 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3659 ctrl->encPath.multiFrag)
3660 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3661
3662 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3663 ctrl->encPath.multiFrag)
3664 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3665
3666 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3667 ctrl->viewPath.multiFrag)
3668 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3669
3670 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3671 ctrl->viewPath.multiFrag)
3672 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3673 } /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */
3674 break;
3675
3676 case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: {
3677 ctrl->vfeCamifConfigLocal.camif2BusEnable = TRUE;
3678 ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
3679 ctrl->vfeBusConfigLocal.rawWritePathSelect =
3680 VFE_RAW_OUTPUT_ENC_CBCR_PATH;
3681
3682 ctrl->encPath.pathEnabled = TRUE;
3683 ctrl->vfeImaskLocal.encIrq = TRUE;
3684 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3685 VFE_COMP_IRQ_CBCR_ONLY;
3686
3687 ctrl->vfeBusConfigLocal.encYWrPathEn = FALSE;
3688 ctrl->vfeBusConfigLocal.encCbcrWrPathEn = TRUE;
3689
3690 ctrl->viewPath.pathEnabled = TRUE;
3691 ctrl->vfeImaskLocal.viewIrq = TRUE;
3692
3693 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3694 VFE_COMP_IRQ_BOTH_Y_CBCR;
3695
3696 ctrl->vfeBusConfigLocal.viewYWrPathEn = TRUE;
3697 ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
3698
3699 if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
3700 ctrl->encPath.multiFrag)
3701 ctrl->vfeImaskLocal.encYPingpongIrq = TRUE;
3702
3703 if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
3704 ctrl->encPath.multiFrag)
3705 ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
3706
3707 if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
3708 ctrl->viewPath.multiFrag)
3709 ctrl->vfeImaskLocal.viewYPingpongIrq = TRUE;
3710
3711 if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
3712 ctrl->viewPath.multiFrag)
3713 ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
3714 } /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */
3715 break;
3716
3717 case VFE_AXI_LAST_OUTPUT_MODE_ENUM:
3718 break;
3719 } /* switch */
3720
3721 /* Save the addresses for each path. */
3722 /* output2 path */
3723 fcnt = ctrl->encPath.fragCount;
3724
3725 pcircle = ctrl->encPath.yPath.addressBuffer;
3726 pdest = ctrl->encPath.nextFrameAddrBuf;
3727
3728 psrc = &(in->output2.outputY.outFragments[0][0]);
3729 for (i = 0; i < fcnt; i++)
3730 *pcircle++ = *psrc++;
3731
3732 psrc = &(in->output2.outputY.outFragments[1][0]);
3733 for (i = 0; i < fcnt; i++)
3734 *pcircle++ = *psrc++;
3735
3736 psrc = &(in->output2.outputY.outFragments[2][0]);
3737 for (i = 0; i < fcnt; i++)
3738 *pdest++ = *psrc++;
3739
3740 pcircle = ctrl->encPath.cbcrPath.addressBuffer;
3741
3742 psrc = &(in->output2.outputCbcr.outFragments[0][0]);
3743 for (i = 0; i < fcnt; i++)
3744 *pcircle++ = *psrc++;
3745
3746 psrc = &(in->output2.outputCbcr.outFragments[1][0]);
3747 for (i = 0; i < fcnt; i++)
3748 *pcircle++ = *psrc++;
3749
3750 psrc = &(in->output2.outputCbcr.outFragments[2][0]);
3751 for (i = 0; i < fcnt; i++)
3752 *pdest++ = *psrc++;
3753
3754 vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath);
3755
3756 ctrl->encPath.ackPending = FALSE;
3757 ctrl->encPath.currentFrame = ping;
3758 ctrl->encPath.whichOutputPath = 1;
3759 ctrl->encPath.yPath.fragIndex = 2;
3760 ctrl->encPath.cbcrPath.fragIndex = 2;
3761 ctrl->encPath.yPath.hwCurrentFlag = ping;
3762 ctrl->encPath.cbcrPath.hwCurrentFlag = ping;
3763
3764 /* output1 path */
3765 pcircle = ctrl->viewPath.yPath.addressBuffer;
3766 pdest = ctrl->viewPath.nextFrameAddrBuf;
3767 fcnt = ctrl->viewPath.fragCount;
3768
3769 psrc = &(in->output1.outputY.outFragments[0][0]);
3770 for (i = 0; i < fcnt; i++)
3771 *pcircle++ = *psrc++;
3772
3773 psrc = &(in->output1.outputY.outFragments[1][0]);
3774 for (i = 0; i < fcnt; i++)
3775 *pcircle++ = *psrc++;
3776
3777 psrc = &(in->output1.outputY.outFragments[2][0]);
3778 for (i = 0; i < fcnt; i++)
3779 *pdest++ = *psrc++;
3780
3781 pcircle = ctrl->viewPath.cbcrPath.addressBuffer;
3782
3783 psrc = &(in->output1.outputCbcr.outFragments[0][0]);
3784 for (i = 0; i < fcnt; i++)
3785 *pcircle++ = *psrc++;
3786
3787 psrc = &(in->output1.outputCbcr.outFragments[1][0]);
3788 for (i = 0; i < fcnt; i++)
3789 *pcircle++ = *psrc++;
3790
3791 psrc = &(in->output1.outputCbcr.outFragments[2][0]);
3792 for (i = 0; i < fcnt; i++)
3793 *pdest++ = *psrc++;
3794
3795 ctrl->viewPath.ackPending = FALSE;
3796 ctrl->viewPath.currentFrame = ping;
3797 ctrl->viewPath.whichOutputPath = 0;
3798 ctrl->viewPath.yPath.fragIndex = 2;
3799 ctrl->viewPath.cbcrPath.fragIndex = 2;
3800 ctrl->viewPath.yPath.hwCurrentFlag = ping;
3801 ctrl->viewPath.cbcrPath.hwCurrentFlag = ping;
3802
3803 /* call to program the registers. */
3804 vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw);
3805}
3806
3807void vfe_camif_config(struct vfe_cmd_camif_config *in)
3808{
3809 struct vfe_camifcfg cmd;
3810 memset(&cmd, 0, sizeof(cmd));
3811
3812 CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine);
3813 CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame);
3814 CDBG("camif.window firstpixel = %d\n", in->window.firstpixel);
3815 CDBG("camif.window lastpixel = %d\n", in->window.lastpixel);
3816 CDBG("camif.window firstline = %d\n", in->window.firstline);
3817 CDBG("camif.window lastline = %d\n", in->window.lastline);
3818
3819 /* determine if epoch interrupt needs to be enabled. */
3820 if ((in->epoch1.enable == TRUE) &&
3821 (in->epoch1.lineindex <=
3822 in->frame.linesPerFrame))
3823 ctrl->vfeImaskLocal.camifEpoch1Irq = 1;
3824
3825 if ((in->epoch2.enable == TRUE) &&
3826 (in->epoch2.lineindex <=
3827 in->frame.linesPerFrame)) {
3828 ctrl->vfeImaskLocal.camifEpoch2Irq = 1;
3829 }
3830
3831 /* save the content to program CAMIF_CONFIG separately. */
3832 ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig;
3833
3834 /* EFS_Config */
3835 cmd.efsEndOfLine = in->EFS.efsendofline;
3836 cmd.efsStartOfLine = in->EFS.efsstartofline;
3837 cmd.efsEndOfFrame = in->EFS.efsendofframe;
3838 cmd.efsStartOfFrame = in->EFS.efsstartofframe;
3839
3840 /* Frame Config */
3841 cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine;
3842 cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame;
3843
3844 /* Window Width Config */
3845 cmd.windowWidthCfgLastPixel = in->window.lastpixel;
3846 cmd.windowWidthCfgFirstPixel = in->window.firstpixel;
3847
3848 /* Window Height Config */
3849 cmd.windowHeightCfglastLine = in->window.lastline;
3850 cmd.windowHeightCfgfirstLine = in->window.firstline;
3851
3852 /* Subsample 1 Config */
3853 cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask;
3854 cmd.subsample1CfgLineSkip = in->subsample.lineskipmask;
3855
3856 /* Subsample 2 Config */
3857 cmd.subsample2CfgFrameSkip = in->subsample.frameskip;
3858 cmd.subsample2CfgFrameSkipMode = in->subsample.frameskipmode;
3859 cmd.subsample2CfgPixelSkipWrap = in->subsample.pixelskipwrap;
3860
3861 /* Epoch Interrupt */
3862 cmd.epoch1Line = in->epoch1.lineindex;
3863 cmd.epoch2Line = in->epoch2.lineindex;
3864
3865 vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG,
3866 (uint32_t *)&cmd, sizeof(cmd));
3867}
3868
3869void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in)
3870{
3871 struct vfe_fov_crop_cfg cmd;
3872 memset(&cmd, 0, sizeof(cmd));
3873
3874 ctrl->vfeModuleEnableLocal.cropEnable = in->enable;
3875
3876 /* FOV Corp, Part 1 */
3877 cmd.lastPixel = in->lastPixel;
3878 cmd.firstPixel = in->firstPixel;
3879
3880 /* FOV Corp, Part 2 */
3881 cmd.lastLine = in->lastLine;
3882 cmd.firstLine = in->firstLine;
3883
3884 vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG,
3885 (uint32_t *)&cmd, sizeof(cmd));
3886}
3887
3888void vfe_get_hw_version(struct vfe_cmd_hw_version *out)
3889{
3890 uint32_t vfeHwVersionPacked;
3891 struct vfe_hw_ver ver;
3892
3893 vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION);
3894
3895 ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked);
3896
3897 out->coreVersion = ver.coreVersion;
3898 out->minorVersion = ver.minorVersion;
3899 out->majorVersion = ver.majorVersion;
3900}
3901
3902static void vfe_reset_internal_variables(void)
3903{
3904 unsigned long flags;
3905
3906 /* local variables to program the hardware. */
3907 ctrl->vfeImaskPacked = 0;
3908 ctrl->vfeImaskCompositePacked = 0;
3909
3910 /* FALSE = disable, 1 = enable. */
3911 memset(&ctrl->vfeModuleEnableLocal, 0,
3912 sizeof(ctrl->vfeModuleEnableLocal));
3913
3914 /* 0 = disable, 1 = enable */
3915 memset(&ctrl->vfeCamifConfigLocal, 0,
3916 sizeof(ctrl->vfeCamifConfigLocal));
3917 /* 0 = disable, 1 = enable */
3918 memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal));
3919 memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal));
3920 memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal));
3921 memset(&ctrl->vfeBusPmConfigLocal, 0,
3922 sizeof(ctrl->vfeBusPmConfigLocal));
3923 memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal));
3924 memset(&ctrl->vfeInterruptNameLocal, 0,
3925 sizeof(ctrl->vfeInterruptNameLocal));
3926 memset(&ctrl->vfeDroppedFrameCounts, 0,
3927 sizeof(ctrl->vfeDroppedFrameCounts));
3928 memset(&ctrl->vfeIrqThreadMsgLocal, 0,
3929 sizeof(ctrl->vfeIrqThreadMsgLocal));
3930
3931 /* state control variables */
3932 ctrl->vfeStartAckPendingFlag = FALSE;
3933 ctrl->vfeStopAckPending = FALSE;
3934 ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0;
3935 ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
3936 VFE_COMP_IRQ_BOTH_Y_CBCR;
3937 ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
3938 VFE_COMP_IRQ_BOTH_Y_CBCR;
3939
3940 spin_lock_irqsave(&ctrl->state_lock, flags);
3941 ctrl->vstate = VFE_STATE_IDLE;
3942 spin_unlock_irqrestore(&ctrl->state_lock, flags);
3943
3944 ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM;
3945 /* 0 for continuous mode, 1 for snapshot mode */
3946 ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS;
3947 ctrl->vfeSnapShotCount = 0;
3948 ctrl->vfeStatsPingPongReloadFlag = FALSE;
3949 /* this is unsigned 32 bit integer. */
3950 ctrl->vfeFrameId = 0;
3951 ctrl->vfeFrameSkip.output1Pattern = 0xffffffff;
3952 ctrl->vfeFrameSkip.output1Period = 31;
3953 ctrl->vfeFrameSkip.output2Pattern = 0xffffffff;
3954 ctrl->vfeFrameSkip.output2Period = 31;
3955 ctrl->vfeFrameSkipPattern = 0xffffffff;
3956 ctrl->vfeFrameSkipCount = 0;
3957 ctrl->vfeFrameSkipPeriod = 31;
3958
3959 memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath));
3960 memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath));
3961
3962 ctrl->encPath.whichOutputPath = 1;
3963 ctrl->encPath.cbcrStatusBit = 5;
3964 ctrl->viewPath.whichOutputPath = 0;
3965 ctrl->viewPath.cbcrStatusBit = 7;
3966
3967 ctrl->vfeTestGenStartFlag = FALSE;
3968
3969 /* default to bank 0. */
3970 ctrl->vfeLaBankSel = 0;
3971
3972 /* default to bank 0 for all channels. */
3973 memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel));
3974
3975 /* Stats control variables. */
3976 memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl));
3977 memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl));
3978 vfe_set_stats_pingpong_address(&ctrl->afStatsControl,
3979 &ctrl->awbStatsControl);
3980}
3981
3982void vfe_reset(void)
3983{
3984 vfe_reset_internal_variables();
3985
3986 ctrl->vfeImaskLocal.resetAckIrq = TRUE;
3987 ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
3988
3989 /* disable all interrupts. */
3990 writel(VFE_DISABLE_ALL_IRQS,
3991 ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
3992
3993 /* clear all pending interrupts*/
3994 writel(VFE_CLEAR_ALL_IRQS,
3995 ctrl->vfebase + VFE_IRQ_CLEAR);
3996
3997 /* enable reset_ack interrupt. */
3998 writel(ctrl->vfeImaskPacked,
3999 ctrl->vfebase + VFE_IRQ_MASK);
4000
4001 writel(VFE_RESET_UPON_RESET_CMD,
4002 ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
4003}
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.h b/drivers/staging/dream/camera/msm_vfe8x_proc.h
deleted file mode 100644
index 91828569a4d7..000000000000
--- a/drivers/staging/dream/camera/msm_vfe8x_proc.h
+++ /dev/null
@@ -1,1549 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef __MSM_VFE8X_REG_H__
6#define __MSM_VFE8X_REG_H__
7
8#include <mach/msm_iomap.h>
9#include <mach/camera.h>
10#include "msm_vfe8x.h"
11
12/* at start of camif, bit 1:0 = 0x01:enable
13 * image data capture at frame boundary. */
14#define CAMIF_COMMAND_START 0x00000005
15
16/* bit 2= 0x1:clear the CAMIF_STATUS register
17 * value. */
18#define CAMIF_COMMAND_CLEAR 0x00000004
19
20/* at stop of vfe pipeline, for now it is assumed
21 * that camif will stop at any time. Bit 1:0 = 0x10:
22 * disable image data capture immediately. */
23#define CAMIF_COMMAND_STOP_IMMEDIATELY 0x00000002
24
25/* at stop of vfe pipeline, for now it is assumed
26 * that camif will stop at any time. Bit 1:0 = 0x00:
27 * disable image data capture at frame boundary */
28#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY 0x00000000
29
30/* to halt axi bridge */
31#define AXI_HALT 0x00000001
32
33/* clear the halt bit. */
34#define AXI_HALT_CLEAR 0x00000000
35
36/* reset the pipeline when stop command is issued.
37 * (without reset the register.) bit 26-31 = 0,
38 * domain reset, bit 0-9 = 1 for module reset, except
39 * register module. */
40#define VFE_RESET_UPON_STOP_CMD 0x000003ef
41
42/* reset the pipeline when reset command.
43 * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
44#define VFE_RESET_UPON_RESET_CMD 0x000003ff
45
46/* bit 5 is for axi status idle or busy.
47 * 1 = halted, 0 = busy */
48#define AXI_STATUS_BUSY_MASK 0x00000020
49
50/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
51 * for frame done interrupt */
52#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
53
54/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
55#define VFE_COMP_IRQ_CBCR_ONLY 2
56
57/* bit 0 = 1, only y irq triggers frame done interrupt */
58#define VFE_COMP_IRQ_Y_ONLY 1
59
60/* bit 0 = 1, PM go; bit1 = 1, PM stop */
61#define VFE_PERFORMANCE_MONITOR_GO 0x00000001
62#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
63
64/* bit 0 = 1, test gen go; bit1 = 1, test gen stop */
65#define VFE_TEST_GEN_GO 0x00000001
66#define VFE_TEST_GEN_STOP 0x00000002
67
68/* the chroma is assumed to be interpolated between
69 * the luma samples. JPEG 4:2:2 */
70#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
71
72/* constants for irq registers */
73#define VFE_DISABLE_ALL_IRQS 0
74/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS. */
75#define VFE_CLEAR_ALL_IRQS 0xffffffff
76/* imask for while waiting for stop ack, driver has already
77 * requested stop, waiting for reset irq,
78 * bit 29,28,27,26 for async timer, bit 9 for reset */
79#define VFE_IMASK_WHILE_STOPPING 0x3c000200
80
81/* when normal case, don't want to block error status.
82 * bit 0,6,20,21,22,30,31 */
83#define VFE_IMASK_ERROR_ONLY 0xC0700041
84#define VFE_REG_UPDATE_TRIGGER 1
85#define VFE_PM_BUF_MAX_CNT_MASK 0xFF
86#define VFE_DMI_CFG_DEFAULT 0x00000100
87#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
88#define VFE_AF_PINGPONG_STATUS_BIT 0x100
89#define VFE_AWB_PINGPONG_STATUS_BIT 0x200
90
91/* VFE I/O registers */
92enum {
93 VFE_HW_VERSION = 0x00000000,
94 VFE_GLOBAL_RESET_CMD = 0x00000004,
95 VFE_MODULE_RESET = 0x00000008,
96 VFE_CGC_OVERRIDE = 0x0000000C,
97 VFE_MODULE_CFG = 0x00000010,
98 VFE_CFG = 0x00000014,
99 VFE_IRQ_MASK = 0x00000018,
100 VFE_IRQ_CLEAR = 0x0000001C,
101VFE_IRQ_STATUS = 0x00000020,
102VFE_IRQ_COMPOSITE_MASK = 0x00000024,
103VFE_BUS_CMD = 0x00000028,
104VFE_BUS_CFG = 0x0000002C,
105VFE_BUS_ENC_Y_WR_PING_ADDR = 0x00000030,
106VFE_BUS_ENC_Y_WR_PONG_ADDR = 0x00000034,
107VFE_BUS_ENC_Y_WR_IMAGE_SIZE = 0x00000038,
108VFE_BUS_ENC_Y_WR_BUFFER_CFG = 0x0000003C,
109VFE_BUS_ENC_CBCR_WR_PING_ADDR = 0x00000040,
110VFE_BUS_ENC_CBCR_WR_PONG_ADDR = 0x00000044,
111VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE = 0x00000048,
112VFE_BUS_ENC_CBCR_WR_BUFFER_CFG = 0x0000004C,
113VFE_BUS_VIEW_Y_WR_PING_ADDR = 0x00000050,
114VFE_BUS_VIEW_Y_WR_PONG_ADDR = 0x00000054,
115VFE_BUS_VIEW_Y_WR_IMAGE_SIZE = 0x00000058,
116VFE_BUS_VIEW_Y_WR_BUFFER_CFG = 0x0000005C,
117VFE_BUS_VIEW_CBCR_WR_PING_ADDR = 0x00000060,
118VFE_BUS_VIEW_CBCR_WR_PONG_ADDR = 0x00000064,
119VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE = 0x00000068,
120VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG = 0x0000006C,
121VFE_BUS_STATS_AF_WR_PING_ADDR = 0x00000070,
122VFE_BUS_STATS_AF_WR_PONG_ADDR = 0x00000074,
123VFE_BUS_STATS_AWB_WR_PING_ADDR = 0x00000078,
124VFE_BUS_STATS_AWB_WR_PONG_ADDR = 0x0000007C,
125VFE_BUS_STATS_HIST_WR_PING_ADDR = 0x00000080,
126VFE_BUS_STATS_HIST_WR_PONG_ADDR = 0x00000084,
127VFE_BUS_STATS_WR_PRIORITY = 0x00000088,
128VFE_BUS_STRIPE_RD_ADDR_0 = 0x0000008C,
129VFE_BUS_STRIPE_RD_ADDR_1 = 0x00000090,
130VFE_BUS_STRIPE_RD_ADDR_2 = 0x00000094,
131VFE_BUS_STRIPE_RD_ADDR_3 = 0x00000098,
132VFE_BUS_STRIPE_RD_VSIZE = 0x0000009C,
133VFE_BUS_STRIPE_RD_HSIZE = 0x000000A0,
134VFE_BUS_STRIPE_RD_BUFFER_CFG = 0x000000A4,
135VFE_BUS_STRIPE_RD_UNPACK_CFG = 0x000000A8,
136VFE_BUS_STRIPE_RD_UNPACK = 0x000000AC,
137VFE_BUS_STRIPE_RD_PAD_SIZE = 0x000000B0,
138VFE_BUS_STRIPE_RD_PAD_L_UNPACK = 0x000000B4,
139VFE_BUS_STRIPE_RD_PAD_R_UNPACK = 0x000000B8,
140VFE_BUS_STRIPE_RD_PAD_TB_UNPACK = 0x000000BC,
141VFE_BUS_PINGPONG_IRQ_EN = 0x000000C0,
142VFE_BUS_PINGPONG_STATUS = 0x000000C4,
143VFE_BUS_PM_CMD = 0x000000C8,
144VFE_BUS_PM_CFG = 0x000000CC,
145VFE_BUS_ENC_Y_WR_PM_STATS_0 = 0x000000D0,
146VFE_BUS_ENC_Y_WR_PM_STATS_1 = 0x000000D4,
147VFE_BUS_ENC_CBCR_WR_PM_STATS_0 = 0x000000D8,
148VFE_BUS_ENC_CBCR_WR_PM_STATS_1 = 0x000000DC,
149VFE_BUS_VIEW_Y_WR_PM_STATS_0 = 0x000000E0,
150VFE_BUS_VIEW_Y_WR_PM_STATS_1 = 0x000000E4,
151VFE_BUS_VIEW_CBCR_WR_PM_STATS_0 = 0x000000E8,
152VFE_BUS_VIEW_CBCR_WR_PM_STATS_1 = 0x000000EC,
153VFE_BUS_MISR_CFG = 0x000000F4,
154VFE_BUS_MISR_MAST_CFG_0 = 0x000000F8,
155VFE_BUS_MISR_MAST_CFG_1 = 0x000000FC,
156VFE_BUS_MISR_RD_VAL = 0x00000100,
157VFE_AXI_CMD = 0x00000104,
158VFE_AXI_CFG = 0x00000108,
159VFE_AXI_STATUS = 0x0000010C,
160CAMIF_COMMAND = 0x00000110,
161CAMIF_CONFIG = 0x00000114,
162CAMIF_EFS_CONFIG = 0x00000118,
163CAMIF_FRAME_CONFIG = 0x0000011C,
164CAMIF_WINDOW_WIDTH_CONFIG = 0x00000120,
165CAMIF_WINDOW_HEIGHT_CONFIG = 0x00000124,
166CAMIF_SUBSAMPLE1_CONFIG = 0x00000128,
167CAMIF_SUBSAMPLE2_CONFIG = 0x0000012C,
168CAMIF_EPOCH_IRQ = 0x00000130,
169CAMIF_STATUS = 0x00000134,
170CAMIF_MISR = 0x00000138,
171VFE_SYNC_TIMER_CMD = 0x0000013C,
172VFE_SYNC_TIMER0_LINE_START = 0x00000140,
173VFE_SYNC_TIMER0_PIXEL_START = 0x00000144,
174VFE_SYNC_TIMER0_PIXEL_DURATION = 0x00000148,
175VFE_SYNC_TIMER1_LINE_START = 0x0000014C,
176VFE_SYNC_TIMER1_PIXEL_START = 0x00000150,
177VFE_SYNC_TIMER1_PIXEL_DURATION = 0x00000154,
178VFE_SYNC_TIMER2_LINE_START = 0x00000158,
179VFE_SYNC_TIMER2_PIXEL_START = 0x0000015C,
180VFE_SYNC_TIMER2_PIXEL_DURATION = 0x00000160,
181VFE_SYNC_TIMER_POLARITY = 0x00000164,
182VFE_ASYNC_TIMER_CMD = 0x00000168,
183VFE_ASYNC_TIMER0_CFG_0 = 0x0000016C,
184VFE_ASYNC_TIMER0_CFG_1 = 0x00000170,
185VFE_ASYNC_TIMER1_CFG_0 = 0x00000174,
186VFE_ASYNC_TIMER1_CFG_1 = 0x00000178,
187VFE_ASYNC_TIMER2_CFG_0 = 0x0000017C,
188VFE_ASYNC_TIMER2_CFG_1 = 0x00000180,
189VFE_ASYNC_TIMER3_CFG_0 = 0x00000184,
190VFE_ASYNC_TIMER3_CFG_1 = 0x00000188,
191VFE_TIMER_SEL = 0x0000018C,
192VFE_REG_UPDATE_CMD = 0x00000190,
193VFE_BLACK_EVEN_EVEN_VALUE = 0x00000194,
194VFE_BLACK_EVEN_ODD_VALUE = 0x00000198,
195VFE_BLACK_ODD_EVEN_VALUE = 0x0000019C,
196VFE_BLACK_ODD_ODD_VALUE = 0x000001A0,
197VFE_ROLLOFF_CFG_0 = 0x000001A4,
198VFE_ROLLOFF_CFG_1 = 0x000001A8,
199VFE_ROLLOFF_CFG_2 = 0x000001AC,
200VFE_DEMUX_CFG = 0x000001B0,
201VFE_DEMUX_GAIN_0 = 0x000001B4,
202VFE_DEMUX_GAIN_1 = 0x000001B8,
203VFE_DEMUX_EVEN_CFG = 0x000001BC,
204VFE_DEMUX_ODD_CFG = 0x000001C0,
205VFE_DEMOSAIC_CFG = 0x000001C4,
206VFE_DEMOSAIC_ABF_CFG_0 = 0x000001C8,
207VFE_DEMOSAIC_ABF_CFG_1 = 0x000001CC,
208VFE_DEMOSAIC_BPC_CFG_0 = 0x000001D0,
209VFE_DEMOSAIC_BPC_CFG_1 = 0x000001D4,
210VFE_DEMOSAIC_STATUS = 0x000001D8,
211VFE_CHROMA_UPSAMPLE_CFG = 0x000001DC,
212VFE_CROP_WIDTH_CFG = 0x000001E0,
213VFE_CROP_HEIGHT_CFG = 0x000001E4,
214VFE_COLOR_CORRECT_COEFF_0 = 0x000001E8,
215VFE_COLOR_CORRECT_COEFF_1 = 0x000001EC,
216VFE_COLOR_CORRECT_COEFF_2 = 0x000001F0,
217VFE_COLOR_CORRECT_COEFF_3 = 0x000001F4,
218VFE_COLOR_CORRECT_COEFF_4 = 0x000001F8,
219VFE_COLOR_CORRECT_COEFF_5 = 0x000001FC,
220VFE_COLOR_CORRECT_COEFF_6 = 0x00000200,
221VFE_COLOR_CORRECT_COEFF_7 = 0x00000204,
222VFE_COLOR_CORRECT_COEFF_8 = 0x00000208,
223VFE_COLOR_CORRECT_OFFSET_0 = 0x0000020C,
224VFE_COLOR_CORRECT_OFFSET_1 = 0x00000210,
225VFE_COLOR_CORRECT_OFFSET_2 = 0x00000214,
226VFE_COLOR_CORRECT_COEFF_Q = 0x00000218,
227VFE_LA_CFG = 0x0000021C,
228VFE_LUT_BANK_SEL = 0x00000220,
229VFE_CHROMA_ENHAN_A = 0x00000224,
230VFE_CHROMA_ENHAN_B = 0x00000228,
231VFE_CHROMA_ENHAN_C = 0x0000022C,
232VFE_CHROMA_ENHAN_D = 0x00000230,
233VFE_CHROMA_ENHAN_K = 0x00000234,
234VFE_COLOR_CONVERT_COEFF_0 = 0x00000238,
235VFE_COLOR_CONVERT_COEFF_1 = 0x0000023C,
236VFE_COLOR_CONVERT_COEFF_2 = 0x00000240,
237VFE_COLOR_CONVERT_OFFSET = 0x00000244,
238VFE_ASF_CFG = 0x00000248,
239VFE_ASF_SHARP_CFG_0 = 0x0000024C,
240VFE_ASF_SHARP_CFG_1 = 0x00000250,
241VFE_ASF_SHARP_COEFF_0 = 0x00000254,
242VFE_ASF_SHARP_COEFF_1 = 0x00000258,
243VFE_ASF_SHARP_COEFF_2 = 0x0000025C,
244VFE_ASF_SHARP_COEFF_3 = 0x00000260,
245VFE_ASF_MAX_EDGE = 0x00000264,
246VFE_ASF_CROP_WIDTH_CFG = 0x00000268,
247VFE_ASF_CROP_HEIGHT_CFG = 0x0000026C,
248VFE_SCALE_CFG = 0x00000270,
249VFE_SCALE_H_IMAGE_SIZE_CFG = 0x00000274,
250VFE_SCALE_H_PHASE_CFG = 0x00000278,
251VFE_SCALE_H_STRIPE_CFG = 0x0000027C,
252VFE_SCALE_V_IMAGE_SIZE_CFG = 0x00000280,
253VFE_SCALE_V_PHASE_CFG = 0x00000284,
254VFE_SCALE_V_STRIPE_CFG = 0x00000288,
255VFE_SCALE_Y_CFG = 0x0000028C,
256VFE_SCALE_Y_H_IMAGE_SIZE_CFG = 0x00000290,
257VFE_SCALE_Y_H_PHASE_CFG = 0x00000294,
258VFE_SCALE_Y_V_IMAGE_SIZE_CFG = 0x00000298,
259VFE_SCALE_Y_V_PHASE_CFG = 0x0000029C,
260VFE_SCALE_CBCR_CFG = 0x000002A0,
261VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG = 0x000002A4,
262VFE_SCALE_CBCR_H_PHASE_CFG = 0x000002A8,
263VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG = 0x000002AC,
264VFE_SCALE_CBCR_V_PHASE_CFG = 0x000002B0,
265VFE_WB_CFG = 0x000002B4,
266VFE_CHROMA_SUPPRESS_CFG_0 = 0x000002B8,
267VFE_CHROMA_SUPPRESS_CFG_1 = 0x000002BC,
268VFE_CHROMA_SUBSAMPLE_CFG = 0x000002C0,
269VFE_CHROMA_SUB_CROP_WIDTH_CFG = 0x000002C4,
270VFE_CHROMA_SUB_CROP_HEIGHT_CFG = 0x000002C8,
271VFE_FRAMEDROP_ENC_Y_CFG = 0x000002CC,
272VFE_FRAMEDROP_ENC_CBCR_CFG = 0x000002D0,
273VFE_FRAMEDROP_ENC_Y_PATTERN = 0x000002D4,
274VFE_FRAMEDROP_ENC_CBCR_PATTERN = 0x000002D8,
275VFE_FRAMEDROP_VIEW_Y_CFG = 0x000002DC,
276VFE_FRAMEDROP_VIEW_CBCR_CFG = 0x000002E0,
277VFE_FRAMEDROP_VIEW_Y_PATTERN = 0x000002E4,
278VFE_FRAMEDROP_VIEW_CBCR_PATTERN = 0x000002E8,
279VFE_CLAMP_MAX_CFG = 0x000002EC,
280VFE_CLAMP_MIN_CFG = 0x000002F0,
281VFE_STATS_CMD = 0x000002F4,
282VFE_STATS_AF_CFG = 0x000002F8,
283VFE_STATS_AF_DIM = 0x000002FC,
284VFE_STATS_AF_GRID_0 = 0x00000300,
285VFE_STATS_AF_GRID_1 = 0x00000304,
286VFE_STATS_AF_GRID_2 = 0x00000308,
287VFE_STATS_AF_GRID_3 = 0x0000030C,
288VFE_STATS_AF_HEADER = 0x00000310,
289VFE_STATS_AF_COEF0 = 0x00000314,
290VFE_STATS_AF_COEF1 = 0x00000318,
291VFE_STATS_AWBAE_CFG = 0x0000031C,
292VFE_STATS_AXW_HEADER = 0x00000320,
293VFE_STATS_AWB_MCFG = 0x00000324,
294VFE_STATS_AWB_CCFG1 = 0x00000328,
295VFE_STATS_AWB_CCFG2 = 0x0000032C,
296VFE_STATS_HIST_HEADER = 0x00000330,
297VFE_STATS_HIST_INNER_OFFSET = 0x00000334,
298VFE_STATS_HIST_INNER_DIM = 0x00000338,
299VFE_STATS_FRAME_SIZE = 0x0000033C,
300VFE_DMI_CFG = 0x00000340,
301VFE_DMI_ADDR = 0x00000344,
302VFE_DMI_DATA_HI = 0x00000348,
303VFE_DMI_DATA_LO = 0x0000034C,
304VFE_DMI_RAM_AUTO_LOAD_CMD = 0x00000350,
305VFE_DMI_RAM_AUTO_LOAD_STATUS = 0x00000354,
306VFE_DMI_RAM_AUTO_LOAD_CFG = 0x00000358,
307VFE_DMI_RAM_AUTO_LOAD_SEED = 0x0000035C,
308VFE_TESTBUS_SEL = 0x00000360,
309VFE_TESTGEN_CFG = 0x00000364,
310VFE_SW_TESTGEN_CMD = 0x00000368,
311VFE_HW_TESTGEN_CMD = 0x0000036C,
312VFE_HW_TESTGEN_CFG = 0x00000370,
313VFE_HW_TESTGEN_IMAGE_CFG = 0x00000374,
314VFE_HW_TESTGEN_SOF_OFFSET_CFG = 0x00000378,
315VFE_HW_TESTGEN_EOF_NOFFSET_CFG = 0x0000037C,
316VFE_HW_TESTGEN_SOL_OFFSET_CFG = 0x00000380,
317VFE_HW_TESTGEN_EOL_NOFFSET_CFG = 0x00000384,
318VFE_HW_TESTGEN_HBI_CFG = 0x00000388,
319VFE_HW_TESTGEN_VBL_CFG = 0x0000038C,
320VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390,
321VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394,
322VFE_HW_TESTGEN_COLOR_BARS_CFG = 0x00000398,
323VFE_HW_TESTGEN_RANDOM_CFG = 0x0000039C,
324VFE_SPARE = 0x000003A0,
325};
326
327#define ping 0x0
328#define pong 0x1
329
330struct vfe_bus_cfg_data {
331 boolean stripeRdPathEn;
332 boolean encYWrPathEn;
333 boolean encCbcrWrPathEn;
334 boolean viewYWrPathEn;
335 boolean viewCbcrWrPathEn;
336 enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize;
337 enum VFE_RAW_WR_PATH_SEL rawWritePathSelect;
338};
339
340struct vfe_camif_cfg_data {
341 boolean camif2OutputEnable;
342 boolean camif2BusEnable;
343 struct vfe_cmds_camif_cfg camifCfgFromCmd;
344};
345
346struct vfe_irq_composite_mask_config {
347 uint8_t encIrqComMask;
348 uint8_t viewIrqComMask;
349 uint8_t ceDoneSel;
350};
351
352/* define a structure for each output path.*/
353struct vfe_output_path {
354 uint32_t addressBuffer[8];
355 uint16_t fragIndex;
356 boolean hwCurrentFlag;
357 uint8_t *hwRegPingAddress;
358 uint8_t *hwRegPongAddress;
359};
360
361struct vfe_output_path_combo {
362 boolean whichOutputPath;
363 boolean pathEnabled;
364 boolean multiFrag;
365 uint8_t fragCount;
366 boolean ackPending;
367 uint8_t currentFrame;
368 uint32_t nextFrameAddrBuf[8];
369 struct vfe_output_path yPath;
370 struct vfe_output_path cbcrPath;
371 uint8_t snapshotPendingCount;
372 boolean pmEnabled;
373 uint8_t cbcrStatusBit;
374};
375
376struct vfe_stats_control {
377 boolean ackPending;
378 uint32_t addressBuffer[2];
379 uint32_t nextFrameAddrBuf;
380 boolean pingPongStatus;
381 uint8_t *hwRegPingAddress;
382 uint8_t *hwRegPongAddress;
383 uint32_t droppedStatsFrameCount;
384 uint32_t bufToRender;
385};
386
387struct vfe_gamma_lut_sel {
388 boolean ch0BankSelect;
389 boolean ch1BankSelect;
390 boolean ch2BankSelect;
391};
392
393struct vfe_interrupt_mask {
394 boolean camifErrorIrq;
395 boolean camifSofIrq;
396 boolean camifEolIrq;
397 boolean camifEofIrq;
398 boolean camifEpoch1Irq;
399 boolean camifEpoch2Irq;
400 boolean camifOverflowIrq;
401 boolean ceIrq;
402 boolean regUpdateIrq;
403 boolean resetAckIrq;
404 boolean encYPingpongIrq;
405 boolean encCbcrPingpongIrq;
406 boolean viewYPingpongIrq;
407 boolean viewCbcrPingpongIrq;
408 boolean rdPingpongIrq;
409 boolean afPingpongIrq;
410 boolean awbPingpongIrq;
411 boolean histPingpongIrq;
412 boolean encIrq;
413 boolean viewIrq;
414 boolean busOverflowIrq;
415 boolean afOverflowIrq;
416 boolean awbOverflowIrq;
417 boolean syncTimer0Irq;
418 boolean syncTimer1Irq;
419 boolean syncTimer2Irq;
420 boolean asyncTimer0Irq;
421 boolean asyncTimer1Irq;
422 boolean asyncTimer2Irq;
423 boolean asyncTimer3Irq;
424 boolean axiErrorIrq;
425 boolean violationIrq;
426};
427
428enum vfe_interrupt_name {
429 CAMIF_ERROR_IRQ,
430 CAMIF_SOF_IRQ,
431 CAMIF_EOL_IRQ,
432 CAMIF_EOF_IRQ,
433 CAMIF_EPOCH1_IRQ,
434 CAMIF_EPOCH2_IRQ,
435 CAMIF_OVERFLOW_IRQ,
436 CE_IRQ,
437 REG_UPDATE_IRQ,
438 RESET_ACK_IRQ,
439 ENC_Y_PINGPONG_IRQ,
440 ENC_CBCR_PINGPONG_IRQ,
441 VIEW_Y_PINGPONG_IRQ,
442 VIEW_CBCR_PINGPONG_IRQ,
443 RD_PINGPONG_IRQ,
444 AF_PINGPONG_IRQ,
445 AWB_PINGPONG_IRQ,
446 HIST_PINGPONG_IRQ,
447 ENC_IRQ,
448 VIEW_IRQ,
449 BUS_OVERFLOW_IRQ,
450 AF_OVERFLOW_IRQ,
451 AWB_OVERFLOW_IRQ,
452 SYNC_TIMER0_IRQ,
453 SYNC_TIMER1_IRQ,
454 SYNC_TIMER2_IRQ,
455 ASYNC_TIMER0_IRQ,
456 ASYNC_TIMER1_IRQ,
457 ASYNC_TIMER2_IRQ,
458 ASYNC_TIMER3_IRQ,
459 AXI_ERROR_IRQ,
460 VIOLATION_IRQ
461};
462
463enum VFE_DMI_RAM_SEL {
464 NO_MEM_SELECTED = 0,
465 ROLLOFF_RAM = 0x1,
466 RGBLUT_RAM_CH0_BANK0 = 0x2,
467 RGBLUT_RAM_CH0_BANK1 = 0x3,
468 RGBLUT_RAM_CH1_BANK0 = 0x4,
469 RGBLUT_RAM_CH1_BANK1 = 0x5,
470 RGBLUT_RAM_CH2_BANK0 = 0x6,
471 RGBLUT_RAM_CH2_BANK1 = 0x7,
472 STATS_HIST_CB_EVEN_RAM = 0x8,
473 STATS_HIST_CB_ODD_RAM = 0x9,
474 STATS_HIST_CR_EVEN_RAM = 0xa,
475 STATS_HIST_CR_ODD_RAM = 0xb,
476 RGBLUT_CHX_BANK0 = 0xc,
477 RGBLUT_CHX_BANK1 = 0xd,
478 LUMA_ADAPT_LUT_RAM_BANK0 = 0xe,
479 LUMA_ADAPT_LUT_RAM_BANK1 = 0xf
480};
481
482struct vfe_module_enable {
483 boolean blackLevelCorrectionEnable;
484 boolean lensRollOffEnable;
485 boolean demuxEnable;
486 boolean chromaUpsampleEnable;
487 boolean demosaicEnable;
488 boolean statsEnable;
489 boolean cropEnable;
490 boolean mainScalerEnable;
491 boolean whiteBalanceEnable;
492 boolean colorCorrectionEnable;
493 boolean yHistEnable;
494 boolean skinToneEnable;
495 boolean lumaAdaptationEnable;
496 boolean rgbLUTEnable;
497 boolean chromaEnhanEnable;
498 boolean asfEnable;
499 boolean chromaSuppressionEnable;
500 boolean chromaSubsampleEnable;
501 boolean scaler2YEnable;
502 boolean scaler2CbcrEnable;
503};
504
505struct vfe_bus_cmd_data {
506 boolean stripeReload;
507 boolean busPingpongReload;
508 boolean statsPingpongReload;
509};
510
511struct vfe_stats_cmd_data {
512 boolean autoFocusEnable;
513 boolean axwEnable;
514 boolean histEnable;
515 boolean clearHistEnable;
516 boolean histAutoClearEnable;
517 boolean colorConversionEnable;
518};
519
520struct vfe_hw_ver {
521 uint32_t minorVersion:8;
522 uint32_t majorVersion:8;
523 uint32_t coreVersion:4;
524 uint32_t /* reserved */ : 12;
525} __attribute__((packed, aligned(4)));
526
527struct vfe_cfg {
528 uint32_t pixelPattern:3;
529 uint32_t /* reserved */ : 13;
530 uint32_t inputSource:2;
531 uint32_t /* reserved */ : 14;
532} __attribute__((packed, aligned(4)));
533
534struct vfe_buscmd {
535 uint32_t stripeReload:1;
536 uint32_t /* reserved */ : 3;
537 uint32_t busPingpongReload:1;
538 uint32_t statsPingpongReload:1;
539 uint32_t /* reserved */ : 26;
540} __attribute__((packed, aligned(4)));
541
542struct VFE_Irq_Composite_MaskType {
543 uint32_t encIrqComMaskBits:2;
544 uint32_t viewIrqComMaskBits:2;
545 uint32_t ceDoneSelBits:5;
546 uint32_t /* reserved */ : 23;
547} __attribute__((packed, aligned(4)));
548
549struct vfe_mod_enable {
550 uint32_t blackLevelCorrectionEnable:1;
551 uint32_t lensRollOffEnable:1;
552 uint32_t demuxEnable:1;
553 uint32_t chromaUpsampleEnable:1;
554 uint32_t demosaicEnable:1;
555 uint32_t statsEnable:1;
556 uint32_t cropEnable:1;
557 uint32_t mainScalerEnable:1;
558 uint32_t whiteBalanceEnable:1;
559 uint32_t colorCorrectionEnable:1;
560 uint32_t yHistEnable:1;
561 uint32_t skinToneEnable:1;
562 uint32_t lumaAdaptationEnable:1;
563 uint32_t rgbLUTEnable:1;
564 uint32_t chromaEnhanEnable:1;
565 uint32_t asfEnable:1;
566 uint32_t chromaSuppressionEnable:1;
567 uint32_t chromaSubsampleEnable:1;
568 uint32_t scaler2YEnable:1;
569 uint32_t scaler2CbcrEnable:1;
570 uint32_t /* reserved */ : 14;
571} __attribute__((packed, aligned(4)));
572
573struct vfe_irqenable {
574 uint32_t camifErrorIrq:1;
575 uint32_t camifSofIrq:1;
576 uint32_t camifEolIrq:1;
577 uint32_t camifEofIrq:1;
578 uint32_t camifEpoch1Irq:1;
579 uint32_t camifEpoch2Irq:1;
580 uint32_t camifOverflowIrq:1;
581 uint32_t ceIrq:1;
582 uint32_t regUpdateIrq:1;
583 uint32_t resetAckIrq:1;
584 uint32_t encYPingpongIrq:1;
585 uint32_t encCbcrPingpongIrq:1;
586 uint32_t viewYPingpongIrq:1;
587 uint32_t viewCbcrPingpongIrq:1;
588 uint32_t rdPingpongIrq:1;
589 uint32_t afPingpongIrq:1;
590 uint32_t awbPingpongIrq:1;
591 uint32_t histPingpongIrq:1;
592 uint32_t encIrq:1;
593 uint32_t viewIrq:1;
594 uint32_t busOverflowIrq:1;
595 uint32_t afOverflowIrq:1;
596 uint32_t awbOverflowIrq:1;
597 uint32_t syncTimer0Irq:1;
598 uint32_t syncTimer1Irq:1;
599 uint32_t syncTimer2Irq:1;
600 uint32_t asyncTimer0Irq:1;
601 uint32_t asyncTimer1Irq:1;
602 uint32_t asyncTimer2Irq:1;
603 uint32_t asyncTimer3Irq:1;
604 uint32_t axiErrorIrq:1;
605 uint32_t violationIrq:1;
606} __attribute__((packed, aligned(4)));
607
608struct vfe_upsample_cfg {
609 uint32_t chromaCositingForYCbCrInputs:1;
610 uint32_t /* reserved */ : 31;
611} __attribute__((packed, aligned(4)));
612
613struct VFE_CAMIFConfigType {
614 /* CAMIF Config */
615 uint32_t /* reserved */ : 1;
616 uint32_t VSyncEdge:1;
617 uint32_t HSyncEdge:1;
618 uint32_t syncMode:2;
619 uint32_t vfeSubsampleEnable:1;
620 uint32_t /* reserved */ : 1;
621 uint32_t busSubsampleEnable:1;
622 uint32_t camif2vfeEnable:1;
623 uint32_t /* reserved */ : 1;
624 uint32_t camif2busEnable:1;
625 uint32_t irqSubsampleEnable:1;
626 uint32_t binningEnable:1;
627 uint32_t /* reserved */ : 18;
628 uint32_t misrEnable:1;
629} __attribute__((packed, aligned(4)));
630
631struct vfe_camifcfg {
632 /* EFS_Config */
633 uint32_t efsEndOfLine:8;
634 uint32_t efsStartOfLine:8;
635 uint32_t efsEndOfFrame:8;
636 uint32_t efsStartOfFrame:8;
637 /* Frame Config */
638 uint32_t frameConfigPixelsPerLine:14;
639 uint32_t /* reserved */ : 2;
640 uint32_t frameConfigLinesPerFrame:14;
641 uint32_t /* reserved */ : 2;
642 /* Window Width Config */
643 uint32_t windowWidthCfgLastPixel:14;
644 uint32_t /* reserved */ : 2;
645 uint32_t windowWidthCfgFirstPixel:14;
646 uint32_t /* reserved */ : 2;
647 /* Window Height Config */
648 uint32_t windowHeightCfglastLine:14;
649 uint32_t /* reserved */ : 2;
650 uint32_t windowHeightCfgfirstLine:14;
651 uint32_t /* reserved */ : 2;
652 /* Subsample 1 Config */
653 uint32_t subsample1CfgPixelSkip:16;
654 uint32_t subsample1CfgLineSkip:16;
655 /* Subsample 2 Config */
656 uint32_t subsample2CfgFrameSkip:4;
657 uint32_t subsample2CfgFrameSkipMode:1;
658 uint32_t subsample2CfgPixelSkipWrap:1;
659 uint32_t /* reserved */ : 26;
660 /* Epoch Interrupt */
661 uint32_t epoch1Line:14;
662 uint32_t /* reserved */ : 2;
663 uint32_t epoch2Line:14;
664 uint32_t /* reserved */ : 2;
665} __attribute__((packed, aligned(4)));
666
667struct vfe_camifframe_update {
668 uint32_t pixelsPerLine:14;
669 uint32_t /* reserved */ : 2;
670 uint32_t linesPerFrame:14;
671 uint32_t /* reserved */ : 2;
672} __attribute__((packed, aligned(4)));
673
674struct vfe_axi_bus_cfg {
675 uint32_t stripeRdPathEn:1;
676 uint32_t /* reserved */ : 3;
677 uint32_t encYWrPathEn:1;
678 uint32_t encCbcrWrPathEn:1;
679 uint32_t viewYWrPathEn:1;
680 uint32_t viewCbcrWrPathEn:1;
681 uint32_t rawPixelDataSize:2;
682 uint32_t rawWritePathSelect:2;
683 uint32_t /* reserved */ : 20;
684} __attribute__((packed, aligned(4)));
685
686struct vfe_axi_out_cfg {
687 uint32_t out2YPingAddr:32;
688 uint32_t out2YPongAddr:32;
689 uint32_t out2YImageHeight:12;
690 uint32_t /* reserved */ : 4;
691 uint32_t out2YImageWidthin64bit:10;
692 uint32_t /* reserved */ : 6;
693 uint32_t out2YBurstLength:2;
694 uint32_t /* reserved */ : 2;
695 uint32_t out2YNumRows:12;
696 uint32_t out2YRowIncrementIn64bit:12;
697 uint32_t /* reserved */ : 4;
698 uint32_t out2CbcrPingAddr:32;
699 uint32_t out2CbcrPongAddr:32;
700 uint32_t out2CbcrImageHeight:12;
701 uint32_t /* reserved */ : 4;
702 uint32_t out2CbcrImageWidthIn64bit:10;
703 uint32_t /* reserved */ : 6;
704 uint32_t out2CbcrBurstLength:2;
705 uint32_t /* reserved */ : 2;
706 uint32_t out2CbcrNumRows:12;
707 uint32_t out2CbcrRowIncrementIn64bit:12;
708 uint32_t /* reserved */ : 4;
709 uint32_t out1YPingAddr:32;
710 uint32_t out1YPongAddr:32;
711 uint32_t out1YImageHeight:12;
712 uint32_t /* reserved */ : 4;
713 uint32_t out1YImageWidthin64bit:10;
714 uint32_t /* reserved */ : 6;
715 uint32_t out1YBurstLength:2;
716 uint32_t /* reserved */ : 2;
717 uint32_t out1YNumRows:12;
718 uint32_t out1YRowIncrementIn64bit:12;
719 uint32_t /* reserved */ : 4;
720 uint32_t out1CbcrPingAddr:32;
721 uint32_t out1CbcrPongAddr:32;
722 uint32_t out1CbcrImageHeight:12;
723 uint32_t /* reserved */ : 4;
724 uint32_t out1CbcrImageWidthIn64bit:10;
725 uint32_t /* reserved */ : 6;
726 uint32_t out1CbcrBurstLength:2;
727 uint32_t /* reserved */ : 2;
728 uint32_t out1CbcrNumRows:12;
729 uint32_t out1CbcrRowIncrementIn64bit:12;
730 uint32_t /* reserved */ : 4;
731} __attribute__((packed, aligned(4)));
732
733struct vfe_output_clamp_cfg {
734 /* Output Clamp Maximums */
735 uint32_t yChanMax:8;
736 uint32_t cbChanMax:8;
737 uint32_t crChanMax:8;
738 uint32_t /* reserved */ : 8;
739 /* Output Clamp Minimums */
740 uint32_t yChanMin:8;
741 uint32_t cbChanMin:8;
742 uint32_t crChanMin:8;
743 uint32_t /* reserved */ : 8;
744} __attribute__((packed, aligned(4)));
745
746struct vfe_fov_crop_cfg {
747 uint32_t lastPixel:12;
748 uint32_t /* reserved */ : 4;
749 uint32_t firstPixel:12;
750 uint32_t /* reserved */ : 4;
751
752 /* FOV Corp, Part 2 */
753 uint32_t lastLine:12;
754 uint32_t /* reserved */ : 4;
755 uint32_t firstLine:12;
756 uint32_t /* reserved */ : 4;
757} __attribute__((packed, aligned(4)));
758
759struct VFE_FRAME_SKIP_UpdateCmdType {
760 uint32_t yPattern:32;
761 uint32_t cbcrPattern:32;
762} __attribute__((packed, aligned(4)));
763
764struct vfe_frame_skip_cfg {
765 /* Frame Drop Enc (output2) */
766 uint32_t output2YPeriod:5;
767 uint32_t /* reserved */ : 27;
768 uint32_t output2CbCrPeriod:5;
769 uint32_t /* reserved */ : 27;
770 uint32_t output2YPattern:32;
771 uint32_t output2CbCrPattern:32;
772 /* Frame Drop View (output1) */
773 uint32_t output1YPeriod:5;
774 uint32_t /* reserved */ : 27;
775 uint32_t output1CbCrPeriod:5;
776 uint32_t /* reserved */ : 27;
777 uint32_t output1YPattern:32;
778 uint32_t output1CbCrPattern:32;
779} __attribute__((packed, aligned(4)));
780
781struct vfe_main_scaler_cfg {
782 /* Scaler Enable Config */
783 uint32_t hEnable:1;
784 uint32_t vEnable:1;
785 uint32_t /* reserved */ : 30;
786 /* Scale H Image Size Config */
787 uint32_t inWidth:12;
788 uint32_t /* reserved */ : 4;
789 uint32_t outWidth:12;
790 uint32_t /* reserved */ : 4;
791 /* Scale H Phase Config */
792 uint32_t horizPhaseMult:18;
793 uint32_t /* reserved */ : 2;
794 uint32_t horizInterResolution:2;
795 uint32_t /* reserved */ : 10;
796 /* Scale H Stripe Config */
797 uint32_t horizMNInit:12;
798 uint32_t /* reserved */ : 4;
799 uint32_t horizPhaseInit:15;
800 uint32_t /* reserved */ : 1;
801 /* Scale V Image Size Config */
802 uint32_t inHeight:12;
803 uint32_t /* reserved */ : 4;
804 uint32_t outHeight:12;
805 uint32_t /* reserved */ : 4;
806 /* Scale V Phase Config */
807 uint32_t vertPhaseMult:18;
808 uint32_t /* reserved */ : 2;
809 uint32_t vertInterResolution:2;
810 uint32_t /* reserved */ : 10;
811 /* Scale V Stripe Config */
812 uint32_t vertMNInit:12;
813 uint32_t /* reserved */ : 4;
814 uint32_t vertPhaseInit:15;
815 uint32_t /* reserved */ : 1;
816} __attribute__((packed, aligned(4)));
817
818struct vfe_scaler2_cfg {
819 /* Scaler Enable Config */
820 uint32_t hEnable:1;
821 uint32_t vEnable:1;
822 uint32_t /* reserved */ : 30;
823 /* Scaler H Image Size Config */
824 uint32_t inWidth:12;
825 uint32_t /* reserved */ : 4;
826 uint32_t outWidth:12;
827 uint32_t /* reserved */ : 4;
828 /* Scaler H Phase Config */
829 uint32_t horizPhaseMult:18;
830 uint32_t /* reserved */ : 2;
831 uint32_t horizInterResolution:2;
832 uint32_t /* reserved */ : 10;
833 /* Scaler V Image Size Config */
834 uint32_t inHeight:12;
835 uint32_t /* reserved */ : 4;
836 uint32_t outHeight:12;
837 uint32_t /* reserved */ : 4;
838 /* Scaler V Phase Config */
839 uint32_t vertPhaseMult:18;
840 uint32_t /* reserved */ : 2;
841 uint32_t vertInterResolution:2;
842 uint32_t /* reserved */ : 10;
843} __attribute__((packed, aligned(4)));
844
845struct vfe_rolloff_cfg {
846 /* Rolloff 0 Config */
847 uint32_t gridWidth:9;
848 uint32_t gridHeight:9;
849 uint32_t yDelta:9;
850 uint32_t /* reserved */ : 5;
851 /* Rolloff 1 Config*/
852 uint32_t gridX:4;
853 uint32_t gridY:4;
854 uint32_t pixelX:9;
855 uint32_t /* reserved */ : 3;
856 uint32_t pixelY:9;
857 uint32_t /* reserved */ : 3;
858 /* Rolloff 2 Config */
859 uint32_t yDeltaAccum:12;
860 uint32_t /* reserved */ : 20;
861} __attribute__((packed, aligned(4)));
862
863struct vfe_asf_update {
864 /* ASF Config Command */
865 uint32_t smoothEnable:1;
866 uint32_t sharpMode:2;
867 uint32_t /* reserved */ : 1;
868 uint32_t smoothCoeff1:4;
869 uint32_t smoothCoeff0:8;
870 uint32_t pipeFlushCount:12;
871 uint32_t pipeFlushOvd:1;
872 uint32_t flushHaltOvd:1;
873 uint32_t cropEnable:1;
874 uint32_t /* reserved */ : 1;
875 /* Sharpening Config 0 */
876 uint32_t sharpThresholdE1:7;
877 uint32_t /* reserved */ : 1;
878 uint32_t sharpDegreeK1:5;
879 uint32_t /* reserved */ : 3;
880 uint32_t sharpDegreeK2:5;
881 uint32_t /* reserved */ : 3;
882 uint32_t normalizeFactor:7;
883 uint32_t /* reserved */ : 1;
884 /* Sharpening Config 1 */
885 uint32_t sharpThresholdE2:8;
886 uint32_t sharpThresholdE3:8;
887 uint32_t sharpThresholdE4:8;
888 uint32_t sharpThresholdE5:8;
889 /* Sharpening Coefficients 0 */
890 uint32_t F1Coeff0:6;
891 uint32_t F1Coeff1:6;
892 uint32_t F1Coeff2:6;
893 uint32_t F1Coeff3:6;
894 uint32_t F1Coeff4:6;
895 uint32_t /* reserved */ : 2;
896 /* Sharpening Coefficients 1 */
897 uint32_t F1Coeff5:6;
898 uint32_t F1Coeff6:6;
899 uint32_t F1Coeff7:6;
900 uint32_t F1Coeff8:7;
901 uint32_t /* reserved */ : 7;
902 /* Sharpening Coefficients 2 */
903 uint32_t F2Coeff0:6;
904 uint32_t F2Coeff1:6;
905 uint32_t F2Coeff2:6;
906 uint32_t F2Coeff3:6;
907 uint32_t F2Coeff4:6;
908 uint32_t /* reserved */ : 2;
909 /* Sharpening Coefficients 3 */
910 uint32_t F2Coeff5:6;
911 uint32_t F2Coeff6:6;
912 uint32_t F2Coeff7:6;
913 uint32_t F2Coeff8:7;
914 uint32_t /* reserved */ : 7;
915} __attribute__((packed, aligned(4)));
916
917struct vfe_asfcrop_cfg {
918 /* ASF Crop Width Config */
919 uint32_t lastPixel:12;
920 uint32_t /* reserved */ : 4;
921 uint32_t firstPixel:12;
922 uint32_t /* reserved */ : 4;
923 /* ASP Crop Height Config */
924 uint32_t lastLine:12;
925 uint32_t /* reserved */ : 4;
926 uint32_t firstLine:12;
927 uint32_t /* reserved */ : 4;
928} __attribute__((packed, aligned(4)));
929
930struct vfe_chroma_suppress_cfg {
931 /* Chroma Suppress 0 Config */
932 uint32_t m1:8;
933 uint32_t m3:8;
934 uint32_t n1:3;
935 uint32_t /* reserved */ : 1;
936 uint32_t n3:3;
937 uint32_t /* reserved */ : 9;
938 /* Chroma Suppress 1 Config */
939 uint32_t mm1:8;
940 uint32_t nn1:3;
941 uint32_t /* reserved */ : 21;
942} __attribute__((packed, aligned(4)));
943
944struct vfe_chromasubsample_cfg {
945 /* Chroma Subsample Selection */
946 uint32_t hCositedPhase:1;
947 uint32_t vCositedPhase:1;
948 uint32_t hCosited:1;
949 uint32_t vCosited:1;
950 uint32_t hsubSampleEnable:1;
951 uint32_t vsubSampleEnable:1;
952 uint32_t cropEnable:1;
953 uint32_t /* reserved */ : 25;
954 uint32_t cropWidthLastPixel:12;
955 uint32_t /* reserved */ : 4;
956 uint32_t cropWidthFirstPixel:12;
957 uint32_t /* reserved */ : 4;
958 uint32_t cropHeightLastLine:12;
959 uint32_t /* reserved */ : 4;
960 uint32_t cropHeightFirstLine:12;
961 uint32_t /* reserved */ : 4;
962} __attribute__((packed, aligned(4)));
963
964struct vfe_blacklevel_cfg {
965 /* Black Even-Even Value Config */
966 uint32_t evenEvenAdjustment:9;
967 uint32_t /* reserved */ : 23;
968 /* Black Even-Odd Value Config */
969 uint32_t evenOddAdjustment:9;
970 uint32_t /* reserved */ : 23;
971 /* Black Odd-Even Value Config */
972 uint32_t oddEvenAdjustment:9;
973 uint32_t /* reserved */ : 23;
974 /* Black Odd-Odd Value Config */
975 uint32_t oddOddAdjustment:9;
976 uint32_t /* reserved */ : 23;
977} __attribute__((packed, aligned(4)));
978
979struct vfe_demux_cfg {
980 /* Demux Gain 0 Config */
981 uint32_t ch0EvenGain:10;
982 uint32_t /* reserved */ : 6;
983 uint32_t ch0OddGain:10;
984 uint32_t /* reserved */ : 6;
985 /* Demux Gain 1 Config */
986 uint32_t ch1Gain:10;
987 uint32_t /* reserved */ : 6;
988 uint32_t ch2Gain:10;
989 uint32_t /* reserved */ : 6;
990} __attribute__((packed, aligned(4)));
991
992struct vfe_bps_info {
993 uint32_t greenBadPixelCount:8;
994 uint32_t /* reserved */ : 8;
995 uint32_t RedBlueBadPixelCount:8;
996 uint32_t /* reserved */ : 8;
997} __attribute__((packed, aligned(4)));
998
999struct vfe_demosaic_cfg {
1000 /* Demosaic Config */
1001 uint32_t abfEnable:1;
1002 uint32_t badPixelCorrEnable:1;
1003 uint32_t forceAbfOn:1;
1004 uint32_t /* reserved */ : 1;
1005 uint32_t abfShift:4;
1006 uint32_t fminThreshold:7;
1007 uint32_t /* reserved */ : 1;
1008 uint32_t fmaxThreshold:7;
1009 uint32_t /* reserved */ : 5;
1010 uint32_t slopeShift:3;
1011 uint32_t /* reserved */ : 1;
1012} __attribute__((packed, aligned(4)));
1013
1014struct vfe_demosaic_bpc_cfg {
1015 /* Demosaic BPC Config 0 */
1016 uint32_t blueDiffThreshold:12;
1017 uint32_t redDiffThreshold:12;
1018 uint32_t /* reserved */ : 8;
1019 /* Demosaic BPC Config 1 */
1020 uint32_t greenDiffThreshold:12;
1021 uint32_t /* reserved */ : 20;
1022} __attribute__((packed, aligned(4)));
1023
1024struct vfe_demosaic_abf_cfg {
1025 /* Demosaic ABF Config 0 */
1026 uint32_t lpThreshold:10;
1027 uint32_t /* reserved */ : 22;
1028 /* Demosaic ABF Config 1 */
1029 uint32_t ratio:4;
1030 uint32_t minValue:10;
1031 uint32_t /* reserved */ : 2;
1032 uint32_t maxValue:10;
1033 uint32_t /* reserved */ : 6;
1034} __attribute__((packed, aligned(4)));
1035
1036struct vfe_color_correction_cfg {
1037 /* Color Corr. Coefficient 0 Config */
1038 uint32_t c0:12;
1039 uint32_t /* reserved */ : 20;
1040 /* Color Corr. Coefficient 1 Config */
1041 uint32_t c1:12;
1042 uint32_t /* reserved */ : 20;
1043 /* Color Corr. Coefficient 2 Config */
1044 uint32_t c2:12;
1045 uint32_t /* reserved */ : 20;
1046 /* Color Corr. Coefficient 3 Config */
1047 uint32_t c3:12;
1048 uint32_t /* reserved */ : 20;
1049 /* Color Corr. Coefficient 4 Config */
1050 uint32_t c4:12;
1051 uint32_t /* reserved */ : 20;
1052 /* Color Corr. Coefficient 5 Config */
1053 uint32_t c5:12;
1054 uint32_t /* reserved */ : 20;
1055 /* Color Corr. Coefficient 6 Config */
1056 uint32_t c6:12;
1057 uint32_t /* reserved */ : 20;
1058 /* Color Corr. Coefficient 7 Config */
1059 uint32_t c7:12;
1060 uint32_t /* reserved */ : 20;
1061 /* Color Corr. Coefficient 8 Config */
1062 uint32_t c8:12;
1063 uint32_t /* reserved */ : 20;
1064 /* Color Corr. Offset 0 Config */
1065 uint32_t k0:11;
1066 uint32_t /* reserved */ : 21;
1067 /* Color Corr. Offset 1 Config */
1068 uint32_t k1:11;
1069 uint32_t /* reserved */ : 21;
1070 /* Color Corr. Offset 2 Config */
1071 uint32_t k2:11;
1072 uint32_t /* reserved */ : 21;
1073 /* Color Corr. Coefficient Q Config */
1074 uint32_t coefQFactor:2;
1075 uint32_t /* reserved */ : 30;
1076} __attribute__((packed, aligned(4)));
1077
1078struct VFE_LumaAdaptation_ConfigCmdType {
1079 /* LA Config */
1080 uint32_t lutBankSelect:1;
1081 uint32_t /* reserved */ : 31;
1082} __attribute__((packed, aligned(4)));
1083
1084struct vfe_wb_cfg {
1085 /* WB Config */
1086 uint32_t ch0Gain:9;
1087 uint32_t ch1Gain:9;
1088 uint32_t ch2Gain:9;
1089 uint32_t /* reserved */ : 5;
1090} __attribute__((packed, aligned(4)));
1091
1092struct VFE_GammaLutSelect_ConfigCmdType {
1093 /* LUT Bank Select Config */
1094 uint32_t ch0BankSelect:1;
1095 uint32_t ch1BankSelect:1;
1096 uint32_t ch2BankSelect:1;
1097 uint32_t /* reserved */ : 29;
1098} __attribute__((packed, aligned(4)));
1099
1100struct vfe_chroma_enhance_cfg {
1101 /* Chroma Enhance A Config */
1102 uint32_t ap:11;
1103 uint32_t /* reserved */ : 5;
1104 uint32_t am:11;
1105 uint32_t /* reserved */ : 5;
1106 /* Chroma Enhance B Config */
1107 uint32_t bp:11;
1108 uint32_t /* reserved */ : 5;
1109 uint32_t bm:11;
1110 uint32_t /* reserved */ : 5;
1111 /* Chroma Enhance C Config */
1112 uint32_t cp:11;
1113 uint32_t /* reserved */ : 5;
1114 uint32_t cm:11;
1115 uint32_t /* reserved */ : 5;
1116 /* Chroma Enhance D Config */
1117 uint32_t dp:11;
1118 uint32_t /* reserved */ : 5;
1119 uint32_t dm:11;
1120 uint32_t /* reserved */ : 5;
1121 /* Chroma Enhance K Config */
1122 uint32_t kcb:11;
1123 uint32_t /* reserved */ : 5;
1124 uint32_t kcr:11;
1125 uint32_t /* reserved */ : 5;
1126} __attribute__((packed, aligned(4)));
1127
1128struct vfe_color_convert_cfg {
1129 /* Conversion Coefficient 0 */
1130 uint32_t v0:12;
1131 uint32_t /* reserved */ : 20;
1132 /* Conversion Coefficient 1 */
1133 uint32_t v1:12;
1134 uint32_t /* reserved */ : 20;
1135 /* Conversion Coefficient 2 */
1136 uint32_t v2:12;
1137 uint32_t /* reserved */ : 20;
1138 /* Conversion Offset */
1139 uint32_t ConvertOffset:8;
1140 uint32_t /* reserved */ : 24;
1141} __attribute__((packed, aligned(4)));
1142
1143struct VFE_SyncTimer_ConfigCmdType {
1144 /* Timer Line Start Config */
1145 uint32_t timerLineStart:12;
1146 uint32_t /* reserved */ : 20;
1147 /* Timer Pixel Start Config */
1148 uint32_t timerPixelStart:18;
1149 uint32_t /* reserved */ : 14;
1150 /* Timer Pixel Duration Config */
1151 uint32_t timerPixelDuration:28;
1152 uint32_t /* reserved */ : 4;
1153 /* Sync Timer Polarity Config */
1154 uint32_t timer0Polarity:1;
1155 uint32_t timer1Polarity:1;
1156 uint32_t timer2Polarity:1;
1157 uint32_t /* reserved */ : 29;
1158} __attribute__((packed, aligned(4)));
1159
1160struct VFE_AsyncTimer_ConfigCmdType {
1161 /* Async Timer Config 0 */
1162 uint32_t inactiveLength:20;
1163 uint32_t numRepetition:10;
1164 uint32_t /* reserved */ : 1;
1165 uint32_t polarity:1;
1166 /* Async Timer Config 1 */
1167 uint32_t activeLength:20;
1168 uint32_t /* reserved */ : 12;
1169} __attribute__((packed, aligned(4)));
1170
1171struct VFE_AWBAEStatistics_ConfigCmdType {
1172 /* AWB autoexposure Config */
1173 uint32_t aeRegionConfig:1;
1174 uint32_t aeSubregionConfig:1;
1175 uint32_t /* reserved */ : 14;
1176 uint32_t awbYMin:8;
1177 uint32_t awbYMax:8;
1178 /* AXW Header */
1179 uint32_t axwHeader:8;
1180 uint32_t /* reserved */ : 24;
1181 /* AWB Mconfig */
1182 uint32_t m4:8;
1183 uint32_t m3:8;
1184 uint32_t m2:8;
1185 uint32_t m1:8;
1186 /* AWB Cconfig */
1187 uint32_t c2:12;
1188 uint32_t /* reserved */ : 4;
1189 uint32_t c1:12;
1190 uint32_t /* reserved */ : 4;
1191 /* AWB Cconfig 2 */
1192 uint32_t c4:12;
1193 uint32_t /* reserved */ : 4;
1194 uint32_t c3:12;
1195 uint32_t /* reserved */ : 4;
1196} __attribute__((packed, aligned(4)));
1197
1198struct VFE_TestGen_ConfigCmdType {
1199 /* HW Test Gen Config */
1200 uint32_t numFrame:10;
1201 uint32_t /* reserved */ : 2;
1202 uint32_t pixelDataSelect:1;
1203 uint32_t systematicDataSelect:1;
1204 uint32_t /* reserved */ : 2;
1205 uint32_t pixelDataSize:2;
1206 uint32_t hsyncEdge:1;
1207 uint32_t vsyncEdge:1;
1208 uint32_t /* reserved */ : 12;
1209 /* HW Test Gen Image Config */
1210 uint32_t imageWidth:14;
1211 uint32_t /* reserved */ : 2;
1212 uint32_t imageHeight:14;
1213 uint32_t /* reserved */ : 2;
1214 /* SOF Offset Config */
1215 uint32_t sofOffset:24;
1216 uint32_t /* reserved */ : 8;
1217 /* EOF NOffset Config */
1218 uint32_t eofNOffset:24;
1219 uint32_t /* reserved */ : 8;
1220 /* SOL Offset Config */
1221 uint32_t solOffset:9;
1222 uint32_t /* reserved */ : 23;
1223 /* EOL NOffset Config */
1224 uint32_t eolNOffset:9;
1225 uint32_t /* reserved */ : 23;
1226 /* HBI Config */
1227 uint32_t hBlankInterval:14;
1228 uint32_t /* reserved */ : 18;
1229 /* VBL Config */
1230 uint32_t vBlankInterval:14;
1231 uint32_t /* reserved */ : 2;
1232 uint32_t vBlankIntervalEnable:1;
1233 uint32_t /* reserved */ : 15;
1234 /* SOF Dummy Line Config */
1235 uint32_t sofDummy:8;
1236 uint32_t /* reserved */ : 24;
1237 /* EOF Dummy Line Config */
1238 uint32_t eofDummy:8;
1239 uint32_t /* reserved */ : 24;
1240 /* Color Bars Config */
1241 uint32_t unicolorBarSelect:3;
1242 uint32_t /* reserved */ : 1;
1243 uint32_t unicolorBarEnable:1;
1244 uint32_t splitEnable:1;
1245 uint32_t pixelPattern:2;
1246 uint32_t rotatePeriod:6;
1247 uint32_t /* reserved */ : 18;
1248 /* Random Config */
1249 uint32_t randomSeed:16;
1250 uint32_t /* reserved */ : 16;
1251} __attribute__((packed, aligned(4)));
1252
1253struct VFE_Bus_Pm_ConfigCmdType {
1254 /* VFE Bus Performance Monitor Config */
1255 uint32_t output2YWrPmEnable:1;
1256 uint32_t output2CbcrWrPmEnable:1;
1257 uint32_t output1YWrPmEnable:1;
1258 uint32_t output1CbcrWrPmEnable:1;
1259 uint32_t /* reserved */ : 28;
1260} __attribute__((packed, aligned(4)));
1261
1262struct vfe_asf_info {
1263 /* asf max edge */
1264 uint32_t maxEdge:13;
1265 uint32_t /* reserved */ : 3;
1266 /* HBi count */
1267 uint32_t HBICount:12;
1268 uint32_t /* reserved */ : 4;
1269} __attribute__((packed, aligned(4)));
1270
1271struct vfe_camif_stats {
1272 uint32_t pixelCount:14;
1273 uint32_t /* reserved */ : 2;
1274 uint32_t lineCount:14;
1275 uint32_t /* reserved */ : 1;
1276 uint32_t camifHalt:1;
1277} __attribute__((packed, aligned(4)));
1278
1279struct VFE_StatsCmdType {
1280 uint32_t autoFocusEnable:1;
1281 uint32_t axwEnable:1;
1282 uint32_t histEnable:1;
1283 uint32_t clearHistEnable:1;
1284 uint32_t histAutoClearEnable:1;
1285 uint32_t colorConversionEnable:1;
1286 uint32_t /* reserved */ : 26;
1287} __attribute__((packed, aligned(4)));
1288
1289
1290struct vfe_statsframe {
1291 uint32_t lastPixel:12;
1292 uint32_t /* reserved */ : 4;
1293 uint32_t lastLine:12;
1294 uint32_t /* reserved */ : 4;
1295} __attribute__((packed, aligned(4)));
1296
1297struct vfe_busstats_wrprio {
1298 uint32_t afBusPriority:4;
1299 uint32_t awbBusPriority:4;
1300 uint32_t histBusPriority:4;
1301 uint32_t afBusPriorityEn:1;
1302 uint32_t awbBusPriorityEn:1;
1303 uint32_t histBusPriorityEn:1;
1304 uint32_t /* reserved */ : 17;
1305} __attribute__((packed, aligned(4)));
1306
1307struct vfe_statsaf_update {
1308 /* VFE_STATS_AF_CFG */
1309 uint32_t windowVOffset:12;
1310 uint32_t /* reserved */ : 4;
1311 uint32_t windowHOffset:12;
1312 uint32_t /* reserved */ : 3;
1313 uint32_t windowMode:1;
1314
1315 /* VFE_STATS_AF_DIM */
1316 uint32_t windowHeight:12;
1317 uint32_t /* reserved */ : 4;
1318 uint32_t windowWidth:12;
1319 uint32_t /* reserved */ : 4;
1320} __attribute__((packed, aligned(4)));
1321
1322struct vfe_statsaf_cfg {
1323 /* VFE_STATS_AF_GRID_0 */
1324 uint32_t entry00:8;
1325 uint32_t entry01:8;
1326 uint32_t entry02:8;
1327 uint32_t entry03:8;
1328
1329 /* VFE_STATS_AF_GRID_1 */
1330 uint32_t entry10:8;
1331 uint32_t entry11:8;
1332 uint32_t entry12:8;
1333 uint32_t entry13:8;
1334
1335 /* VFE_STATS_AF_GRID_2 */
1336 uint32_t entry20:8;
1337 uint32_t entry21:8;
1338 uint32_t entry22:8;
1339 uint32_t entry23:8;
1340
1341 /* VFE_STATS_AF_GRID_3 */
1342 uint32_t entry30:8;
1343 uint32_t entry31:8;
1344 uint32_t entry32:8;
1345 uint32_t entry33:8;
1346
1347 /* VFE_STATS_AF_HEADER */
1348 uint32_t afHeader:8;
1349 uint32_t /* reserved */ : 24;
1350 /* VFE_STATS_AF_COEF0 */
1351 uint32_t a00:5;
1352 uint32_t a04:5;
1353 uint32_t fvMax:11;
1354 uint32_t fvMetric:1;
1355 uint32_t /* reserved */ : 10;
1356
1357 /* VFE_STATS_AF_COEF1 */
1358 uint32_t a20:5;
1359 uint32_t a21:5;
1360 uint32_t a22:5;
1361 uint32_t a23:5;
1362 uint32_t a24:5;
1363 uint32_t /* reserved */ : 7;
1364} __attribute__((packed, aligned(4)));
1365
1366struct vfe_statsawbae_update {
1367 uint32_t aeRegionCfg:1;
1368 uint32_t aeSubregionCfg:1;
1369 uint32_t /* reserved */ : 14;
1370 uint32_t awbYMin:8;
1371 uint32_t awbYMax:8;
1372} __attribute__((packed, aligned(4)));
1373
1374struct vfe_statsaxw_hdr_cfg {
1375 /* Stats AXW Header Config */
1376 uint32_t axwHeader:8;
1377 uint32_t /* reserved */ : 24;
1378} __attribute__((packed, aligned(4)));
1379
1380struct vfe_statsawb_update {
1381 /* AWB MConfig */
1382 uint32_t m4:8;
1383 uint32_t m3:8;
1384 uint32_t m2:8;
1385 uint32_t m1:8;
1386
1387 /* AWB CConfig1 */
1388 uint32_t c2:12;
1389 uint32_t /* reserved */ : 4;
1390 uint32_t c1:12;
1391 uint32_t /* reserved */ : 4;
1392
1393 /* AWB CConfig2 */
1394 uint32_t c4:12;
1395 uint32_t /* reserved */ : 4;
1396 uint32_t c3:12;
1397 uint32_t /* reserved */ : 4;
1398} __attribute__((packed, aligned(4)));
1399
1400struct VFE_SyncTimerCmdType {
1401 uint32_t hsyncCount:12;
1402 uint32_t /* reserved */ : 20;
1403 uint32_t pclkCount:18;
1404 uint32_t /* reserved */ : 14;
1405 uint32_t outputDuration:28;
1406 uint32_t /* reserved */ : 4;
1407} __attribute__((packed, aligned(4)));
1408
1409struct VFE_AsyncTimerCmdType {
1410 /* config 0 */
1411 uint32_t inactiveCount:20;
1412 uint32_t repeatCount:10;
1413 uint32_t /* reserved */ : 1;
1414 uint32_t polarity:1;
1415 /* config 1 */
1416 uint32_t activeCount:20;
1417 uint32_t /* reserved */ : 12;
1418} __attribute__((packed, aligned(4)));
1419
1420struct VFE_AxiInputCmdType {
1421 uint32_t stripeStartAddr0:32;
1422 uint32_t stripeStartAddr1:32;
1423 uint32_t stripeStartAddr2:32;
1424 uint32_t stripeStartAddr3:32;
1425
1426 uint32_t ySize:12;
1427 uint32_t yOffsetDelta:12;
1428 uint32_t /* reserved */ : 8;
1429
1430 /* bus_stripe_rd_hSize */
1431 uint32_t /* reserved */ : 16;
1432 uint32_t xSizeWord:10;
1433 uint32_t /* reserved */ : 6;
1434
1435 /* bus_stripe_rd_buffer_cfg */
1436 uint32_t burstLength:2;
1437 uint32_t /* reserved */ : 2;
1438 uint32_t NumOfRows:12;
1439 uint32_t RowIncrement:12;
1440 uint32_t /* reserved */ : 4;
1441
1442 /* bus_stripe_rd_unpack_cfg */
1443 uint32_t mainUnpackHeight:12;
1444 uint32_t mainUnpackWidth:13;
1445 uint32_t mainUnpackHbiSel:3;
1446 uint32_t mainUnpackPhase:3;
1447 uint32_t /* reserved */ : 1;
1448
1449 /* bus_stripe_rd_unpack */
1450 uint32_t unpackPattern:32;
1451
1452 /* bus_stripe_rd_pad_size */
1453 uint32_t padLeft:7;
1454 uint32_t /* reserved */ : 1;
1455 uint32_t padRight:7;
1456 uint32_t /* reserved */ : 1;
1457 uint32_t padTop:7;
1458 uint32_t /* reserved */ : 1;
1459 uint32_t padBottom:7;
1460 uint32_t /* reserved */ : 1;
1461
1462 /* bus_stripe_rd_pad_L_unpack */
1463 uint32_t leftUnpackPattern0:4;
1464 uint32_t leftUnpackPattern1:4;
1465 uint32_t leftUnpackPattern2:4;
1466 uint32_t leftUnpackPattern3:4;
1467 uint32_t leftUnpackStop0:1;
1468 uint32_t leftUnpackStop1:1;
1469 uint32_t leftUnpackStop2:1;
1470 uint32_t leftUnpackStop3:1;
1471 uint32_t /* reserved */ : 12;
1472
1473 /* bus_stripe_rd_pad_R_unpack */
1474 uint32_t rightUnpackPattern0:4;
1475 uint32_t rightUnpackPattern1:4;
1476 uint32_t rightUnpackPattern2:4;
1477 uint32_t rightUnpackPattern3:4;
1478 uint32_t rightUnpackStop0:1;
1479 uint32_t rightUnpackStop1:1;
1480 uint32_t rightUnpackStop2:1;
1481 uint32_t rightUnpackStop3:1;
1482 uint32_t /* reserved */ : 12;
1483
1484 /* bus_stripe_rd_pad_tb_unpack */
1485 uint32_t topUnapckPattern:4;
1486 uint32_t /* reserved */ : 12;
1487 uint32_t bottomUnapckPattern:4;
1488 uint32_t /* reserved */ : 12;
1489} __attribute__((packed, aligned(4)));
1490
1491struct VFE_AxiRdFragIrqEnable {
1492 uint32_t stripeRdFragirq0Enable:1;
1493 uint32_t stripeRdFragirq1Enable:1;
1494 uint32_t stripeRdFragirq2Enable:1;
1495 uint32_t stripeRdFragirq3Enable:1;
1496 uint32_t /* reserved */ : 28;
1497} __attribute__((packed, aligned(4)));
1498
1499int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *);
1500void vfe_stats_af_stop(void);
1501void vfe_stop(void);
1502void vfe_update(void);
1503int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *);
1504int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *);
1505void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *);
1506void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *);
1507void vfe_start(struct vfe_cmd_start *);
1508void vfe_la_update(struct vfe_cmd_la_config *);
1509void vfe_la_config(struct vfe_cmd_la_config *);
1510void vfe_test_gen_start(struct vfe_cmd_test_gen_start *);
1511void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *);
1512void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *);
1513void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *);
1514void vfe_camif_frame_update(struct vfe_cmds_camif_frame *);
1515void vfe_color_correction_config(struct vfe_cmd_color_correction_config *);
1516void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *);
1517void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *);
1518void vfe_demosaic_config(struct vfe_cmd_demosaic_config *);
1519void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *);
1520void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *);
1521void vfe_black_level_update(struct vfe_cmd_black_level_config *);
1522void vfe_black_level_config(struct vfe_cmd_black_level_config *);
1523void vfe_asf_update(struct vfe_cmd_asf_update *);
1524void vfe_asf_config(struct vfe_cmd_asf_config *);
1525void vfe_white_balance_config(struct vfe_cmd_white_balance_config *);
1526void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *);
1527void vfe_roll_off_config(struct vfe_cmd_roll_off_config *);
1528void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *);
1529void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *);
1530void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *);
1531void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *);
1532void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *);
1533void vfe_stats_wb_exp_stop(void);
1534void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *);
1535void vfe_stats_update_af(struct vfe_cmd_stats_af_update *);
1536void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *);
1537void vfe_stats_start_af(struct vfe_cmd_stats_af_start *);
1538void vfe_stats_setting(struct vfe_cmd_stats_setting *);
1539void vfe_axi_input_config(struct vfe_cmd_axi_input_config *);
1540void vfe_stats_config(struct vfe_cmd_stats_setting *);
1541void vfe_axi_output_config(struct vfe_cmd_axi_output_config *);
1542void vfe_camif_config(struct vfe_cmd_camif_config *);
1543void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *);
1544void vfe_get_hw_version(struct vfe_cmd_hw_version *);
1545void vfe_reset(void);
1546void vfe_cmd_release(struct platform_device *);
1547void vfe_output1_ack(struct vfe_cmd_output_ack *);
1548void vfe_output2_ack(struct vfe_cmd_output_ack *);
1549#endif /* __MSM_VFE8X_REG_H__ */
diff --git a/drivers/staging/dream/camera/mt9d112.c b/drivers/staging/dream/camera/mt9d112.c
deleted file mode 100644
index e6f2d5124611..000000000000
--- a/drivers/staging/dream/camera/mt9d112.c
+++ /dev/null
@@ -1,762 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/delay.h>
6#include <linux/slab.h>
7#include <linux/types.h>
8#include <linux/i2c.h>
9#include <linux/uaccess.h>
10#include <linux/miscdevice.h>
11#include <media/msm_camera.h>
12#include <mach/gpio.h>
13#include "mt9d112.h"
14
15/* Micron MT9D112 Registers and their values */
16/* Sensor Core Registers */
17#define REG_MT9D112_MODEL_ID 0x3000
18#define MT9D112_MODEL_ID 0x1580
19
20/* SOC Registers Page 1 */
21#define REG_MT9D112_SENSOR_RESET 0x301A
22#define REG_MT9D112_STANDBY_CONTROL 0x3202
23#define REG_MT9D112_MCU_BOOT 0x3386
24
25struct mt9d112_work {
26 struct work_struct work;
27};
28
29static struct mt9d112_work *mt9d112_sensorw;
30static struct i2c_client *mt9d112_client;
31
32struct mt9d112_ctrl {
33 const struct msm_camera_sensor_info *sensordata;
34};
35
36
37static struct mt9d112_ctrl *mt9d112_ctrl;
38
39static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
40DECLARE_MUTEX(mt9d112_sem);
41
42
43/*=============================================================
44 EXTERNAL DECLARATIONS
45==============================================================*/
46extern struct mt9d112_reg mt9d112_regs;
47
48
49/*=============================================================*/
50
51static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
52{
53 int rc = 0;
54
55 rc = gpio_request(dev->sensor_reset, "mt9d112");
56
57 if (!rc) {
58 rc = gpio_direction_output(dev->sensor_reset, 0);
59 mdelay(20);
60 rc = gpio_direction_output(dev->sensor_reset, 1);
61 }
62
63 gpio_free(dev->sensor_reset);
64 return rc;
65}
66
67static int32_t mt9d112_i2c_txdata(unsigned short saddr,
68 unsigned char *txdata, int length)
69{
70 struct i2c_msg msg[] = {
71 {
72 .addr = saddr,
73 .flags = 0,
74 .len = length,
75 .buf = txdata,
76 },
77 };
78
79 if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
80 CDBG("mt9d112_i2c_txdata failed\n");
81 return -EIO;
82 }
83
84 return 0;
85}
86
87static int32_t mt9d112_i2c_write(unsigned short saddr,
88 unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
89{
90 int32_t rc = -EIO;
91 unsigned char buf[4];
92
93 memset(buf, 0, sizeof(buf));
94 switch (width) {
95 case WORD_LEN: {
96 buf[0] = (waddr & 0xFF00)>>8;
97 buf[1] = (waddr & 0x00FF);
98 buf[2] = (wdata & 0xFF00)>>8;
99 buf[3] = (wdata & 0x00FF);
100
101 rc = mt9d112_i2c_txdata(saddr, buf, 4);
102 }
103 break;
104
105 case BYTE_LEN: {
106 buf[0] = waddr;
107 buf[1] = wdata;
108 rc = mt9d112_i2c_txdata(saddr, buf, 2);
109 }
110 break;
111
112 default:
113 break;
114 }
115
116 if (rc < 0)
117 CDBG(
118 "i2c_write failed, addr = 0x%x, val = 0x%x!\n",
119 waddr, wdata);
120
121 return rc;
122}
123
124static int32_t mt9d112_i2c_write_table(
125 struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
126 int num_of_items_in_table)
127{
128 int i;
129 int32_t rc = -EIO;
130
131 for (i = 0; i < num_of_items_in_table; i++) {
132 rc = mt9d112_i2c_write(mt9d112_client->addr,
133 reg_conf_tbl->waddr, reg_conf_tbl->wdata,
134 reg_conf_tbl->width);
135 if (rc < 0)
136 break;
137 if (reg_conf_tbl->mdelay_time != 0)
138 mdelay(reg_conf_tbl->mdelay_time);
139 reg_conf_tbl++;
140 }
141
142 return rc;
143}
144
145static int mt9d112_i2c_rxdata(unsigned short saddr,
146 unsigned char *rxdata, int length)
147{
148 struct i2c_msg msgs[] = {
149 {
150 .addr = saddr,
151 .flags = 0,
152 .len = 2,
153 .buf = rxdata,
154 },
155 {
156 .addr = saddr,
157 .flags = I2C_M_RD,
158 .len = length,
159 .buf = rxdata,
160 },
161 };
162
163 if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
164 CDBG("mt9d112_i2c_rxdata failed!\n");
165 return -EIO;
166 }
167
168 return 0;
169}
170
171static int32_t mt9d112_i2c_read(unsigned short saddr,
172 unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
173{
174 int32_t rc = 0;
175 unsigned char buf[4];
176
177 if (!rdata)
178 return -EIO;
179
180 memset(buf, 0, sizeof(buf));
181
182 switch (width) {
183 case WORD_LEN: {
184 buf[0] = (raddr & 0xFF00)>>8;
185 buf[1] = (raddr & 0x00FF);
186
187 rc = mt9d112_i2c_rxdata(saddr, buf, 2);
188 if (rc < 0)
189 return rc;
190
191 *rdata = buf[0] << 8 | buf[1];
192 }
193 break;
194
195 default:
196 break;
197 }
198
199 if (rc < 0)
200 CDBG("mt9d112_i2c_read failed!\n");
201
202 return rc;
203}
204
205static int32_t mt9d112_set_lens_roll_off(void)
206{
207 int32_t rc = 0;
208 rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
209 mt9d112_regs.rftbl_size);
210 return rc;
211}
212
213static long mt9d112_reg_init(void)
214{
215 int32_t array_length;
216 int32_t i;
217 long rc;
218
219 /* PLL Setup Start */
220 rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
221 mt9d112_regs.plltbl_size);
222
223 if (rc < 0)
224 return rc;
225 /* PLL Setup End */
226
227 array_length = mt9d112_regs.prev_snap_reg_settings_size;
228
229 /* Configure sensor for Preview mode and Snapshot mode */
230 for (i = 0; i < array_length; i++) {
231 rc = mt9d112_i2c_write(mt9d112_client->addr,
232 mt9d112_regs.prev_snap_reg_settings[i].register_address,
233 mt9d112_regs.prev_snap_reg_settings[i].register_value,
234 WORD_LEN);
235
236 if (rc < 0)
237 return rc;
238 }
239
240 /* Configure for Noise Reduction, Saturation and Aperture Correction */
241 array_length = mt9d112_regs.noise_reduction_reg_settings_size;
242
243 for (i = 0; i < array_length; i++) {
244 rc = mt9d112_i2c_write(mt9d112_client->addr,
245 mt9d112_regs.noise_reduction_reg_settings[i].register_address,
246 mt9d112_regs.noise_reduction_reg_settings[i].register_value,
247 WORD_LEN);
248
249 if (rc < 0)
250 return rc;
251 }
252
253 /* Set Color Kill Saturation point to optimum value */
254 rc =
255 mt9d112_i2c_write(mt9d112_client->addr,
256 0x35A4,
257 0x0593,
258 WORD_LEN);
259 if (rc < 0)
260 return rc;
261
262 rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
263 mt9d112_regs.stbl_size);
264 if (rc < 0)
265 return rc;
266
267 rc = mt9d112_set_lens_roll_off();
268 if (rc < 0)
269 return rc;
270
271 return 0;
272}
273
274static long mt9d112_set_sensor_mode(int mode)
275{
276 uint16_t clock;
277 long rc = 0;
278
279 switch (mode) {
280 case SENSOR_PREVIEW_MODE:
281 rc =
282 mt9d112_i2c_write(mt9d112_client->addr,
283 0x338C, 0xA20C, WORD_LEN);
284 if (rc < 0)
285 return rc;
286
287 rc =
288 mt9d112_i2c_write(mt9d112_client->addr,
289 0x3390, 0x0004, WORD_LEN);
290 if (rc < 0)
291 return rc;
292
293 rc =
294 mt9d112_i2c_write(mt9d112_client->addr,
295 0x338C, 0xA215, WORD_LEN);
296 if (rc < 0)
297 return rc;
298
299 rc =
300 mt9d112_i2c_write(mt9d112_client->addr,
301 0x3390, 0x0004, WORD_LEN);
302 if (rc < 0)
303 return rc;
304
305 rc =
306 mt9d112_i2c_write(mt9d112_client->addr,
307 0x338C, 0xA20B, WORD_LEN);
308 if (rc < 0)
309 return rc;
310
311 rc =
312 mt9d112_i2c_write(mt9d112_client->addr,
313 0x3390, 0x0000, WORD_LEN);
314 if (rc < 0)
315 return rc;
316
317 clock = 0x0250;
318
319 rc =
320 mt9d112_i2c_write(mt9d112_client->addr,
321 0x341C, clock, WORD_LEN);
322 if (rc < 0)
323 return rc;
324
325 rc =
326 mt9d112_i2c_write(mt9d112_client->addr,
327 0x338C, 0xA103, WORD_LEN);
328 if (rc < 0)
329 return rc;
330
331 rc =
332 mt9d112_i2c_write(mt9d112_client->addr,
333 0x3390, 0x0001, WORD_LEN);
334 if (rc < 0)
335 return rc;
336
337 mdelay(5);
338 break;
339
340 case SENSOR_SNAPSHOT_MODE:
341 /* Switch to lower fps for Snapshot */
342 rc =
343 mt9d112_i2c_write(mt9d112_client->addr,
344 0x341C, 0x0120, WORD_LEN);
345 if (rc < 0)
346 return rc;
347
348 rc =
349 mt9d112_i2c_write(mt9d112_client->addr,
350 0x338C, 0xA120, WORD_LEN);
351 if (rc < 0)
352 return rc;
353
354 rc =
355 mt9d112_i2c_write(mt9d112_client->addr,
356 0x3390, 0x0002, WORD_LEN);
357 if (rc < 0)
358 return rc;
359
360 mdelay(5);
361
362 rc =
363 mt9d112_i2c_write(mt9d112_client->addr,
364 0x338C, 0xA103, WORD_LEN);
365 if (rc < 0)
366 return rc;
367
368 rc =
369 mt9d112_i2c_write(mt9d112_client->addr,
370 0x3390, 0x0002, WORD_LEN);
371 if (rc < 0)
372 return rc;
373 break;
374
375 default:
376 return -EINVAL;
377 }
378
379 return 0;
380}
381
382static long mt9d112_set_effect(int mode, int effect)
383{
384 uint16_t reg_addr;
385 uint16_t reg_val;
386 long rc = 0;
387
388 switch (mode) {
389 case SENSOR_PREVIEW_MODE:
390 /* Context A Special Effects */
391 reg_addr = 0x2799;
392 break;
393
394 case SENSOR_SNAPSHOT_MODE:
395 /* Context B Special Effects */
396 reg_addr = 0x279B;
397 break;
398
399 default:
400 reg_addr = 0x2799;
401 break;
402 }
403
404 switch (effect) {
405 case CAMERA_EFFECT_OFF: {
406 reg_val = 0x6440;
407
408 rc = mt9d112_i2c_write(mt9d112_client->addr,
409 0x338C, reg_addr, WORD_LEN);
410 if (rc < 0)
411 return rc;
412
413 rc = mt9d112_i2c_write(mt9d112_client->addr,
414 0x3390, reg_val, WORD_LEN);
415 if (rc < 0)
416 return rc;
417 }
418 break;
419
420 case CAMERA_EFFECT_MONO: {
421 reg_val = 0x6441;
422 rc = mt9d112_i2c_write(mt9d112_client->addr,
423 0x338C, reg_addr, WORD_LEN);
424 if (rc < 0)
425 return rc;
426
427 rc = mt9d112_i2c_write(mt9d112_client->addr,
428 0x3390, reg_val, WORD_LEN);
429 if (rc < 0)
430 return rc;
431 }
432 break;
433
434 case CAMERA_EFFECT_NEGATIVE: {
435 reg_val = 0x6443;
436 rc = mt9d112_i2c_write(mt9d112_client->addr,
437 0x338C, reg_addr, WORD_LEN);
438 if (rc < 0)
439 return rc;
440
441 rc = mt9d112_i2c_write(mt9d112_client->addr,
442 0x3390, reg_val, WORD_LEN);
443 if (rc < 0)
444 return rc;
445 }
446 break;
447
448 case CAMERA_EFFECT_SOLARIZE: {
449 reg_val = 0x6445;
450 rc = mt9d112_i2c_write(mt9d112_client->addr,
451 0x338C, reg_addr, WORD_LEN);
452 if (rc < 0)
453 return rc;
454
455 rc = mt9d112_i2c_write(mt9d112_client->addr,
456 0x3390, reg_val, WORD_LEN);
457 if (rc < 0)
458 return rc;
459 }
460 break;
461
462 case CAMERA_EFFECT_SEPIA: {
463 reg_val = 0x6442;
464 rc = mt9d112_i2c_write(mt9d112_client->addr,
465 0x338C, reg_addr, WORD_LEN);
466 if (rc < 0)
467 return rc;
468
469 rc = mt9d112_i2c_write(mt9d112_client->addr,
470 0x3390, reg_val, WORD_LEN);
471 if (rc < 0)
472 return rc;
473 }
474 break;
475
476 case CAMERA_EFFECT_PASTEL:
477 case CAMERA_EFFECT_MOSAIC:
478 case CAMERA_EFFECT_RESIZE:
479 return -EINVAL;
480
481 default: {
482 reg_val = 0x6440;
483 rc = mt9d112_i2c_write(mt9d112_client->addr,
484 0x338C, reg_addr, WORD_LEN);
485 if (rc < 0)
486 return rc;
487
488 rc = mt9d112_i2c_write(mt9d112_client->addr,
489 0x3390, reg_val, WORD_LEN);
490 if (rc < 0)
491 return rc;
492
493 return -EINVAL;
494 }
495 }
496
497 /* Refresh Sequencer */
498 rc = mt9d112_i2c_write(mt9d112_client->addr,
499 0x338C, 0xA103, WORD_LEN);
500 if (rc < 0)
501 return rc;
502
503 rc = mt9d112_i2c_write(mt9d112_client->addr,
504 0x3390, 0x0005, WORD_LEN);
505
506 return rc;
507}
508
509static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
510{
511 uint16_t model_id = 0;
512 int rc = 0;
513
514 CDBG("init entry \n");
515 rc = mt9d112_reset(data);
516 if (rc < 0) {
517 CDBG("reset failed!\n");
518 goto init_probe_fail;
519 }
520
521 mdelay(5);
522
523 /* Micron suggested Power up block Start:
524 * Put MCU into Reset - Stop MCU */
525 rc = mt9d112_i2c_write(mt9d112_client->addr,
526 REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
527 if (rc < 0)
528 goto init_probe_fail;
529
530 /* Pull MCU from Reset - Start MCU */
531 rc = mt9d112_i2c_write(mt9d112_client->addr,
532 REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
533 if (rc < 0)
534 goto init_probe_fail;
535
536 mdelay(5);
537
538 /* Micron Suggested - Power up block */
539 rc = mt9d112_i2c_write(mt9d112_client->addr,
540 REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
541 if (rc < 0)
542 goto init_probe_fail;
543
544 rc = mt9d112_i2c_write(mt9d112_client->addr,
545 REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
546 if (rc < 0)
547 goto init_probe_fail;
548
549 /* FUSED_DEFECT_CORRECTION */
550 rc = mt9d112_i2c_write(mt9d112_client->addr,
551 0x33F4, 0x031D, WORD_LEN);
552 if (rc < 0)
553 goto init_probe_fail;
554
555 mdelay(5);
556
557 /* Micron suggested Power up block End */
558 /* Read the Model ID of the sensor */
559 rc = mt9d112_i2c_read(mt9d112_client->addr,
560 REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
561 if (rc < 0)
562 goto init_probe_fail;
563
564 CDBG("mt9d112 model_id = 0x%x\n", model_id);
565
566 /* Check if it matches it with the value in Datasheet */
567 if (model_id != MT9D112_MODEL_ID) {
568 rc = -EINVAL;
569 goto init_probe_fail;
570 }
571
572 rc = mt9d112_reg_init();
573 if (rc < 0)
574 goto init_probe_fail;
575
576 return rc;
577
578init_probe_fail:
579 return rc;
580}
581
582int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
583{
584 int rc = 0;
585
586 mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
587 if (!mt9d112_ctrl) {
588 CDBG("mt9d112_init failed!\n");
589 rc = -ENOMEM;
590 goto init_done;
591 }
592
593 if (data)
594 mt9d112_ctrl->sensordata = data;
595
596 /* Input MCLK = 24MHz */
597 msm_camio_clk_rate_set(24000000);
598 mdelay(5);
599
600 msm_camio_camif_pad_reg_reset();
601
602 rc = mt9d112_sensor_init_probe(data);
603 if (rc < 0) {
604 CDBG("mt9d112_sensor_init failed!\n");
605 goto init_fail;
606 }
607
608init_done:
609 return rc;
610
611init_fail:
612 kfree(mt9d112_ctrl);
613 return rc;
614}
615
616static int mt9d112_init_client(struct i2c_client *client)
617{
618 /* Initialize the MSM_CAMI2C Chip */
619 init_waitqueue_head(&mt9d112_wait_queue);
620 return 0;
621}
622
623int mt9d112_sensor_config(void __user *argp)
624{
625 struct sensor_cfg_data cfg_data;
626 long rc = 0;
627
628 if (copy_from_user(&cfg_data,
629 (void *)argp,
630 sizeof(struct sensor_cfg_data)))
631 return -EFAULT;
632
633 /* down(&mt9d112_sem); */
634
635 CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
636 cfg_data.cfgtype, cfg_data.mode);
637
638 switch (cfg_data.cfgtype) {
639 case CFG_SET_MODE:
640 rc = mt9d112_set_sensor_mode(
641 cfg_data.mode);
642 break;
643
644 case CFG_SET_EFFECT:
645 rc = mt9d112_set_effect(cfg_data.mode,
646 cfg_data.cfg.effect);
647 break;
648
649 case CFG_GET_AF_MAX_STEPS:
650 default:
651 rc = -EINVAL;
652 break;
653 }
654
655 /* up(&mt9d112_sem); */
656
657 return rc;
658}
659
660int mt9d112_sensor_release(void)
661{
662 int rc = 0;
663
664 /* down(&mt9d112_sem); */
665
666 kfree(mt9d112_ctrl);
667 /* up(&mt9d112_sem); */
668
669 return rc;
670}
671
672static int mt9d112_i2c_probe(struct i2c_client *client,
673 const struct i2c_device_id *id)
674{
675 int rc = 0;
676 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
677 rc = -ENOTSUPP;
678 goto probe_failure;
679 }
680
681 mt9d112_sensorw =
682 kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
683
684 if (!mt9d112_sensorw) {
685 rc = -ENOMEM;
686 goto probe_failure;
687 }
688
689 i2c_set_clientdata(client, mt9d112_sensorw);
690 mt9d112_init_client(client);
691 mt9d112_client = client;
692
693 CDBG("mt9d112_probe succeeded!\n");
694
695 return 0;
696
697probe_failure:
698 kfree(mt9d112_sensorw);
699 mt9d112_sensorw = NULL;
700 CDBG("mt9d112_probe failed!\n");
701 return rc;
702}
703
704static const struct i2c_device_id mt9d112_i2c_id[] = {
705 { "mt9d112", 0},
706 { },
707};
708
709static struct i2c_driver mt9d112_i2c_driver = {
710 .id_table = mt9d112_i2c_id,
711 .probe = mt9d112_i2c_probe,
712 .remove = __exit_p(mt9d112_i2c_remove),
713 .driver = {
714 .name = "mt9d112",
715 },
716};
717
718static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
719 struct msm_sensor_ctrl *s)
720{
721 int rc = i2c_add_driver(&mt9d112_i2c_driver);
722 if (rc < 0 || mt9d112_client == NULL) {
723 rc = -ENOTSUPP;
724 goto probe_done;
725 }
726
727 /* Input MCLK = 24MHz */
728 msm_camio_clk_rate_set(24000000);
729 mdelay(5);
730
731 rc = mt9d112_sensor_init_probe(info);
732 if (rc < 0)
733 goto probe_done;
734
735 s->s_init = mt9d112_sensor_init;
736 s->s_release = mt9d112_sensor_release;
737 s->s_config = mt9d112_sensor_config;
738
739probe_done:
740 CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
741 return rc;
742}
743
744static int __mt9d112_probe(struct platform_device *pdev)
745{
746 return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
747}
748
749static struct platform_driver msm_camera_driver = {
750 .probe = __mt9d112_probe,
751 .driver = {
752 .name = "msm_camera_mt9d112",
753 .owner = THIS_MODULE,
754 },
755};
756
757static int __init mt9d112_init(void)
758{
759 return platform_driver_register(&msm_camera_driver);
760}
761
762module_init(mt9d112_init);
diff --git a/drivers/staging/dream/camera/mt9d112.h b/drivers/staging/dream/camera/mt9d112.h
deleted file mode 100644
index c678996f9e2b..000000000000
--- a/drivers/staging/dream/camera/mt9d112.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef MT9D112_H
6#define MT9D112_H
7
8#include <linux/types.h>
9#include <mach/camera.h>
10
11enum mt9d112_width {
12 WORD_LEN,
13 BYTE_LEN
14};
15
16struct mt9d112_i2c_reg_conf {
17 unsigned short waddr;
18 unsigned short wdata;
19 enum mt9d112_width width;
20 unsigned short mdelay_time;
21};
22
23struct mt9d112_reg {
24 const struct register_address_value_pair *prev_snap_reg_settings;
25 uint16_t prev_snap_reg_settings_size;
26 const struct register_address_value_pair *noise_reduction_reg_settings;
27 uint16_t noise_reduction_reg_settings_size;
28 const struct mt9d112_i2c_reg_conf *plltbl;
29 uint16_t plltbl_size;
30 const struct mt9d112_i2c_reg_conf *stbl;
31 uint16_t stbl_size;
32 const struct mt9d112_i2c_reg_conf *rftbl;
33 uint16_t rftbl_size;
34};
35
36#endif /* MT9D112_H */
diff --git a/drivers/staging/dream/camera/mt9d112_reg.c b/drivers/staging/dream/camera/mt9d112_reg.c
deleted file mode 100644
index c52e96f47141..000000000000
--- a/drivers/staging/dream/camera/mt9d112_reg.c
+++ /dev/null
@@ -1,307 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include "mt9d112.h"
6
7struct register_address_value_pair
8preview_snapshot_mode_reg_settings_array[] = {
9 {0x338C, 0x2703},
10 {0x3390, 800}, /* Output Width (P) = 640 */
11 {0x338C, 0x2705},
12 {0x3390, 600}, /* Output Height (P) = 480 */
13 {0x338C, 0x2707},
14 {0x3390, 0x0640}, /* Output Width (S) = 1600 */
15 {0x338C, 0x2709},
16 {0x3390, 0x04B0}, /* Output Height (S) = 1200 */
17 {0x338C, 0x270D},
18 {0x3390, 0x0000}, /* Row Start (P) = 0 */
19 {0x338C, 0x270F},
20 {0x3390, 0x0000}, /* Column Start (P) = 0 */
21 {0x338C, 0x2711},
22 {0x3390, 0x04BD}, /* Row End (P) = 1213 */
23 {0x338C, 0x2713},
24 {0x3390, 0x064D}, /* Column End (P) = 1613 */
25 {0x338C, 0x2715},
26 {0x3390, 0x0000}, /* Extra Delay (P) = 0 */
27 {0x338C, 0x2717},
28 {0x3390, 0x2111}, /* Row Speed (P) = 8465 */
29 {0x338C, 0x2719},
30 {0x3390, 0x046C}, /* Read Mode (P) = 1132 */
31 {0x338C, 0x271B},
32 {0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
33 {0x338C, 0x271D},
34 {0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
35 {0x338C, 0x271F},
36 {0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
37 {0x338C, 0x2721},
38 {0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
39 {0x338C, 0x2723},
40 {0x3390, 659}, /* Frame Lines (P) = 679 */
41 {0x338C, 0x2725},
42 {0x3390, 0x0824}, /* Line Length (P) = 2084 */
43 {0x338C, 0x2727},
44 {0x3390, 0x2020},
45 {0x338C, 0x2729},
46 {0x3390, 0x2020},
47 {0x338C, 0x272B},
48 {0x3390, 0x1020},
49 {0x338C, 0x272D},
50 {0x3390, 0x2007},
51 {0x338C, 0x272F},
52 {0x3390, 0x0004}, /* Row Start(S) = 4 */
53 {0x338C, 0x2731},
54 {0x3390, 0x0004}, /* Column Start(S) = 4 */
55 {0x338C, 0x2733},
56 {0x3390, 0x04BB}, /* Row End(S) = 1211 */
57 {0x338C, 0x2735},
58 {0x3390, 0x064B}, /* Column End(S) = 1611 */
59 {0x338C, 0x2737},
60 {0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
61 {0x338C, 0x2739},
62 {0x3390, 0x2111}, /* Row Speed(S) = 8465 */
63 {0x338C, 0x273B},
64 {0x3390, 0x0024}, /* Read Mode(S) = 36 */
65 {0x338C, 0x273D},
66 {0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
67 {0x338C, 0x2741},
68 {0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
69 {0x338C, 0x2745},
70 {0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
71 {0x338C, 0x2747},
72 {0x3390, 0x0824}, /* Line Length(S) = 2084 */
73 {0x338C, 0x2751},
74 {0x3390, 0x0000}, /* Crop_X0(P) = 0 */
75 {0x338C, 0x2753},
76 {0x3390, 0x0320}, /* Crop_X1(P) = 800 */
77 {0x338C, 0x2755},
78 {0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
79 {0x338C, 0x2757},
80 {0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
81 {0x338C, 0x275F},
82 {0x3390, 0x0000}, /* Crop_X0(S) = 0 */
83 {0x338C, 0x2761},
84 {0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
85 {0x338C, 0x2763},
86 {0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
87 {0x338C, 0x2765},
88 {0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
89 {0x338C, 0x222E},
90 {0x3390, 0x00A0}, /* R9 Step = 160 */
91 {0x338C, 0xA408},
92 {0x3390, 0x001F},
93 {0x338C, 0xA409},
94 {0x3390, 0x0021},
95 {0x338C, 0xA40A},
96 {0x3390, 0x0025},
97 {0x338C, 0xA40B},
98 {0x3390, 0x0027},
99 {0x338C, 0x2411},
100 {0x3390, 0x00A0},
101 {0x338C, 0x2413},
102 {0x3390, 0x00C0},
103 {0x338C, 0x2415},
104 {0x3390, 0x00A0},
105 {0x338C, 0x2417},
106 {0x3390, 0x00C0},
107 {0x338C, 0x2799},
108 {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
109 {0x338C, 0x279B},
110 {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
111};
112
113static struct register_address_value_pair
114noise_reduction_reg_settings_array[] = {
115 {0x338C, 0xA76D},
116 {0x3390, 0x0003},
117 {0x338C, 0xA76E},
118 {0x3390, 0x0003},
119 {0x338C, 0xA76F},
120 {0x3390, 0},
121 {0x338C, 0xA770},
122 {0x3390, 21},
123 {0x338C, 0xA771},
124 {0x3390, 37},
125 {0x338C, 0xA772},
126 {0x3390, 63},
127 {0x338C, 0xA773},
128 {0x3390, 100},
129 {0x338C, 0xA774},
130 {0x3390, 128},
131 {0x338C, 0xA775},
132 {0x3390, 151},
133 {0x338C, 0xA776},
134 {0x3390, 169},
135 {0x338C, 0xA777},
136 {0x3390, 186},
137 {0x338C, 0xA778},
138 {0x3390, 199},
139 {0x338C, 0xA779},
140 {0x3390, 210},
141 {0x338C, 0xA77A},
142 {0x3390, 220},
143 {0x338C, 0xA77B},
144 {0x3390, 228},
145 {0x338C, 0xA77C},
146 {0x3390, 234},
147 {0x338C, 0xA77D},
148 {0x3390, 240},
149 {0x338C, 0xA77E},
150 {0x3390, 244},
151 {0x338C, 0xA77F},
152 {0x3390, 248},
153 {0x338C, 0xA780},
154 {0x3390, 252},
155 {0x338C, 0xA781},
156 {0x3390, 255},
157 {0x338C, 0xA782},
158 {0x3390, 0},
159 {0x338C, 0xA783},
160 {0x3390, 21},
161 {0x338C, 0xA784},
162 {0x3390, 37},
163 {0x338C, 0xA785},
164 {0x3390, 63},
165 {0x338C, 0xA786},
166 {0x3390, 100},
167 {0x338C, 0xA787},
168 {0x3390, 128},
169 {0x338C, 0xA788},
170 {0x3390, 151},
171 {0x338C, 0xA789},
172 {0x3390, 169},
173 {0x338C, 0xA78A},
174 {0x3390, 186},
175 {0x338C, 0xA78B},
176 {0x3390, 199},
177 {0x338C, 0xA78C},
178 {0x3390, 210},
179 {0x338C, 0xA78D},
180 {0x3390, 220},
181 {0x338C, 0xA78E},
182 {0x3390, 228},
183 {0x338C, 0xA78F},
184 {0x3390, 234},
185 {0x338C, 0xA790},
186 {0x3390, 240},
187 {0x338C, 0xA791},
188 {0x3390, 244},
189 {0x338C, 0xA793},
190 {0x3390, 252},
191 {0x338C, 0xA794},
192 {0x3390, 255},
193 {0x338C, 0xA103},
194 {0x3390, 6},
195};
196
197static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
198 { 0x34CE, 0x81A0, WORD_LEN, 0 },
199 { 0x34D0, 0x6331, WORD_LEN, 0 },
200 { 0x34D2, 0x3394, WORD_LEN, 0 },
201 { 0x34D4, 0x9966, WORD_LEN, 0 },
202 { 0x34D6, 0x4B25, WORD_LEN, 0 },
203 { 0x34D8, 0x2670, WORD_LEN, 0 },
204 { 0x34DA, 0x724C, WORD_LEN, 0 },
205 { 0x34DC, 0xFFFD, WORD_LEN, 0 },
206 { 0x34DE, 0x00CA, WORD_LEN, 0 },
207 { 0x34E6, 0x00AC, WORD_LEN, 0 },
208 { 0x34EE, 0x0EE1, WORD_LEN, 0 },
209 { 0x34F6, 0x0D87, WORD_LEN, 0 },
210 { 0x3500, 0xE1F7, WORD_LEN, 0 },
211 { 0x3508, 0x1CF4, WORD_LEN, 0 },
212 { 0x3510, 0x1D28, WORD_LEN, 0 },
213 { 0x3518, 0x1F26, WORD_LEN, 0 },
214 { 0x3520, 0x2220, WORD_LEN, 0 },
215 { 0x3528, 0x333D, WORD_LEN, 0 },
216 { 0x3530, 0x15D9, WORD_LEN, 0 },
217 { 0x3538, 0xCFB8, WORD_LEN, 0 },
218 { 0x354C, 0x05FE, WORD_LEN, 0 },
219 { 0x3544, 0x05F8, WORD_LEN, 0 },
220 { 0x355C, 0x0596, WORD_LEN, 0 },
221 { 0x3554, 0x0611, WORD_LEN, 0 },
222 { 0x34E0, 0x00F2, WORD_LEN, 0 },
223 { 0x34E8, 0x00A8, WORD_LEN, 0 },
224 { 0x34F0, 0x0F7B, WORD_LEN, 0 },
225 { 0x34F8, 0x0CD7, WORD_LEN, 0 },
226 { 0x3502, 0xFEDB, WORD_LEN, 0 },
227 { 0x350A, 0x13E4, WORD_LEN, 0 },
228 { 0x3512, 0x1F2C, WORD_LEN, 0 },
229 { 0x351A, 0x1D20, WORD_LEN, 0 },
230 { 0x3522, 0x2422, WORD_LEN, 0 },
231 { 0x352A, 0x2925, WORD_LEN, 0 },
232 { 0x3532, 0x1D04, WORD_LEN, 0 },
233 { 0x353A, 0xFBF2, WORD_LEN, 0 },
234 { 0x354E, 0x0616, WORD_LEN, 0 },
235 { 0x3546, 0x0597, WORD_LEN, 0 },
236 { 0x355E, 0x05CD, WORD_LEN, 0 },
237 { 0x3556, 0x0529, WORD_LEN, 0 },
238 { 0x34E4, 0x00B2, WORD_LEN, 0 },
239 { 0x34EC, 0x005E, WORD_LEN, 0 },
240 { 0x34F4, 0x0F43, WORD_LEN, 0 },
241 { 0x34FC, 0x0E2F, WORD_LEN, 0 },
242 { 0x3506, 0xF9FC, WORD_LEN, 0 },
243 { 0x350E, 0x0CE4, WORD_LEN, 0 },
244 { 0x3516, 0x1E1E, WORD_LEN, 0 },
245 { 0x351E, 0x1B19, WORD_LEN, 0 },
246 { 0x3526, 0x151B, WORD_LEN, 0 },
247 { 0x352E, 0x1416, WORD_LEN, 0 },
248 { 0x3536, 0x10FC, WORD_LEN, 0 },
249 { 0x353E, 0xC018, WORD_LEN, 0 },
250 { 0x3552, 0x06B4, WORD_LEN, 0 },
251 { 0x354A, 0x0506, WORD_LEN, 0 },
252 { 0x3562, 0x06AB, WORD_LEN, 0 },
253 { 0x355A, 0x063A, WORD_LEN, 0 },
254 { 0x34E2, 0x00E5, WORD_LEN, 0 },
255 { 0x34EA, 0x008B, WORD_LEN, 0 },
256 { 0x34F2, 0x0E4C, WORD_LEN, 0 },
257 { 0x34FA, 0x0CA3, WORD_LEN, 0 },
258 { 0x3504, 0x0907, WORD_LEN, 0 },
259 { 0x350C, 0x1DFD, WORD_LEN, 0 },
260 { 0x3514, 0x1E24, WORD_LEN, 0 },
261 { 0x351C, 0x2529, WORD_LEN, 0 },
262 { 0x3524, 0x1D20, WORD_LEN, 0 },
263 { 0x352C, 0x2332, WORD_LEN, 0 },
264 { 0x3534, 0x10E9, WORD_LEN, 0 },
265 { 0x353C, 0x0BCB, WORD_LEN, 0 },
266 { 0x3550, 0x04EF, WORD_LEN, 0 },
267 { 0x3548, 0x0609, WORD_LEN, 0 },
268 { 0x3560, 0x0580, WORD_LEN, 0 },
269 { 0x3558, 0x05DD, WORD_LEN, 0 },
270 { 0x3540, 0x0000, WORD_LEN, 0 },
271 { 0x3542, 0x0000, WORD_LEN, 0 }
272};
273
274static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
275 { 0x341E, 0x8F09, WORD_LEN, 0 },
276 { 0x341C, 0x0250, WORD_LEN, 0 },
277 { 0x341E, 0x8F09, WORD_LEN, 5 },
278 { 0x341E, 0x8F08, WORD_LEN, 0 }
279};
280
281/* Refresh Sequencer */
282static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
283 { 0x338C, 0x2799, WORD_LEN, 0},
284 { 0x3390, 0x6440, WORD_LEN, 5},
285 { 0x338C, 0x279B, WORD_LEN, 0},
286 { 0x3390, 0x6440, WORD_LEN, 5},
287 { 0x338C, 0xA103, WORD_LEN, 0},
288 { 0x3390, 0x0005, WORD_LEN, 5},
289 { 0x338C, 0xA103, WORD_LEN, 0},
290 { 0x3390, 0x0006, WORD_LEN, 5}
291};
292
293struct mt9d112_reg mt9d112_regs = {
294 .prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
295 .prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array),
296 .noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
297 .noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array),
298 .plltbl = pll_setup_tbl,
299 .plltbl_size = ARRAY_SIZE(pll_setup_tbl),
300 .stbl = sequencer_tbl,
301 .stbl_size = ARRAY_SIZE(sequencer_tbl),
302 .rftbl = lens_roll_off_tbl,
303 .rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
304};
305
306
307
diff --git a/drivers/staging/dream/camera/mt9p012.h b/drivers/staging/dream/camera/mt9p012.h
deleted file mode 100644
index 678a0027d42e..000000000000
--- a/drivers/staging/dream/camera/mt9p012.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5
6#ifndef MT9T012_H
7#define MT9T012_H
8
9#include <linux/types.h>
10
11struct reg_struct {
12 uint16_t vt_pix_clk_div; /* 0x0300 */
13 uint16_t vt_sys_clk_div; /* 0x0302 */
14 uint16_t pre_pll_clk_div; /* 0x0304 */
15 uint16_t pll_multiplier; /* 0x0306 */
16 uint16_t op_pix_clk_div; /* 0x0308 */
17 uint16_t op_sys_clk_div; /* 0x030A */
18 uint16_t scale_m; /* 0x0404 */
19 uint16_t row_speed; /* 0x3016 */
20 uint16_t x_addr_start; /* 0x3004 */
21 uint16_t x_addr_end; /* 0x3008 */
22 uint16_t y_addr_start; /* 0x3002 */
23 uint16_t y_addr_end; /* 0x3006 */
24 uint16_t read_mode; /* 0x3040 */
25 uint16_t x_output_size ; /* 0x034C */
26 uint16_t y_output_size; /* 0x034E */
27 uint16_t line_length_pck; /* 0x300C */
28 uint16_t frame_length_lines; /* 0x300A */
29 uint16_t coarse_int_time; /* 0x3012 */
30 uint16_t fine_int_time; /* 0x3014 */
31};
32
33
34struct mt9p012_i2c_reg_conf {
35 unsigned short waddr;
36 unsigned short wdata;
37};
38
39
40struct mt9p012_reg {
41 struct reg_struct *reg_pat;
42 uint16_t reg_pat_size;
43 struct mt9p012_i2c_reg_conf *ttbl;
44 uint16_t ttbl_size;
45 struct mt9p012_i2c_reg_conf *lctbl;
46 uint16_t lctbl_size;
47 struct mt9p012_i2c_reg_conf *rftbl;
48 uint16_t rftbl_size;
49};
50
51#endif /* MT9T012_H */
diff --git a/drivers/staging/dream/camera/mt9p012_fox.c b/drivers/staging/dream/camera/mt9p012_fox.c
deleted file mode 100644
index 791bd6c40615..000000000000
--- a/drivers/staging/dream/camera/mt9p012_fox.c
+++ /dev/null
@@ -1,1306 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/delay.h>
6#include <linux/types.h>
7#include <linux/slab.h>
8#include <linux/i2c.h>
9#include <linux/uaccess.h>
10#include <linux/miscdevice.h>
11#include <linux/kernel.h>
12#include <media/msm_camera.h>
13#include <mach/gpio.h>
14#include <mach/camera.h>
15#include "mt9p012.h"
16
17/*=============================================================
18 SENSOR REGISTER DEFINES
19==============================================================*/
20#define MT9P012_REG_MODEL_ID 0x0000
21#define MT9P012_MODEL_ID 0x2801
22#define REG_GROUPED_PARAMETER_HOLD 0x0104
23#define GROUPED_PARAMETER_HOLD 0x0100
24#define GROUPED_PARAMETER_UPDATE 0x0000
25#define REG_COARSE_INT_TIME 0x3012
26#define REG_VT_PIX_CLK_DIV 0x0300
27#define REG_VT_SYS_CLK_DIV 0x0302
28#define REG_PRE_PLL_CLK_DIV 0x0304
29#define REG_PLL_MULTIPLIER 0x0306
30#define REG_OP_PIX_CLK_DIV 0x0308
31#define REG_OP_SYS_CLK_DIV 0x030A
32#define REG_SCALE_M 0x0404
33#define REG_FRAME_LENGTH_LINES 0x300A
34#define REG_LINE_LENGTH_PCK 0x300C
35#define REG_X_ADDR_START 0x3004
36#define REG_Y_ADDR_START 0x3002
37#define REG_X_ADDR_END 0x3008
38#define REG_Y_ADDR_END 0x3006
39#define REG_X_OUTPUT_SIZE 0x034C
40#define REG_Y_OUTPUT_SIZE 0x034E
41#define REG_FINE_INTEGRATION_TIME 0x3014
42#define REG_ROW_SPEED 0x3016
43#define MT9P012_REG_RESET_REGISTER 0x301A
44#define MT9P012_RESET_REGISTER_PWON 0x10CC
45#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
46#define REG_READ_MODE 0x3040
47#define REG_GLOBAL_GAIN 0x305E
48#define REG_TEST_PATTERN_MODE 0x3070
49
50#define MT9P012_REV_7
51
52
53enum mt9p012_test_mode {
54 TEST_OFF,
55 TEST_1,
56 TEST_2,
57 TEST_3
58};
59
60enum mt9p012_resolution {
61 QTR_SIZE,
62 FULL_SIZE,
63 INVALID_SIZE
64};
65
66enum mt9p012_reg_update {
67 /* Sensor egisters that need to be updated during initialization */
68 REG_INIT,
69 /* Sensor egisters that needs periodic I2C writes */
70 UPDATE_PERIODIC,
71 /* All the sensor Registers will be updated */
72 UPDATE_ALL,
73 /* Not valid update */
74 UPDATE_INVALID
75};
76
77enum mt9p012_setting {
78 RES_PREVIEW,
79 RES_CAPTURE
80};
81
82/* actuator's Slave Address */
83#define MT9P012_AF_I2C_ADDR 0x18
84
85/* AF Total steps parameters */
86#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF 32
87#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR 32
88
89#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
90#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES 0
91
92/* Time in milisecs for waiting for the sensor to reset.*/
93#define MT9P012_RESET_DELAY_MSECS 66
94
95/* for 20 fps preview */
96#define MT9P012_DEFAULT_CLOCK_RATE 24000000
97#define MT9P012_DEFAULT_MAX_FPS 26 /* ???? */
98
99struct mt9p012_work {
100 struct work_struct work;
101};
102static struct mt9p012_work *mt9p012_sensorw;
103static struct i2c_client *mt9p012_client;
104
105struct mt9p012_ctrl {
106 const struct msm_camera_sensor_info *sensordata;
107
108 int sensormode;
109 uint32_t fps_divider; /* init to 1 * 0x00000400 */
110 uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
111
112 uint16_t curr_lens_pos;
113 uint16_t init_curr_lens_pos;
114 uint16_t my_reg_gain;
115 uint32_t my_reg_line_count;
116
117 enum mt9p012_resolution prev_res;
118 enum mt9p012_resolution pict_res;
119 enum mt9p012_resolution curr_res;
120 enum mt9p012_test_mode set_test;
121};
122
123
124static struct mt9p012_ctrl *mt9p012_ctrl;
125static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
126DECLARE_MUTEX(mt9p012_sem);
127
128/*=============================================================
129 EXTERNAL DECLARATIONS
130==============================================================*/
131extern struct mt9p012_reg mt9p012_regs; /* from mt9p012_reg.c */
132
133
134
135/*=============================================================*/
136
137static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
138 int length)
139{
140 struct i2c_msg msgs[] = {
141 {
142 .addr = saddr,
143 .flags = 0,
144 .len = 2,
145 .buf = rxdata,
146 },
147 {
148 .addr = saddr,
149 .flags = I2C_M_RD,
150 .len = length,
151 .buf = rxdata,
152 },
153 };
154
155 if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) {
156 CDBG("mt9p012_i2c_rxdata failed!\n");
157 return -EIO;
158 }
159
160 return 0;
161}
162
163static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
164 unsigned short *rdata)
165{
166 int32_t rc = 0;
167 unsigned char buf[4];
168
169 if (!rdata)
170 return -EIO;
171
172 memset(buf, 0, sizeof(buf));
173
174 buf[0] = (raddr & 0xFF00)>>8;
175 buf[1] = (raddr & 0x00FF);
176
177 rc = mt9p012_i2c_rxdata(saddr, buf, 2);
178 if (rc < 0)
179 return rc;
180
181 *rdata = buf[0] << 8 | buf[1];
182
183 if (rc < 0)
184 CDBG("mt9p012_i2c_read failed!\n");
185
186 return rc;
187}
188
189static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
190 int length)
191{
192 struct i2c_msg msg[] = {
193 {
194 .addr = saddr,
195 .flags = 0,
196 .len = length,
197 .buf = txdata,
198 },
199 };
200
201 if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) {
202 CDBG("mt9p012_i2c_txdata failed\n");
203 return -EIO;
204 }
205
206 return 0;
207}
208
209static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
210 unsigned short bdata)
211{
212 int32_t rc = -EIO;
213 unsigned char buf[2];
214
215 memset(buf, 0, sizeof(buf));
216 buf[0] = baddr;
217 buf[1] = bdata;
218 rc = mt9p012_i2c_txdata(saddr, buf, 2);
219
220 if (rc < 0)
221 CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
222 saddr, baddr, bdata);
223
224 return rc;
225}
226
227static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
228 unsigned short wdata)
229{
230 int32_t rc = -EIO;
231 unsigned char buf[4];
232
233 memset(buf, 0, sizeof(buf));
234 buf[0] = (waddr & 0xFF00)>>8;
235 buf[1] = (waddr & 0x00FF);
236 buf[2] = (wdata & 0xFF00)>>8;
237 buf[3] = (wdata & 0x00FF);
238
239 rc = mt9p012_i2c_txdata(saddr, buf, 4);
240
241 if (rc < 0)
242 CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
243 waddr, wdata);
244
245 return rc;
246}
247
248static int32_t mt9p012_i2c_write_w_table(
249 struct mt9p012_i2c_reg_conf *reg_conf_tbl, int num)
250{
251 int i;
252 int32_t rc = -EIO;
253
254 for (i = 0; i < num; i++) {
255 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
256 reg_conf_tbl->waddr, reg_conf_tbl->wdata);
257 if (rc < 0)
258 break;
259 reg_conf_tbl++;
260 }
261
262 return rc;
263}
264
265static int32_t mt9p012_test(enum mt9p012_test_mode mo)
266{
267 int32_t rc = 0;
268
269 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
270 REG_GROUPED_PARAMETER_HOLD,
271 GROUPED_PARAMETER_HOLD);
272 if (rc < 0)
273 return rc;
274
275 if (mo == TEST_OFF)
276 return 0;
277 else {
278 rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl, mt9p012_regs.ttbl_size);
279 if (rc < 0)
280 return rc;
281
282 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
283 REG_TEST_PATTERN_MODE, (uint16_t)mo);
284 if (rc < 0)
285 return rc;
286 }
287
288 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
289 REG_GROUPED_PARAMETER_HOLD,
290 GROUPED_PARAMETER_UPDATE);
291 if (rc < 0)
292 return rc;
293
294 return rc;
295}
296
297static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
298{
299 int32_t rc = 0;
300
301 CDBG("%s: entered. enable = %d\n", __func__, is_enable);
302
303 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
304 REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
305 if (rc < 0)
306 return rc;
307
308 rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
309 ((uint16_t) is_enable) << 15);
310 if (rc < 0)
311 return rc;
312
313 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
314 REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
315
316 CDBG("%s: exiting. rc = %d\n", __func__, rc);
317 return rc;
318}
319
320static int32_t mt9p012_set_lc(void)
321{
322 int32_t rc;
323
324 rc = mt9p012_i2c_write_w_table(mt9p012_regs.lctbl, mt9p012_regs.lctbl_size);
325 if (rc < 0)
326 return rc;
327
328 rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl, mt9p012_regs.rftbl_size);
329
330 return rc;
331}
332
333static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
334{
335 /* input fps is preview fps in Q8 format */
336 uint32_t divider; /*Q10 */
337 uint32_t pclk_mult; /*Q10 */
338
339 if (mt9p012_ctrl->prev_res == QTR_SIZE) {
340 divider = (uint32_t)
341 (((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
342 mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) * 0x00000400) /
343 (mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines *
344 mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck));
345
346 pclk_mult =
347 (uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier *
348 0x00000400) / (mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier));
349 } else {
350 /* full size resolution used for preview. */
351 divider = 0x00000400; /*1.0 */
352 pclk_mult = 0x00000400; /*1.0 */
353 }
354
355 /* Verify PCLK settings and frame sizes. */
356 *pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
357 0x00000400);
358}
359
360static uint16_t mt9p012_get_prev_lines_pf(void)
361{
362 if (mt9p012_ctrl->prev_res == QTR_SIZE)
363 return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
364 else
365 return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
366}
367
368static uint16_t mt9p012_get_prev_pixels_pl(void)
369{
370 if (mt9p012_ctrl->prev_res == QTR_SIZE)
371 return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
372 else
373 return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
374}
375
376static uint16_t mt9p012_get_pict_lines_pf(void)
377{
378 return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
379}
380
381static uint16_t mt9p012_get_pict_pixels_pl(void)
382{
383 return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
384}
385
386static uint32_t mt9p012_get_pict_max_exp_lc(void)
387{
388 uint16_t snapshot_lines_per_frame;
389
390 if (mt9p012_ctrl->pict_res == QTR_SIZE)
391 snapshot_lines_per_frame =
392 mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
393 else
394 snapshot_lines_per_frame =
395 mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
396
397 return snapshot_lines_per_frame * 24;
398}
399
400static int32_t mt9p012_set_fps(struct fps_cfg *fps)
401{
402 /* input is new fps in Q10 format */
403 int32_t rc = 0;
404
405 mt9p012_ctrl->fps_divider = fps->fps_div;
406 mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
407
408 rc =
409 mt9p012_i2c_write_w(mt9p012_client->addr,
410 REG_GROUPED_PARAMETER_HOLD,
411 GROUPED_PARAMETER_HOLD);
412 if (rc < 0)
413 return -EBUSY;
414
415 rc =
416 mt9p012_i2c_write_w(mt9p012_client->addr,
417 REG_LINE_LENGTH_PCK,
418 (mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck *
419 fps->f_mult / 0x00000400));
420 if (rc < 0)
421 return rc;
422
423 rc =
424 mt9p012_i2c_write_w(mt9p012_client->addr,
425 REG_GROUPED_PARAMETER_HOLD,
426 GROUPED_PARAMETER_UPDATE);
427
428 return rc;
429}
430
431static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
432{
433 uint16_t max_legal_gain = 0x01FF;
434 uint32_t line_length_ratio = 0x00000400;
435 enum mt9p012_setting setting;
436 int32_t rc = 0;
437
438 CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
439
440 if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
441 mt9p012_ctrl->my_reg_gain = gain;
442 mt9p012_ctrl->my_reg_line_count = (uint16_t)line;
443 }
444
445 if (gain > max_legal_gain) {
446 CDBG("Max legal gain Line:%d \n", __LINE__);
447 gain = max_legal_gain;
448 }
449
450 /* Verify no overflow */
451 if (mt9p012_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
452 line = (uint32_t)(line * mt9p012_ctrl->fps_divider /
453 0x00000400);
454 setting = RES_PREVIEW;
455 } else {
456 line = (uint32_t)(line * mt9p012_ctrl->pict_fps_divider /
457 0x00000400);
458 setting = RES_CAPTURE;
459 }
460
461 /* Set digital gain to 1 */
462#ifdef MT9P012_REV_7
463 gain |= 0x1000;
464#else
465 gain |= 0x0200;
466#endif
467
468 if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
469 line_length_ratio = (uint32_t) (line * 0x00000400) /
470 (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
471 } else
472 line_length_ratio = 0x00000400;
473
474 rc =
475 mt9p012_i2c_write_w(mt9p012_client->addr,
476 REG_GROUPED_PARAMETER_HOLD,
477 GROUPED_PARAMETER_HOLD);
478 if (rc < 0) {
479 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
480 return rc;
481 }
482
483 rc =
484 mt9p012_i2c_write_w(
485 mt9p012_client->addr,
486 REG_GLOBAL_GAIN, gain);
487 if (rc < 0) {
488 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
489 return rc;
490 }
491
492 rc =
493 mt9p012_i2c_write_w(mt9p012_client->addr,
494 REG_COARSE_INT_TIME,
495 line);
496 if (rc < 0) {
497 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
498 return rc;
499 }
500
501 CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
502
503 rc =
504 mt9p012_i2c_write_w(mt9p012_client->addr,
505 REG_GROUPED_PARAMETER_HOLD,
506 GROUPED_PARAMETER_UPDATE);
507 if (rc < 0)
508 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
509
510 return rc;
511}
512
513static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
514{
515 int32_t rc = 0;
516
517 CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
518
519 rc =
520 mt9p012_write_exp_gain(gain, line);
521 if (rc < 0) {
522 CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
523 __LINE__);
524 return rc;
525 }
526
527 rc =
528 mt9p012_i2c_write_w(mt9p012_client->addr,
529 MT9P012_REG_RESET_REGISTER,
530 0x10CC | 0x0002);
531 if (rc < 0) {
532 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
533 return rc;
534 }
535
536 mdelay(5);
537
538 /* camera_timed_wait(snapshot_wait*exposure_ratio); */
539 return rc;
540}
541
542static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
543 enum mt9p012_setting rt)
544{
545 int32_t rc = 0;
546
547 switch (rupdate) {
548 case UPDATE_PERIODIC:
549 if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
550
551 struct mt9p012_i2c_reg_conf ppc_tbl[] = {
552 {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
553 {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
554 {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
555 {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
556 {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
557 {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
558 {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
559 {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
560 {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
561 {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
562
563 {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
564 {REG_FRAME_LENGTH_LINES,
565 (mt9p012_regs.reg_pat[rt].frame_length_lines *
566 mt9p012_ctrl->fps_divider / 0x00000400)},
567 {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
568 {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
569 {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
570 };
571
572 rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
573 ARRAY_SIZE(ppc_tbl));
574 if (rc < 0)
575 return rc;
576
577 rc = mt9p012_test(mt9p012_ctrl->set_test);
578 if (rc < 0)
579 return rc;
580
581 rc =
582 mt9p012_i2c_write_w(mt9p012_client->addr,
583 MT9P012_REG_RESET_REGISTER,
584 MT9P012_RESET_REGISTER_PWON | 0x0002);
585 if (rc < 0)
586 return rc;
587
588 mdelay(5); /* 15? wait for sensor to transition*/
589
590 return rc;
591 }
592 break; /* UPDATE_PERIODIC */
593
594 case REG_INIT:
595 if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
596 struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
597 {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
598 {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
599 {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
600 {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
601 {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
602 {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
603 {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
604#ifdef MT9P012_REV_7
605 {0x30B0, 0x0001},
606 {0x308E, 0xE060},
607 {0x3092, 0x0A52},
608 {0x3094, 0x4656},
609 {0x3096, 0x5652},
610 {0x30CA, 0x8006},
611 {0x312A, 0xDD02},
612 {0x312C, 0x00E4},
613 {0x3170, 0x299A},
614#endif
615 /* optimized settings for noise */
616 {0x3088, 0x6FF6},
617 {0x3154, 0x0282},
618 {0x3156, 0x0381},
619 {0x3162, 0x04CE},
620 {0x0204, 0x0010},
621 {0x0206, 0x0010},
622 {0x0208, 0x0010},
623 {0x020A, 0x0010},
624 {0x020C, 0x0010},
625 {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
626 };
627
628 struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
629 {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
630 {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
631 {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
632 {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
633 {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
634 {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
635 {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
636#ifdef MT9P012_REV_7
637 {0x30B0, 0x0001},
638 {0x308E, 0xE060},
639 {0x3092, 0x0A52},
640 {0x3094, 0x4656},
641 {0x3096, 0x5652},
642 {0x30CA, 0x8006},
643 {0x312A, 0xDD02},
644 {0x312C, 0x00E4},
645 {0x3170, 0x299A},
646#endif
647 /* optimized settings for noise */
648 {0x3088, 0x6FF6},
649 {0x3154, 0x0282},
650 {0x3156, 0x0381},
651 {0x3162, 0x04CE},
652 {0x0204, 0x0010},
653 {0x0206, 0x0010},
654 {0x0208, 0x0010},
655 {0x020A, 0x0010},
656 {0x020C, 0x0010},
657 {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
658 };
659
660 struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
661 {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
662 /* Set preview or snapshot mode */
663 {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
664 {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
665 {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
666 {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
667 {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
668 {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
669 {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
670 {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
671 {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
672 {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
673 {REG_FRAME_LENGTH_LINES,
674 mt9p012_regs.reg_pat[rt].frame_length_lines},
675 {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
676 {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
677 {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
678 };
679
680 /* reset fps_divider */
681 mt9p012_ctrl->fps_divider = 1 * 0x0400;
682
683 rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
684 ARRAY_SIZE(ipc_tbl1));
685 if (rc < 0)
686 return rc;
687
688 rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
689 ARRAY_SIZE(ipc_tbl2));
690 if (rc < 0)
691 return rc;
692
693 mdelay(5);
694
695 rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
696 ARRAY_SIZE(ipc_tbl3));
697 if (rc < 0)
698 return rc;
699
700 /* load lens shading */
701 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
702 REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
703 if (rc < 0)
704 return rc;
705
706 rc = mt9p012_set_lc();
707 if (rc < 0)
708 return rc;
709
710 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
711 REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
712
713 if (rc < 0)
714 return rc;
715 }
716 break; /* case REG_INIT: */
717
718 default:
719 rc = -EINVAL;
720 break;
721 } /* switch (rupdate) */
722
723 return rc;
724}
725
726static int32_t mt9p012_video_config(int mode, int res)
727{
728 int32_t rc;
729
730 switch (res) {
731 case QTR_SIZE:
732 rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
733 if (rc < 0)
734 return rc;
735
736 CDBG("mt9p012 sensor configuration done!\n");
737 break;
738
739 case FULL_SIZE:
740 rc =
741 mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
742 if (rc < 0)
743 return rc;
744
745 break;
746
747 default:
748 return 0;
749 } /* switch */
750
751 mt9p012_ctrl->prev_res = res;
752 mt9p012_ctrl->curr_res = res;
753 mt9p012_ctrl->sensormode = mode;
754
755 rc =
756 mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
757 mt9p012_ctrl->my_reg_line_count);
758
759 rc =
760 mt9p012_i2c_write_w(mt9p012_client->addr,
761 MT9P012_REG_RESET_REGISTER,
762 0x10cc|0x0002);
763
764 return rc;
765}
766
767static int32_t mt9p012_snapshot_config(int mode)
768{
769 int32_t rc = 0;
770
771 rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
772 if (rc < 0)
773 return rc;
774
775 mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
776
777 mt9p012_ctrl->sensormode = mode;
778
779 return rc;
780}
781
782static int32_t mt9p012_raw_snapshot_config(int mode)
783{
784 int32_t rc = 0;
785
786 rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
787 if (rc < 0)
788 return rc;
789
790 mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
791
792 mt9p012_ctrl->sensormode = mode;
793
794 return rc;
795}
796
797static int32_t mt9p012_power_down(void)
798{
799 int32_t rc = 0;
800
801 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
802 MT9P012_REG_RESET_REGISTER,
803 MT9P012_RESET_REGISTER_PWOFF);
804
805 mdelay(5);
806 return rc;
807}
808
809static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
810{
811 int16_t step_direction;
812 int16_t actual_step;
813 int16_t next_position;
814 uint8_t code_val_msb, code_val_lsb;
815
816 if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
817 num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
818 else if (num_steps == 0) {
819 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
820 return -EINVAL;
821 }
822
823 if (direction == MOVE_NEAR)
824 step_direction = 16; /* 10bit */
825 else if (direction == MOVE_FAR)
826 step_direction = -16; /* 10 bit */
827 else {
828 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
829 return -EINVAL;
830 }
831
832 if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
833 mt9p012_ctrl->curr_lens_pos =
834 mt9p012_ctrl->init_curr_lens_pos;
835
836 actual_step = (int16_t)(step_direction * (int16_t)num_steps);
837 next_position = (int16_t)(mt9p012_ctrl->curr_lens_pos + actual_step);
838
839 if (next_position > 1023)
840 next_position = 1023;
841 else if (next_position < 0)
842 next_position = 0;
843
844 code_val_msb = next_position >> 4;
845 code_val_lsb = (next_position & 0x000F) << 4;
846 /* code_val_lsb |= mode_mask; */
847
848 /* Writing the digital code for current to the actuator */
849 if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
850 code_val_msb, code_val_lsb) < 0) {
851 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
852 return -EBUSY;
853 }
854
855 /* Storing the current lens Position */
856 mt9p012_ctrl->curr_lens_pos = next_position;
857
858 return 0;
859}
860
861static int32_t mt9p012_set_default_focus(void)
862{
863 int32_t rc = 0;
864 uint8_t code_val_msb, code_val_lsb;
865
866 code_val_msb = 0x00;
867 code_val_lsb = 0x00;
868
869 /* Write the digital code for current to the actuator */
870 rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
871 code_val_msb, code_val_lsb);
872
873 mt9p012_ctrl->curr_lens_pos = 0;
874 mt9p012_ctrl->init_curr_lens_pos = 0;
875
876 return rc;
877}
878
879static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
880{
881 gpio_direction_output(data->sensor_reset, 0);
882 gpio_free(data->sensor_reset);
883 return 0;
884}
885
886static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
887{
888 int32_t rc;
889 uint16_t chipid;
890
891 rc = gpio_request(data->sensor_reset, "mt9p012");
892 if (!rc)
893 gpio_direction_output(data->sensor_reset, 1);
894 else
895 goto init_probe_done;
896
897 mdelay(20);
898
899 /* RESET the sensor image part via I2C command */
900 CDBG("mt9p012_sensor_init(): reseting sensor.\n");
901 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
902 MT9P012_REG_RESET_REGISTER, 0x10CC|0x0001);
903 if (rc < 0) {
904 CDBG("sensor reset failed. rc = %d\n", rc);
905 goto init_probe_fail;
906 }
907
908 mdelay(MT9P012_RESET_DELAY_MSECS);
909
910 /* 3. Read sensor Model ID: */
911 rc = mt9p012_i2c_read_w(mt9p012_client->addr,
912 MT9P012_REG_MODEL_ID, &chipid);
913 if (rc < 0)
914 goto init_probe_fail;
915
916 /* 4. Compare sensor ID to MT9T012VC ID: */
917 if (chipid != MT9P012_MODEL_ID) {
918 CDBG("mt9p012 wrong model_id = 0x%x\n", chipid);
919 rc = -ENODEV;
920 goto init_probe_fail;
921 }
922
923 rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
924 if (rc < 0) {
925 CDBG("REV_7 write failed. rc = %d\n", rc);
926 goto init_probe_fail;
927 }
928
929 /* RESET_REGISTER, enable parallel interface and disable serialiser */
930 CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
931 rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
932 if (rc < 0) {
933 CDBG("enable parallel interface failed. rc = %d\n", rc);
934 goto init_probe_fail;
935 }
936
937 /* To disable the 2 extra lines */
938 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
939 0x3064, 0x0805);
940
941 if (rc < 0) {
942 CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
943 goto init_probe_fail;
944 }
945
946 mdelay(MT9P012_RESET_DELAY_MSECS);
947 goto init_probe_done;
948
949init_probe_fail:
950 mt9p012_probe_init_done(data);
951init_probe_done:
952 return rc;
953}
954
955static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
956{
957 int32_t rc;
958
959 mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
960 if (!mt9p012_ctrl) {
961 CDBG("mt9p012_init failed!\n");
962 rc = -ENOMEM;
963 goto init_done;
964 }
965
966 mt9p012_ctrl->fps_divider = 1 * 0x00000400;
967 mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
968 mt9p012_ctrl->set_test = TEST_OFF;
969 mt9p012_ctrl->prev_res = QTR_SIZE;
970 mt9p012_ctrl->pict_res = FULL_SIZE;
971
972 if (data)
973 mt9p012_ctrl->sensordata = data;
974
975 /* enable mclk first */
976 msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
977 mdelay(20);
978
979 msm_camio_camif_pad_reg_reset();
980 mdelay(20);
981
982 rc = mt9p012_probe_init_sensor(data);
983 if (rc < 0)
984 goto init_fail1;
985
986 if (mt9p012_ctrl->prev_res == QTR_SIZE)
987 rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
988 else
989 rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
990
991 if (rc < 0) {
992 CDBG("mt9p012_setting failed. rc = %d\n", rc);
993 goto init_fail1;
994 }
995
996 /* sensor : output enable */
997 CDBG("mt9p012_sensor_open_init(): enabling output.\n");
998 rc = mt9p012_i2c_write_w(mt9p012_client->addr,
999 MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON);
1000 if (rc < 0) {
1001 CDBG("sensor output enable failed. rc = %d\n", rc);
1002 goto init_fail1;
1003 }
1004
1005 /* TODO: enable AF actuator */
1006#if 0
1007 CDBG("enable AF actuator, gpio = %d\n",
1008 mt9p012_ctrl->sensordata->vcm_pwd);
1009 rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012");
1010 if (!rc)
1011 gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1);
1012 else {
1013 CDBG("mt9p012_ctrl gpio request failed!\n");
1014 goto init_fail1;
1015 }
1016 mdelay(20);
1017
1018 rc = mt9p012_set_default_focus();
1019#endif
1020 if (rc >= 0)
1021 goto init_done;
1022
1023 /* TODO:
1024 * gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
1025 * gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); */
1026init_fail1:
1027 mt9p012_probe_init_done(data);
1028 kfree(mt9p012_ctrl);
1029init_done:
1030 return rc;
1031}
1032
1033static int mt9p012_init_client(struct i2c_client *client)
1034{
1035 /* Initialize the MSM_CAMI2C Chip */
1036 init_waitqueue_head(&mt9p012_wait_queue);
1037 return 0;
1038}
1039
1040static int32_t mt9p012_set_sensor_mode(int mode, int res)
1041{
1042 int32_t rc = 0;
1043
1044 switch (mode) {
1045 case SENSOR_PREVIEW_MODE:
1046 rc = mt9p012_video_config(mode, res);
1047 break;
1048
1049 case SENSOR_SNAPSHOT_MODE:
1050 rc = mt9p012_snapshot_config(mode);
1051 break;
1052
1053 case SENSOR_RAW_SNAPSHOT_MODE:
1054 rc = mt9p012_raw_snapshot_config(mode);
1055 break;
1056
1057 default:
1058 rc = -EINVAL;
1059 break;
1060 }
1061
1062 return rc;
1063}
1064
1065int mt9p012_sensor_config(void __user *argp)
1066{
1067 struct sensor_cfg_data cdata;
1068 int rc = 0;
1069
1070 if (copy_from_user(&cdata,
1071 (void *)argp,
1072 sizeof(struct sensor_cfg_data)))
1073 return -EFAULT;
1074
1075 down(&mt9p012_sem);
1076
1077 CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
1078 switch (cdata.cfgtype) {
1079 case CFG_GET_PICT_FPS:
1080 mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
1081 &(cdata.cfg.gfps.pictfps));
1082
1083 if (copy_to_user((void *)argp, &cdata,
1084 sizeof(struct sensor_cfg_data)))
1085 rc = -EFAULT;
1086 break;
1087
1088 case CFG_GET_PREV_L_PF:
1089 cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
1090
1091 if (copy_to_user((void *)argp,
1092 &cdata,
1093 sizeof(struct sensor_cfg_data)))
1094 rc = -EFAULT;
1095 break;
1096
1097 case CFG_GET_PREV_P_PL:
1098 cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
1099
1100 if (copy_to_user((void *)argp,
1101 &cdata,
1102 sizeof(struct sensor_cfg_data)))
1103 rc = -EFAULT;
1104 break;
1105
1106 case CFG_GET_PICT_L_PF:
1107 cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
1108
1109 if (copy_to_user((void *)argp,
1110 &cdata,
1111 sizeof(struct sensor_cfg_data)))
1112 rc = -EFAULT;
1113 break;
1114
1115 case CFG_GET_PICT_P_PL:
1116 cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
1117
1118 if (copy_to_user((void *)argp,
1119 &cdata,
1120 sizeof(struct sensor_cfg_data)))
1121 rc = -EFAULT;
1122 break;
1123
1124 case CFG_GET_PICT_MAX_EXP_LC:
1125 cdata.cfg.pict_max_exp_lc =
1126 mt9p012_get_pict_max_exp_lc();
1127
1128 if (copy_to_user((void *)argp,
1129 &cdata,
1130 sizeof(struct sensor_cfg_data)))
1131 rc = -EFAULT;
1132 break;
1133
1134 case CFG_SET_FPS:
1135 case CFG_SET_PICT_FPS:
1136 rc = mt9p012_set_fps(&(cdata.cfg.fps));
1137 break;
1138
1139 case CFG_SET_EXP_GAIN:
1140 rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
1141 cdata.cfg.exp_gain.line);
1142 break;
1143
1144 case CFG_SET_PICT_EXP_GAIN:
1145 CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
1146 rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
1147 cdata.cfg.exp_gain.line);
1148 break;
1149
1150 case CFG_SET_MODE:
1151 rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
1152 break;
1153
1154 case CFG_PWR_DOWN:
1155 rc = mt9p012_power_down();
1156 break;
1157
1158 case CFG_MOVE_FOCUS:
1159 CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d cdata.cfg.focus.steps=%d\n",
1160 cdata.cfg.focus.dir, cdata.cfg.focus.steps);
1161 rc = mt9p012_move_focus(cdata.cfg.focus.dir,
1162 cdata.cfg.focus.steps);
1163 break;
1164
1165 case CFG_SET_DEFAULT_FOCUS:
1166 rc = mt9p012_set_default_focus();
1167 break;
1168
1169 case CFG_SET_LENS_SHADING:
1170 CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
1171 rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
1172 break;
1173
1174 case CFG_GET_AF_MAX_STEPS:
1175 cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
1176 if (copy_to_user((void *)argp,
1177 &cdata,
1178 sizeof(struct sensor_cfg_data)))
1179 rc = -EFAULT;
1180 break;
1181
1182 case CFG_SET_EFFECT:
1183 default:
1184 rc = -EINVAL;
1185 break;
1186 }
1187
1188 up(&mt9p012_sem);
1189 return rc;
1190}
1191
1192int mt9p012_sensor_release(void)
1193{
1194 int rc = -EBADF;
1195
1196 down(&mt9p012_sem);
1197
1198 mt9p012_power_down();
1199
1200 gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset,
1201 0);
1202 gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
1203
1204 gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
1205 gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
1206
1207 kfree(mt9p012_ctrl);
1208 mt9p012_ctrl = NULL;
1209
1210 CDBG("mt9p012_release completed\n");
1211
1212 up(&mt9p012_sem);
1213 return rc;
1214}
1215
1216static int mt9p012_i2c_probe(struct i2c_client *client,
1217 const struct i2c_device_id *id)
1218{
1219 int rc = 0;
1220 CDBG("mt9p012_probe called!\n");
1221
1222 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1223 CDBG("i2c_check_functionality failed\n");
1224 goto probe_failure;
1225 }
1226
1227 mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
1228 if (!mt9p012_sensorw) {
1229 CDBG("kzalloc failed.\n");
1230 rc = -ENOMEM;
1231 goto probe_failure;
1232 }
1233
1234 i2c_set_clientdata(client, mt9p012_sensorw);
1235 mt9p012_init_client(client);
1236 mt9p012_client = client;
1237
1238 mdelay(50);
1239
1240 CDBG("mt9p012_probe successed! rc = %d\n", rc);
1241 return 0;
1242
1243probe_failure:
1244 CDBG("mt9p012_probe failed! rc = %d\n", rc);
1245 return rc;
1246}
1247
1248static const struct i2c_device_id mt9p012_i2c_id[] = {
1249 { "mt9p012", 0},
1250 { }
1251};
1252
1253static struct i2c_driver mt9p012_i2c_driver = {
1254 .id_table = mt9p012_i2c_id,
1255 .probe = mt9p012_i2c_probe,
1256 .remove = __exit_p(mt9p012_i2c_remove),
1257 .driver = {
1258 .name = "mt9p012",
1259 },
1260};
1261
1262static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
1263 struct msm_sensor_ctrl *s)
1264{
1265 int rc = i2c_add_driver(&mt9p012_i2c_driver);
1266 if (rc < 0 || mt9p012_client == NULL) {
1267 rc = -ENOTSUPP;
1268 goto probe_done;
1269 }
1270
1271 msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
1272 mdelay(20);
1273
1274 rc = mt9p012_probe_init_sensor(info);
1275 if (rc < 0)
1276 goto probe_done;
1277
1278 s->s_init = mt9p012_sensor_open_init;
1279 s->s_release = mt9p012_sensor_release;
1280 s->s_config = mt9p012_sensor_config;
1281 mt9p012_probe_init_done(info);
1282
1283probe_done:
1284 CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
1285 return rc;
1286}
1287
1288static int __mt9p012_probe(struct platform_device *pdev)
1289{
1290 return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
1291}
1292
1293static struct platform_driver msm_camera_driver = {
1294 .probe = __mt9p012_probe,
1295 .driver = {
1296 .name = "msm_camera_mt9p012",
1297 .owner = THIS_MODULE,
1298 },
1299};
1300
1301static int __init mt9p012_init(void)
1302{
1303 return platform_driver_register(&msm_camera_driver);
1304}
1305
1306module_init(mt9p012_init);
diff --git a/drivers/staging/dream/camera/mt9p012_reg.c b/drivers/staging/dream/camera/mt9p012_reg.c
deleted file mode 100644
index e5223d693b2c..000000000000
--- a/drivers/staging/dream/camera/mt9p012_reg.c
+++ /dev/null
@@ -1,573 +0,0 @@
1/*
2 * Copyright (C) 2009 QUALCOMM Incorporated.
3 */
4
5#include "mt9p012.h"
6#include <linux/kernel.h>
7
8/*Micron settings from Applications for lower power consumption.*/
9struct reg_struct mt9p012_reg_pat[2] = {
10 { /* Preview */
11 /* vt_pix_clk_div REG=0x0300 */
12 6, /* 5 */
13
14 /* vt_sys_clk_div REG=0x0302 */
15 1,
16
17 /* pre_pll_clk_div REG=0x0304 */
18 2,
19
20 /* pll_multiplier REG=0x0306 */
21 60,
22
23 /* op_pix_clk_div REG=0x0308 */
24 8, /* 10 */
25
26 /* op_sys_clk_div REG=0x030A */
27 1,
28
29 /* scale_m REG=0x0404 */
30 16,
31
32 /* row_speed REG=0x3016 */
33 0x0111,
34
35 /* x_addr_start REG=0x3004 */
36 8,
37
38 /* x_addr_end REG=0x3008 */
39 2597,
40
41 /* y_addr_start REG=0x3002 */
42 8,
43
44 /* y_addr_end REG=0x3006 */
45 1949,
46
47 /* read_mode REG=0x3040
48 * Preview 2x2 skipping */
49 0x00C3,
50
51 /* x_output_size REG=0x034C */
52 1296,
53
54 /* y_output_size REG=0x034E */
55 972,
56
57 /* line_length_pck REG=0x300C */
58 3784,
59
60 /* frame_length_lines REG=0x300A */
61 1057,
62
63 /* coarse_integration_time REG=0x3012 */
64 16,
65
66 /* fine_integration_time REG=0x3014 */
67 1764
68 },
69 { /*Snapshot*/
70 /* vt_pix_clk_div REG=0x0300 */
71 6,
72
73 /* vt_sys_clk_div REG=0x0302 */
74 1,
75
76 /* pre_pll_clk_div REG=0x0304 */
77 2,
78
79 /* pll_multiplier REG=0x0306
80 * 60 for 10fps snapshot */
81 60,
82
83 /* op_pix_clk_div REG=0x0308 */
84 8,
85
86 /* op_sys_clk_div REG=0x030A */
87 1,
88
89 /* scale_m REG=0x0404 */
90 16,
91
92 /* row_speed REG=0x3016 */
93 0x0111,
94
95 /* x_addr_start REG=0x3004 */
96 8,
97
98 /* x_addr_end REG=0x3008 */
99 2615,
100
101 /* y_addr_start REG=0x3002 */
102 8,
103
104 /* y_addr_end REG=0x3006 */
105 1967,
106
107 /* read_mode REG=0x3040 */
108 0x0041,
109
110 /* x_output_size REG=0x034C */
111 2608,
112
113 /* y_output_size REG=0x034E */
114 1960,
115
116 /* line_length_pck REG=0x300C */
117 3911,
118
119 /* frame_length_lines REG=0x300A //10 fps snapshot */
120 2045,
121
122 /* coarse_integration_time REG=0x3012 */
123 16,
124
125 /* fine_integration_time REG=0x3014 */
126 882
127 }
128};
129
130
131struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = {
132 {0x3044, 0x0544 & 0xFBFF},
133 {0x30CA, 0x0004 | 0x0001},
134 {0x30D4, 0x9020 & 0x7FFF},
135 {0x31E0, 0x0003 & 0xFFFE},
136 {0x3180, 0x91FF & 0x7FFF},
137 {0x301A, (0x10CC | 0x8000) & 0xFFF7},
138 {0x301E, 0x0000},
139 {0x3780, 0x0000},
140};
141
142
143struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = {
144 /* [Lens shading 85 Percent TL84] */
145 /* P_RD_P0Q0 */
146 {0x360A, 0x7FEF},
147 /* P_RD_P0Q1 */
148 {0x360C, 0x232C},
149 /* P_RD_P0Q2 */
150 {0x360E, 0x7050},
151 /* P_RD_P0Q3 */
152 {0x3610, 0xF3CC},
153 /* P_RD_P0Q4 */
154 {0x3612, 0x89D1},
155 /* P_RD_P1Q0 */
156 {0x364A, 0xBE0D},
157 /* P_RD_P1Q1 */
158 {0x364C, 0x9ACB},
159 /* P_RD_P1Q2 */
160 {0x364E, 0x2150},
161 /* P_RD_P1Q3 */
162 {0x3650, 0xB26B},
163 /* P_RD_P1Q4 */
164 {0x3652, 0x9511},
165 /* P_RD_P2Q0 */
166 {0x368A, 0x2151},
167 /* P_RD_P2Q1 */
168 {0x368C, 0x00AD},
169 /* P_RD_P2Q2 */
170 {0x368E, 0x8334},
171 /* P_RD_P2Q3 */
172 {0x3690, 0x478E},
173 /* P_RD_P2Q4 */
174 {0x3692, 0x0515},
175 /* P_RD_P3Q0 */
176 {0x36CA, 0x0710},
177 /* P_RD_P3Q1 */
178 {0x36CC, 0x452D},
179 /* P_RD_P3Q2 */
180 {0x36CE, 0xF352},
181 /* P_RD_P3Q3 */
182 {0x36D0, 0x190F},
183 /* P_RD_P3Q4 */
184 {0x36D2, 0x4413},
185 /* P_RD_P4Q0 */
186 {0x370A, 0xD112},
187 /* P_RD_P4Q1 */
188 {0x370C, 0xF50F},
189 /* P_RD_P4Q2 */
190 {0x370C, 0xF50F},
191 /* P_RD_P4Q3 */
192 {0x3710, 0xDC11},
193 /* P_RD_P4Q4 */
194 {0x3712, 0xD776},
195 /* P_GR_P0Q0 */
196 {0x3600, 0x1750},
197 /* P_GR_P0Q1 */
198 {0x3602, 0xF0AC},
199 /* P_GR_P0Q2 */
200 {0x3604, 0x4711},
201 /* P_GR_P0Q3 */
202 {0x3606, 0x07CE},
203 /* P_GR_P0Q4 */
204 {0x3608, 0x96B2},
205 /* P_GR_P1Q0 */
206 {0x3640, 0xA9AE},
207 /* P_GR_P1Q1 */
208 {0x3642, 0xF9AC},
209 /* P_GR_P1Q2 */
210 {0x3644, 0x39F1},
211 /* P_GR_P1Q3 */
212 {0x3646, 0x016F},
213 /* P_GR_P1Q4 */
214 {0x3648, 0x8AB2},
215 /* P_GR_P2Q0 */
216 {0x3680, 0x1752},
217 /* P_GR_P2Q1 */
218 {0x3682, 0x70F0},
219 /* P_GR_P2Q2 */
220 {0x3684, 0x83F5},
221 /* P_GR_P2Q3 */
222 {0x3686, 0x8392},
223 /* P_GR_P2Q4 */
224 {0x3688, 0x1FD6},
225 /* P_GR_P3Q0 */
226 {0x36C0, 0x1131},
227 /* P_GR_P3Q1 */
228 {0x36C2, 0x3DAF},
229 /* P_GR_P3Q2 */
230 {0x36C4, 0x89B4},
231 /* P_GR_P3Q3 */
232 {0x36C6, 0xA391},
233 /* P_GR_P3Q4 */
234 {0x36C8, 0x1334},
235 /* P_GR_P4Q0 */
236 {0x3700, 0xDC13},
237 /* P_GR_P4Q1 */
238 {0x3702, 0xD052},
239 /* P_GR_P4Q2 */
240 {0x3704, 0x5156},
241 /* P_GR_P4Q3 */
242 {0x3706, 0x1F13},
243 /* P_GR_P4Q4 */
244 {0x3708, 0x8C38},
245 /* P_BL_P0Q0 */
246 {0x3614, 0x0050},
247 /* P_BL_P0Q1 */
248 {0x3616, 0xBD4C},
249 /* P_BL_P0Q2 */
250 {0x3618, 0x41B0},
251 /* P_BL_P0Q3 */
252 {0x361A, 0x660D},
253 /* P_BL_P0Q4 */
254 {0x361C, 0xC590},
255 /* P_BL_P1Q0 */
256 {0x3654, 0x87EC},
257 /* P_BL_P1Q1 */
258 {0x3656, 0xE44C},
259 /* P_BL_P1Q2 */
260 {0x3658, 0x302E},
261 /* P_BL_P1Q3 */
262 {0x365A, 0x106E},
263 /* P_BL_P1Q4 */
264 {0x365C, 0xB58E},
265 /* P_BL_P2Q0 */
266 {0x3694, 0x0DD1},
267 /* P_BL_P2Q1 */
268 {0x3696, 0x2A50},
269 /* P_BL_P2Q2 */
270 {0x3698, 0xC793},
271 /* P_BL_P2Q3 */
272 {0x369A, 0xE8F1},
273 /* P_BL_P2Q4 */
274 {0x369C, 0x4174},
275 /* P_BL_P3Q0 */
276 {0x36D4, 0x01EF},
277 /* P_BL_P3Q1 */
278 {0x36D6, 0x06CF},
279 /* P_BL_P3Q2 */
280 {0x36D8, 0x8D91},
281 /* P_BL_P3Q3 */
282 {0x36DA, 0x91F0},
283 /* P_BL_P3Q4 */
284 {0x36DC, 0x52EF},
285 /* P_BL_P4Q0 */
286 {0x3714, 0xA6D2},
287 /* P_BL_P4Q1 */
288 {0x3716, 0xA312},
289 /* P_BL_P4Q2 */
290 {0x3718, 0x2695},
291 /* P_BL_P4Q3 */
292 {0x371A, 0x3953},
293 /* P_BL_P4Q4 */
294 {0x371C, 0x9356},
295 /* P_GB_P0Q0 */
296 {0x361E, 0x7EAF},
297 /* P_GB_P0Q1 */
298 {0x3620, 0x2A4C},
299 /* P_GB_P0Q2 */
300 {0x3622, 0x49F0},
301 {0x3624, 0xF1EC},
302 /* P_GB_P0Q4 */
303 {0x3626, 0xC670},
304 /* P_GB_P1Q0 */
305 {0x365E, 0x8E0C},
306 /* P_GB_P1Q1 */
307 {0x3660, 0xC2A9},
308 /* P_GB_P1Q2 */
309 {0x3662, 0x274F},
310 /* P_GB_P1Q3 */
311 {0x3664, 0xADAB},
312 /* P_GB_P1Q4 */
313 {0x3666, 0x8EF0},
314 /* P_GB_P2Q0 */
315 {0x369E, 0x09B1},
316 /* P_GB_P2Q1 */
317 {0x36A0, 0xAA2E},
318 /* P_GB_P2Q2 */
319 {0x36A2, 0xC3D3},
320 /* P_GB_P2Q3 */
321 {0x36A4, 0x7FAF},
322 /* P_GB_P2Q4 */
323 {0x36A6, 0x3F34},
324 /* P_GB_P3Q0 */
325 {0x36DE, 0x4C8F},
326 /* P_GB_P3Q1 */
327 {0x36E0, 0x886E},
328 /* P_GB_P3Q2 */
329 {0x36E2, 0xE831},
330 /* P_GB_P3Q3 */
331 {0x36E4, 0x1FD0},
332 /* P_GB_P3Q4 */
333 {0x36E6, 0x1192},
334 /* P_GB_P4Q0 */
335 {0x371E, 0xB952},
336 /* P_GB_P4Q1 */
337 {0x3720, 0x6DCF},
338 /* P_GB_P4Q2 */
339 {0x3722, 0x1B55},
340 /* P_GB_P4Q3 */
341 {0x3724, 0xA112},
342 /* P_GB_P4Q4 */
343 {0x3726, 0x82F6},
344 /* POLY_ORIGIN_C */
345 {0x3782, 0x0510},
346 /* POLY_ORIGIN_R */
347 {0x3784, 0x0390},
348 /* POLY_SC_ENABLE */
349 {0x3780, 0x8000},
350};
351
352/* rolloff table for illuminant A */
353struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = {
354 /* P_RD_P0Q0 */
355 {0x360A, 0x7FEF},
356 /* P_RD_P0Q1 */
357 {0x360C, 0x232C},
358 /* P_RD_P0Q2 */
359 {0x360E, 0x7050},
360 /* P_RD_P0Q3 */
361 {0x3610, 0xF3CC},
362 /* P_RD_P0Q4 */
363 {0x3612, 0x89D1},
364 /* P_RD_P1Q0 */
365 {0x364A, 0xBE0D},
366 /* P_RD_P1Q1 */
367 {0x364C, 0x9ACB},
368 /* P_RD_P1Q2 */
369 {0x364E, 0x2150},
370 /* P_RD_P1Q3 */
371 {0x3650, 0xB26B},
372 /* P_RD_P1Q4 */
373 {0x3652, 0x9511},
374 /* P_RD_P2Q0 */
375 {0x368A, 0x2151},
376 /* P_RD_P2Q1 */
377 {0x368C, 0x00AD},
378 /* P_RD_P2Q2 */
379 {0x368E, 0x8334},
380 /* P_RD_P2Q3 */
381 {0x3690, 0x478E},
382 /* P_RD_P2Q4 */
383 {0x3692, 0x0515},
384 /* P_RD_P3Q0 */
385 {0x36CA, 0x0710},
386 /* P_RD_P3Q1 */
387 {0x36CC, 0x452D},
388 /* P_RD_P3Q2 */
389 {0x36CE, 0xF352},
390 /* P_RD_P3Q3 */
391 {0x36D0, 0x190F},
392 /* P_RD_P3Q4 */
393 {0x36D2, 0x4413},
394 /* P_RD_P4Q0 */
395 {0x370A, 0xD112},
396 /* P_RD_P4Q1 */
397 {0x370C, 0xF50F},
398 /* P_RD_P4Q2 */
399 {0x370E, 0x6375},
400 /* P_RD_P4Q3 */
401 {0x3710, 0xDC11},
402 /* P_RD_P4Q4 */
403 {0x3712, 0xD776},
404 /* P_GR_P0Q0 */
405 {0x3600, 0x1750},
406 /* P_GR_P0Q1 */
407 {0x3602, 0xF0AC},
408 /* P_GR_P0Q2 */
409 {0x3604, 0x4711},
410 /* P_GR_P0Q3 */
411 {0x3606, 0x07CE},
412 /* P_GR_P0Q4 */
413 {0x3608, 0x96B2},
414 /* P_GR_P1Q0 */
415 {0x3640, 0xA9AE},
416 /* P_GR_P1Q1 */
417 {0x3642, 0xF9AC},
418 /* P_GR_P1Q2 */
419 {0x3644, 0x39F1},
420 /* P_GR_P1Q3 */
421 {0x3646, 0x016F},
422 /* P_GR_P1Q4 */
423 {0x3648, 0x8AB2},
424 /* P_GR_P2Q0 */
425 {0x3680, 0x1752},
426 /* P_GR_P2Q1 */
427 {0x3682, 0x70F0},
428 /* P_GR_P2Q2 */
429 {0x3684, 0x83F5},
430 /* P_GR_P2Q3 */
431 {0x3686, 0x8392},
432 /* P_GR_P2Q4 */
433 {0x3688, 0x1FD6},
434 /* P_GR_P3Q0 */
435 {0x36C0, 0x1131},
436 /* P_GR_P3Q1 */
437 {0x36C2, 0x3DAF},
438 /* P_GR_P3Q2 */
439 {0x36C4, 0x89B4},
440 /* P_GR_P3Q3 */
441 {0x36C6, 0xA391},
442 /* P_GR_P3Q4 */
443 {0x36C8, 0x1334},
444 /* P_GR_P4Q0 */
445 {0x3700, 0xDC13},
446 /* P_GR_P4Q1 */
447 {0x3702, 0xD052},
448 /* P_GR_P4Q2 */
449 {0x3704, 0x5156},
450 /* P_GR_P4Q3 */
451 {0x3706, 0x1F13},
452 /* P_GR_P4Q4 */
453 {0x3708, 0x8C38},
454 /* P_BL_P0Q0 */
455 {0x3614, 0x0050},
456 /* P_BL_P0Q1 */
457 {0x3616, 0xBD4C},
458 /* P_BL_P0Q2 */
459 {0x3618, 0x41B0},
460 /* P_BL_P0Q3 */
461 {0x361A, 0x660D},
462 /* P_BL_P0Q4 */
463 {0x361C, 0xC590},
464 /* P_BL_P1Q0 */
465 {0x3654, 0x87EC},
466 /* P_BL_P1Q1 */
467 {0x3656, 0xE44C},
468 /* P_BL_P1Q2 */
469 {0x3658, 0x302E},
470 /* P_BL_P1Q3 */
471 {0x365A, 0x106E},
472 /* P_BL_P1Q4 */
473 {0x365C, 0xB58E},
474 /* P_BL_P2Q0 */
475 {0x3694, 0x0DD1},
476 /* P_BL_P2Q1 */
477 {0x3696, 0x2A50},
478 /* P_BL_P2Q2 */
479 {0x3698, 0xC793},
480 /* P_BL_P2Q3 */
481 {0x369A, 0xE8F1},
482 /* P_BL_P2Q4 */
483 {0x369C, 0x4174},
484 /* P_BL_P3Q0 */
485 {0x36D4, 0x01EF},
486 /* P_BL_P3Q1 */
487 {0x36D6, 0x06CF},
488 /* P_BL_P3Q2 */
489 {0x36D8, 0x8D91},
490 /* P_BL_P3Q3 */
491 {0x36DA, 0x91F0},
492 /* P_BL_P3Q4 */
493 {0x36DC, 0x52EF},
494 /* P_BL_P4Q0 */
495 {0x3714, 0xA6D2},
496 /* P_BL_P4Q1 */
497 {0x3716, 0xA312},
498 /* P_BL_P4Q2 */
499 {0x3718, 0x2695},
500 /* P_BL_P4Q3 */
501 {0x371A, 0x3953},
502 /* P_BL_P4Q4 */
503 {0x371C, 0x9356},
504 /* P_GB_P0Q0 */
505 {0x361E, 0x7EAF},
506 /* P_GB_P0Q1 */
507 {0x3620, 0x2A4C},
508 /* P_GB_P0Q2 */
509 {0x3622, 0x49F0},
510 {0x3624, 0xF1EC},
511 /* P_GB_P0Q4 */
512 {0x3626, 0xC670},
513 /* P_GB_P1Q0 */
514 {0x365E, 0x8E0C},
515 /* P_GB_P1Q1 */
516 {0x3660, 0xC2A9},
517 /* P_GB_P1Q2 */
518 {0x3662, 0x274F},
519 /* P_GB_P1Q3 */
520 {0x3664, 0xADAB},
521 /* P_GB_P1Q4 */
522 {0x3666, 0x8EF0},
523 /* P_GB_P2Q0 */
524 {0x369E, 0x09B1},
525 /* P_GB_P2Q1 */
526 {0x36A0, 0xAA2E},
527 /* P_GB_P2Q2 */
528 {0x36A2, 0xC3D3},
529 /* P_GB_P2Q3 */
530 {0x36A4, 0x7FAF},
531 /* P_GB_P2Q4 */
532 {0x36A6, 0x3F34},
533 /* P_GB_P3Q0 */
534 {0x36DE, 0x4C8F},
535 /* P_GB_P3Q1 */
536 {0x36E0, 0x886E},
537 /* P_GB_P3Q2 */
538 {0x36E2, 0xE831},
539 /* P_GB_P3Q3 */
540 {0x36E4, 0x1FD0},
541 /* P_GB_P3Q4 */
542 {0x36E6, 0x1192},
543 /* P_GB_P4Q0 */
544 {0x371E, 0xB952},
545 /* P_GB_P4Q1 */
546 {0x3720, 0x6DCF},
547 /* P_GB_P4Q2 */
548 {0x3722, 0x1B55},
549 /* P_GB_P4Q3 */
550 {0x3724, 0xA112},
551 /* P_GB_P4Q4 */
552 {0x3726, 0x82F6},
553 /* POLY_ORIGIN_C */
554 {0x3782, 0x0510},
555 /* POLY_ORIGIN_R */
556 {0x3784, 0x0390},
557 /* POLY_SC_ENABLE */
558 {0x3780, 0x8000},
559};
560
561
562struct mt9p012_reg mt9p012_regs = {
563 .reg_pat = &mt9p012_reg_pat[0],
564 .reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
565 .ttbl = &mt9p012_test_tbl[0],
566 .ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
567 .lctbl = &mt9p012_lc_tbl[0],
568 .lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl),
569 .rftbl = &mt9p012_rolloff_tbl[0],
570 .rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
571};
572
573
diff --git a/drivers/staging/dream/camera/mt9t013.c b/drivers/staging/dream/camera/mt9t013.c
deleted file mode 100644
index 8fd7727ba234..000000000000
--- a/drivers/staging/dream/camera/mt9t013.c
+++ /dev/null
@@ -1,1497 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/delay.h>
6#include <linux/types.h>
7#include <linux/slab.h>
8#include <linux/i2c.h>
9#include <linux/uaccess.h>
10#include <linux/miscdevice.h>
11#include <linux/kernel.h>
12#include <media/msm_camera.h>
13#include <mach/gpio.h>
14#include <mach/camera.h>
15#include <asm/mach-types.h>
16#include "mt9t013.h"
17
18/*=============================================================
19 SENSOR REGISTER DEFINES
20==============================================================*/
21#define MT9T013_REG_MODEL_ID 0x0000
22#define MT9T013_MODEL_ID 0x2600
23#define REG_GROUPED_PARAMETER_HOLD 0x0104
24#define GROUPED_PARAMETER_HOLD 0x0100
25#define GROUPED_PARAMETER_UPDATE 0x0000
26#define REG_COARSE_INT_TIME 0x3012
27#define REG_VT_PIX_CLK_DIV 0x0300
28#define REG_VT_SYS_CLK_DIV 0x0302
29#define REG_PRE_PLL_CLK_DIV 0x0304
30#define REG_PLL_MULTIPLIER 0x0306
31#define REG_OP_PIX_CLK_DIV 0x0308
32#define REG_OP_SYS_CLK_DIV 0x030A
33#define REG_SCALE_M 0x0404
34#define REG_FRAME_LENGTH_LINES 0x300A
35#define REG_LINE_LENGTH_PCK 0x300C
36#define REG_X_ADDR_START 0x3004
37#define REG_Y_ADDR_START 0x3002
38#define REG_X_ADDR_END 0x3008
39#define REG_Y_ADDR_END 0x3006
40#define REG_X_OUTPUT_SIZE 0x034C
41#define REG_Y_OUTPUT_SIZE 0x034E
42#define REG_FINE_INT_TIME 0x3014
43#define REG_ROW_SPEED 0x3016
44#define MT9T013_REG_RESET_REGISTER 0x301A
45#define MT9T013_RESET_REGISTER_PWON 0x10CC
46#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
47#define REG_READ_MODE 0x3040
48#define REG_GLOBAL_GAIN 0x305E
49#define REG_TEST_PATTERN_MODE 0x3070
50
51
52enum mt9t013_test_mode {
53 TEST_OFF,
54 TEST_1,
55 TEST_2,
56 TEST_3
57};
58
59enum mt9t013_resolution {
60 QTR_SIZE,
61 FULL_SIZE,
62 INVALID_SIZE
63};
64
65enum mt9t013_reg_update {
66 REG_INIT, /* registers that need to be updated during initialization */
67 UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
68 UPDATE_ALL, /* all registers will be updated */
69 UPDATE_INVALID
70};
71
72enum mt9t013_setting {
73 RES_PREVIEW,
74 RES_CAPTURE
75};
76
77/* actuator's Slave Address */
78#define MT9T013_AF_I2C_ADDR 0x18
79
80/*
81* AF Total steps parameters
82*/
83#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR 30
84
85/*
86 * Time in milisecs for waiting for the sensor to reset.
87 */
88#define MT9T013_RESET_DELAY_MSECS 66
89
90/* for 30 fps preview */
91#define MT9T013_DEFAULT_CLOCK_RATE 24000000
92#define MT9T013_DEFAULT_MAX_FPS 26
93
94
95/* FIXME: Changes from here */
96struct mt9t013_work {
97 struct work_struct work;
98};
99
100static struct mt9t013_work *mt9t013_sensorw;
101static struct i2c_client *mt9t013_client;
102
103struct mt9t013_ctrl {
104 const struct msm_camera_sensor_info *sensordata;
105
106 int sensormode;
107 uint32_t fps_divider; /* init to 1 * 0x00000400 */
108 uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
109
110 uint16_t curr_lens_pos;
111 uint16_t init_curr_lens_pos;
112 uint16_t my_reg_gain;
113 uint32_t my_reg_line_count;
114
115 enum mt9t013_resolution prev_res;
116 enum mt9t013_resolution pict_res;
117 enum mt9t013_resolution curr_res;
118 enum mt9t013_test_mode set_test;
119
120 unsigned short imgaddr;
121};
122
123
124static struct mt9t013_ctrl *mt9t013_ctrl;
125static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
126DECLARE_MUTEX(mt9t013_sem);
127
128extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
129
130static int mt9t013_i2c_rxdata(unsigned short saddr,
131 unsigned char *rxdata, int length)
132{
133 struct i2c_msg msgs[] = {
134 {
135 .addr = saddr,
136 .flags = 0,
137 .len = 2,
138 .buf = rxdata,
139 },
140 {
141 .addr = saddr,
142 .flags = I2C_M_RD,
143 .len = length,
144 .buf = rxdata,
145 },
146 };
147
148 if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
149 pr_err("mt9t013_i2c_rxdata failed!\n");
150 return -EIO;
151 }
152
153 return 0;
154}
155
156static int32_t mt9t013_i2c_read_w(unsigned short saddr,
157 unsigned short raddr, unsigned short *rdata)
158{
159 int32_t rc = 0;
160 unsigned char buf[4];
161
162 if (!rdata)
163 return -EIO;
164
165 memset(buf, 0, sizeof(buf));
166
167 buf[0] = (raddr & 0xFF00)>>8;
168 buf[1] = (raddr & 0x00FF);
169
170 rc = mt9t013_i2c_rxdata(saddr, buf, 2);
171 if (rc < 0)
172 return rc;
173
174 *rdata = buf[0] << 8 | buf[1];
175
176 if (rc < 0)
177 pr_err("mt9t013_i2c_read failed!\n");
178
179 return rc;
180}
181
182static int32_t mt9t013_i2c_txdata(unsigned short saddr,
183 unsigned char *txdata, int length)
184{
185 struct i2c_msg msg[] = {
186 {
187 .addr = saddr,
188 .flags = 0,
189 .len = length,
190 .buf = txdata,
191 },
192 };
193
194 if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
195 pr_err("mt9t013_i2c_txdata failed\n");
196 return -EIO;
197 }
198
199 return 0;
200}
201
202static int32_t mt9t013_i2c_write_b(unsigned short saddr,
203 unsigned short waddr, unsigned short wdata)
204{
205 int32_t rc = -EIO;
206 unsigned char buf[2];
207
208 memset(buf, 0, sizeof(buf));
209 buf[0] = waddr;
210 buf[1] = wdata;
211 rc = mt9t013_i2c_txdata(saddr, buf, 2);
212
213 if (rc < 0)
214 pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
215 waddr, wdata);
216
217 return rc;
218}
219
220static int32_t mt9t013_i2c_write_w(unsigned short saddr,
221 unsigned short waddr, unsigned short wdata)
222{
223 int32_t rc = -EIO;
224 unsigned char buf[4];
225
226 memset(buf, 0, sizeof(buf));
227 buf[0] = (waddr & 0xFF00)>>8;
228 buf[1] = (waddr & 0x00FF);
229 buf[2] = (wdata & 0xFF00)>>8;
230 buf[3] = (wdata & 0x00FF);
231
232 rc = mt9t013_i2c_txdata(saddr, buf, 4);
233
234 if (rc < 0)
235 pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
236 waddr, wdata);
237
238 return rc;
239}
240
241static int32_t mt9t013_i2c_write_w_table(
242 struct mt9t013_i2c_reg_conf *reg_conf_tbl, int num_of_items_in_table)
243{
244 int i;
245 int32_t rc = -EIO;
246
247 for (i = 0; i < num_of_items_in_table; i++) {
248 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
249 reg_conf_tbl->waddr, reg_conf_tbl->wdata);
250 if (rc < 0)
251 break;
252 reg_conf_tbl++;
253 }
254
255 return rc;
256}
257
258static int32_t mt9t013_test(enum mt9t013_test_mode mo)
259{
260 int32_t rc = 0;
261
262 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
263 REG_GROUPED_PARAMETER_HOLD,
264 GROUPED_PARAMETER_HOLD);
265 if (rc < 0)
266 return rc;
267
268 if (mo == TEST_OFF)
269 return 0;
270 else {
271 rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
272 mt9t013_regs.ttbl_size);
273 if (rc < 0)
274 return rc;
275 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
276 REG_TEST_PATTERN_MODE, (uint16_t)mo);
277 if (rc < 0)
278 return rc;
279 }
280
281 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
282 REG_GROUPED_PARAMETER_HOLD,
283 GROUPED_PARAMETER_UPDATE);
284 if (rc < 0)
285 return rc;
286
287 return rc;
288}
289
290static int32_t mt9t013_set_lc(void)
291{
292 int32_t rc;
293
294 rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl, mt9t013_regs.lctbl_size);
295 if (rc < 0)
296 return rc;
297
298 return rc;
299}
300
301static int32_t mt9t013_set_default_focus(uint8_t af_step)
302{
303 int32_t rc = 0;
304 uint8_t code_val_msb, code_val_lsb;
305 code_val_msb = 0x01;
306 code_val_lsb = af_step;
307
308 /* Write the digital code for current to the actuator */
309 rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
310 code_val_msb, code_val_lsb);
311
312 mt9t013_ctrl->curr_lens_pos = 0;
313 mt9t013_ctrl->init_curr_lens_pos = 0;
314 return rc;
315}
316
317static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
318{
319 /* input fps is preview fps in Q8 format */
320 uint32_t divider; /*Q10 */
321 uint32_t pclk_mult; /*Q10 */
322
323 if (mt9t013_ctrl->prev_res == QTR_SIZE) {
324 divider =
325 (uint32_t)(
326 ((mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
327 mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck) *
328 0x00000400) /
329 (mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines *
330 mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck));
331
332 pclk_mult =
333 (uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
334 0x00000400) /
335 (mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
336
337 } else {
338 /* full size resolution used for preview. */
339 divider = 0x00000400; /*1.0 */
340 pclk_mult = 0x00000400; /*1.0 */
341 }
342
343 /* Verify PCLK settings and frame sizes. */
344 *pfps =
345 (uint16_t) (fps * divider * pclk_mult /
346 0x00000400 / 0x00000400);
347}
348
349static uint16_t mt9t013_get_prev_lines_pf(void)
350{
351 if (mt9t013_ctrl->prev_res == QTR_SIZE)
352 return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
353 else
354 return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
355}
356
357static uint16_t mt9t013_get_prev_pixels_pl(void)
358{
359 if (mt9t013_ctrl->prev_res == QTR_SIZE)
360 return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
361 else
362 return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
363}
364
365static uint16_t mt9t013_get_pict_lines_pf(void)
366{
367 return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
368}
369
370static uint16_t mt9t013_get_pict_pixels_pl(void)
371{
372 return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
373}
374
375static uint32_t mt9t013_get_pict_max_exp_lc(void)
376{
377 uint16_t snapshot_lines_per_frame;
378
379 if (mt9t013_ctrl->pict_res == QTR_SIZE) {
380 snapshot_lines_per_frame =
381 mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
382 } else {
383 snapshot_lines_per_frame =
384 mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
385 }
386
387 return snapshot_lines_per_frame * 24;
388}
389
390static int32_t mt9t013_set_fps(struct fps_cfg *fps)
391{
392 /* input is new fps in Q8 format */
393 int32_t rc = 0;
394
395 mt9t013_ctrl->fps_divider = fps->fps_div;
396 mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
397
398 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
399 REG_GROUPED_PARAMETER_HOLD,
400 GROUPED_PARAMETER_HOLD);
401 if (rc < 0)
402 return -EBUSY;
403
404 CDBG("mt9t013_set_fps: fps_div is %d, frame_rate is %d\n",
405 fps->fps_div,
406 (uint16_t) (mt9t013_regs.reg_pat[RES_PREVIEW].
407 frame_length_lines *
408 fps->fps_div/0x00000400));
409
410 CDBG("mt9t013_set_fps: fps_mult is %d, frame_rate is %d\n",
411 fps->f_mult,
412 (uint16_t)(mt9t013_regs.reg_pat[RES_PREVIEW].
413 line_length_pck *
414 fps->f_mult / 0x00000400));
415
416 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
417 REG_LINE_LENGTH_PCK,
418 (uint16_t) (
419 mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
420 fps->f_mult / 0x00000400));
421 if (rc < 0)
422 return rc;
423
424 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
425 REG_GROUPED_PARAMETER_HOLD,
426 GROUPED_PARAMETER_UPDATE);
427 if (rc < 0)
428 return rc;
429
430 return rc;
431}
432
433static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
434{
435 const uint16_t max_legal_gain = 0x01FF;
436 uint32_t line_length_ratio = 0x00000400;
437 enum mt9t013_setting setting;
438 int32_t rc = 0;
439
440 if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
441 mt9t013_ctrl->my_reg_gain = gain;
442 mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
443 }
444
445 if (gain > max_legal_gain)
446 gain = max_legal_gain;
447
448 /* Verify no overflow */
449 if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
450 line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
451 0x00000400);
452
453 setting = RES_PREVIEW;
454
455 } else {
456 line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
457 0x00000400);
458
459 setting = RES_CAPTURE;
460 }
461
462 /*Set digital gain to 1 */
463 gain |= 0x0200;
464
465 if ((mt9t013_regs.reg_pat[setting].frame_length_lines - 1) < line) {
466
467 line_length_ratio =
468 (uint32_t) (line * 0x00000400) /
469 (mt9t013_regs.reg_pat[setting].frame_length_lines - 1);
470 } else
471 line_length_ratio = 0x00000400;
472
473 /* There used to be PARAMETER_HOLD register write before and
474 * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
475 * aec oscillation. Hence removed. */
476
477 rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
478 if (rc < 0)
479 return rc;
480
481 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
482 REG_COARSE_INT_TIME,
483 (uint16_t)((uint32_t) line * 0x00000400 /
484 line_length_ratio));
485 if (rc < 0)
486 return rc;
487
488 return rc;
489}
490
491static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
492{
493 int32_t rc = 0;
494
495 rc = mt9t013_write_exp_gain(gain, line);
496 if (rc < 0)
497 return rc;
498
499 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
500 MT9T013_REG_RESET_REGISTER,
501 0x10CC | 0x0002);
502
503 mdelay(5);
504
505 /* camera_timed_wait(snapshot_wait*exposure_ratio); */
506 return rc;
507}
508
509static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
510 enum mt9t013_setting rt)
511{
512 int32_t rc = 0;
513
514 switch (rupdate) {
515 case UPDATE_PERIODIC: {
516
517 if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
518#if 0
519 rc =
520 mt9t013_i2c_write_w(mt9t013_client->addr,
521 MT9T013_REG_RESET_REGISTER,
522 MT9T013_RESET_REGISTER_PWOFF);
523 if (rc < 0)
524 return rc;
525#endif
526
527 rc =
528 mt9t013_i2c_write_w(mt9t013_client->addr,
529 REG_VT_PIX_CLK_DIV,
530 mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
531 if (rc < 0)
532 return rc;
533
534 rc =
535 mt9t013_i2c_write_w(mt9t013_client->addr,
536 REG_VT_SYS_CLK_DIV,
537 mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
538 if (rc < 0)
539 return rc;
540
541 rc =
542 mt9t013_i2c_write_w(mt9t013_client->addr,
543 REG_PRE_PLL_CLK_DIV,
544 mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
545 if (rc < 0)
546 return rc;
547
548 rc =
549 mt9t013_i2c_write_w(mt9t013_client->addr,
550 REG_PLL_MULTIPLIER,
551 mt9t013_regs.reg_pat[rt].pll_multiplier);
552 if (rc < 0)
553 return rc;
554
555 rc =
556 mt9t013_i2c_write_w(mt9t013_client->addr,
557 REG_OP_PIX_CLK_DIV,
558 mt9t013_regs.reg_pat[rt].op_pix_clk_div);
559 if (rc < 0)
560 return rc;
561
562 rc =
563 mt9t013_i2c_write_w(mt9t013_client->addr,
564 REG_OP_SYS_CLK_DIV,
565 mt9t013_regs.reg_pat[rt].op_sys_clk_div);
566 if (rc < 0)
567 return rc;
568
569 mdelay(5);
570
571 rc =
572 mt9t013_i2c_write_w(mt9t013_client->addr,
573 REG_GROUPED_PARAMETER_HOLD,
574 GROUPED_PARAMETER_HOLD);
575 if (rc < 0)
576 return rc;
577
578 rc =
579 mt9t013_i2c_write_w(mt9t013_client->addr,
580 REG_ROW_SPEED,
581 mt9t013_regs.reg_pat[rt].row_speed);
582 if (rc < 0)
583 return rc;
584
585 rc =
586 mt9t013_i2c_write_w(mt9t013_client->addr,
587 REG_X_ADDR_START,
588 mt9t013_regs.reg_pat[rt].x_addr_start);
589 if (rc < 0)
590 return rc;
591
592 rc =
593 mt9t013_i2c_write_w(mt9t013_client->addr,
594 REG_X_ADDR_END,
595 mt9t013_regs.reg_pat[rt].x_addr_end);
596 if (rc < 0)
597 return rc;
598
599 rc =
600 mt9t013_i2c_write_w(mt9t013_client->addr,
601 REG_Y_ADDR_START,
602 mt9t013_regs.reg_pat[rt].y_addr_start);
603 if (rc < 0)
604 return rc;
605
606 rc =
607 mt9t013_i2c_write_w(mt9t013_client->addr,
608 REG_Y_ADDR_END,
609 mt9t013_regs.reg_pat[rt].y_addr_end);
610 if (rc < 0)
611 return rc;
612
613 if (machine_is_sapphire()) {
614 if (rt == 0)
615 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
616 REG_READ_MODE,
617 0x046F);
618 else
619 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
620 REG_READ_MODE,
621 0x0027);
622 } else
623 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
624 REG_READ_MODE,
625 mt9t013_regs.reg_pat[rt].read_mode);
626 if (rc < 0)
627 return rc;
628
629 rc =
630 mt9t013_i2c_write_w(mt9t013_client->addr,
631 REG_SCALE_M,
632 mt9t013_regs.reg_pat[rt].scale_m);
633 if (rc < 0)
634 return rc;
635
636
637 rc =
638 mt9t013_i2c_write_w(mt9t013_client->addr,
639 REG_X_OUTPUT_SIZE,
640 mt9t013_regs.reg_pat[rt].x_output_size);
641 if (rc < 0)
642 return rc;
643
644 rc =
645 mt9t013_i2c_write_w(mt9t013_client->addr,
646 REG_Y_OUTPUT_SIZE,
647 mt9t013_regs.reg_pat[rt].y_output_size);
648 if (rc < 0)
649 return rc;
650
651 rc =
652 mt9t013_i2c_write_w(mt9t013_client->addr,
653 REG_LINE_LENGTH_PCK,
654 mt9t013_regs.reg_pat[rt].line_length_pck);
655 if (rc < 0)
656 return rc;
657
658 rc =
659 mt9t013_i2c_write_w(mt9t013_client->addr,
660 REG_FRAME_LENGTH_LINES,
661 (mt9t013_regs.reg_pat[rt].frame_length_lines *
662 mt9t013_ctrl->fps_divider / 0x00000400));
663 if (rc < 0)
664 return rc;
665
666 rc =
667 mt9t013_i2c_write_w(mt9t013_client->addr,
668 REG_COARSE_INT_TIME,
669 mt9t013_regs.reg_pat[rt].coarse_int_time);
670 if (rc < 0)
671 return rc;
672
673 rc =
674 mt9t013_i2c_write_w(mt9t013_client->addr,
675 REG_FINE_INT_TIME,
676 mt9t013_regs.reg_pat[rt].fine_int_time);
677 if (rc < 0)
678 return rc;
679
680 rc =
681 mt9t013_i2c_write_w(mt9t013_client->addr,
682 REG_GROUPED_PARAMETER_HOLD,
683 GROUPED_PARAMETER_UPDATE);
684 if (rc < 0)
685 return rc;
686
687 rc = mt9t013_test(mt9t013_ctrl->set_test);
688 if (rc < 0)
689 return rc;
690
691 rc =
692 mt9t013_i2c_write_w(mt9t013_client->addr,
693 MT9T013_REG_RESET_REGISTER,
694 MT9T013_RESET_REGISTER_PWON);
695 if (rc < 0)
696 return rc;
697
698 mdelay(5);
699
700 return rc;
701 }
702 }
703 break;
704
705 /*CAMSENSOR_REG_UPDATE_PERIODIC */
706 case REG_INIT: {
707 if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
708
709 rc =
710 mt9t013_i2c_write_w(mt9t013_client->addr,
711 MT9T013_REG_RESET_REGISTER,
712 MT9T013_RESET_REGISTER_PWOFF);
713 if (rc < 0)
714 /* MODE_SELECT, stop streaming */
715 return rc;
716
717 rc =
718 mt9t013_i2c_write_w(mt9t013_client->addr,
719 REG_VT_PIX_CLK_DIV,
720 mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
721 if (rc < 0)
722 return rc;
723
724 rc =
725 mt9t013_i2c_write_w(mt9t013_client->addr,
726 REG_VT_SYS_CLK_DIV,
727 mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
728 if (rc < 0)
729 return rc;
730
731 rc =
732 mt9t013_i2c_write_w(mt9t013_client->addr,
733 REG_PRE_PLL_CLK_DIV,
734 mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
735 if (rc < 0)
736 return rc;
737
738 rc =
739 mt9t013_i2c_write_w(mt9t013_client->addr,
740 REG_PLL_MULTIPLIER,
741 mt9t013_regs.reg_pat[rt].pll_multiplier);
742 if (rc < 0)
743 return rc;
744
745 rc =
746 mt9t013_i2c_write_w(mt9t013_client->addr,
747 REG_OP_PIX_CLK_DIV,
748 mt9t013_regs.reg_pat[rt].op_pix_clk_div);
749 if (rc < 0)
750 return rc;
751
752 rc =
753 mt9t013_i2c_write_w(mt9t013_client->addr,
754 REG_OP_SYS_CLK_DIV,
755 mt9t013_regs.reg_pat[rt].op_sys_clk_div);
756 if (rc < 0)
757 return rc;
758
759 mdelay(5);
760
761 rc =
762 mt9t013_i2c_write_w(mt9t013_client->addr,
763 REG_GROUPED_PARAMETER_HOLD,
764 GROUPED_PARAMETER_HOLD);
765 if (rc < 0)
766 return rc;
767
768 /* additional power saving mode ok around 38.2MHz */
769 rc =
770 mt9t013_i2c_write_w(mt9t013_client->addr,
771 0x3084, 0x2409);
772 if (rc < 0)
773 return rc;
774
775 rc =
776 mt9t013_i2c_write_w(mt9t013_client->addr,
777 0x3092, 0x0A49);
778 if (rc < 0)
779 return rc;
780
781 rc =
782 mt9t013_i2c_write_w(mt9t013_client->addr,
783 0x3094, 0x4949);
784 if (rc < 0)
785 return rc;
786
787 rc =
788 mt9t013_i2c_write_w(mt9t013_client->addr,
789 0x3096, 0x4949);
790 if (rc < 0)
791 return rc;
792
793 /* Set preview or snapshot mode */
794 rc =
795 mt9t013_i2c_write_w(mt9t013_client->addr,
796 REG_ROW_SPEED,
797 mt9t013_regs.reg_pat[rt].row_speed);
798 if (rc < 0)
799 return rc;
800
801 rc =
802 mt9t013_i2c_write_w(mt9t013_client->addr,
803 REG_X_ADDR_START,
804 mt9t013_regs.reg_pat[rt].x_addr_start);
805 if (rc < 0)
806 return rc;
807
808 rc =
809 mt9t013_i2c_write_w(mt9t013_client->addr,
810 REG_X_ADDR_END,
811 mt9t013_regs.reg_pat[rt].x_addr_end);
812 if (rc < 0)
813 return rc;
814
815 rc =
816 mt9t013_i2c_write_w(mt9t013_client->addr,
817 REG_Y_ADDR_START,
818 mt9t013_regs.reg_pat[rt].y_addr_start);
819 if (rc < 0)
820 return rc;
821
822 rc =
823 mt9t013_i2c_write_w(mt9t013_client->addr,
824 REG_Y_ADDR_END,
825 mt9t013_regs.reg_pat[rt].y_addr_end);
826 if (rc < 0)
827 return rc;
828
829 if (machine_is_sapphire()) {
830 if (rt == 0)
831 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
832 REG_READ_MODE,
833 0x046F);
834 else
835 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
836 REG_READ_MODE,
837 0x0027);
838 } else
839 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
840 REG_READ_MODE,
841 mt9t013_regs.reg_pat[rt].read_mode);
842 if (rc < 0)
843 return rc;
844
845 rc =
846 mt9t013_i2c_write_w(mt9t013_client->addr,
847 REG_SCALE_M,
848 mt9t013_regs.reg_pat[rt].scale_m);
849 if (rc < 0)
850 return rc;
851
852 rc =
853 mt9t013_i2c_write_w(mt9t013_client->addr,
854 REG_X_OUTPUT_SIZE,
855 mt9t013_regs.reg_pat[rt].x_output_size);
856 if (rc < 0)
857 return rc;
858
859 rc =
860 mt9t013_i2c_write_w(mt9t013_client->addr,
861 REG_Y_OUTPUT_SIZE,
862 mt9t013_regs.reg_pat[rt].y_output_size);
863 if (rc < 0)
864 return 0;
865
866 rc =
867 mt9t013_i2c_write_w(mt9t013_client->addr,
868 REG_LINE_LENGTH_PCK,
869 mt9t013_regs.reg_pat[rt].line_length_pck);
870 if (rc < 0)
871 return rc;
872
873 rc =
874 mt9t013_i2c_write_w(mt9t013_client->addr,
875 REG_FRAME_LENGTH_LINES,
876 mt9t013_regs.reg_pat[rt].frame_length_lines);
877 if (rc < 0)
878 return rc;
879
880 rc =
881 mt9t013_i2c_write_w(mt9t013_client->addr,
882 REG_COARSE_INT_TIME,
883 mt9t013_regs.reg_pat[rt].coarse_int_time);
884 if (rc < 0)
885 return rc;
886
887 rc =
888 mt9t013_i2c_write_w(mt9t013_client->addr,
889 REG_FINE_INT_TIME,
890 mt9t013_regs.reg_pat[rt].fine_int_time);
891 if (rc < 0)
892 return rc;
893
894 rc =
895 mt9t013_i2c_write_w(mt9t013_client->addr,
896 REG_GROUPED_PARAMETER_HOLD,
897 GROUPED_PARAMETER_UPDATE);
898 if (rc < 0)
899 return rc;
900
901 /* load lens shading */
902 rc =
903 mt9t013_i2c_write_w(mt9t013_client->addr,
904 REG_GROUPED_PARAMETER_HOLD,
905 GROUPED_PARAMETER_HOLD);
906 if (rc < 0)
907 return rc;
908
909 /* most likely needs to be written only once. */
910 rc = mt9t013_set_lc();
911 if (rc < 0)
912 return -EBUSY;
913
914 rc =
915 mt9t013_i2c_write_w(mt9t013_client->addr,
916 REG_GROUPED_PARAMETER_HOLD,
917 GROUPED_PARAMETER_UPDATE);
918 if (rc < 0)
919 return rc;
920
921 rc = mt9t013_test(mt9t013_ctrl->set_test);
922 if (rc < 0)
923 return rc;
924
925 mdelay(5);
926
927 rc =
928 mt9t013_i2c_write_w(mt9t013_client->addr,
929 MT9T013_REG_RESET_REGISTER,
930 MT9T013_RESET_REGISTER_PWON);
931 if (rc < 0)
932 /* MODE_SELECT, stop streaming */
933 return rc;
934
935 CDBG("!!! mt9t013 !!! PowerOn is done!\n");
936 mdelay(5);
937 return rc;
938 }
939 } /* case CAMSENSOR_REG_INIT: */
940 break;
941
942 /*CAMSENSOR_REG_INIT */
943 default:
944 rc = -EINVAL;
945 break;
946 } /* switch (rupdate) */
947
948 return rc;
949}
950
951static int32_t mt9t013_video_config(int mode, int res)
952{
953 int32_t rc;
954
955 switch (res) {
956 case QTR_SIZE:
957 rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
958 if (rc < 0)
959 return rc;
960 CDBG("sensor configuration done!\n");
961 break;
962
963 case FULL_SIZE:
964 rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
965 if (rc < 0)
966 return rc;
967 break;
968
969 default:
970 return -EINVAL;
971 } /* switch */
972
973 mt9t013_ctrl->prev_res = res;
974 mt9t013_ctrl->curr_res = res;
975 mt9t013_ctrl->sensormode = mode;
976
977 return mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
978 mt9t013_ctrl->my_reg_line_count);
979}
980
981static int32_t mt9t013_snapshot_config(int mode)
982{
983 int32_t rc = 0;
984
985 rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
986 if (rc < 0)
987 return rc;
988
989 mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
990 mt9t013_ctrl->sensormode = mode;
991 return rc;
992}
993
994static int32_t mt9t013_raw_snapshot_config(int mode)
995{
996 int32_t rc = 0;
997
998 rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
999 if (rc < 0)
1000 return rc;
1001
1002 mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
1003 mt9t013_ctrl->sensormode = mode;
1004 return rc;
1005}
1006
1007static int32_t mt9t013_power_down(void)
1008{
1009 int32_t rc = 0;
1010
1011 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1012 MT9T013_REG_RESET_REGISTER,
1013 MT9T013_RESET_REGISTER_PWOFF);
1014 if (rc >= 0)
1015 mdelay(5);
1016 return rc;
1017}
1018
1019static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
1020{
1021 int16_t step_direction;
1022 int16_t actual_step;
1023 int16_t next_position;
1024 int16_t break_steps[4];
1025 uint8_t code_val_msb, code_val_lsb;
1026 int16_t i;
1027
1028 if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
1029 num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
1030 else if (num_steps == 0)
1031 return -EINVAL;
1032
1033 if (direction == MOVE_NEAR)
1034 step_direction = 4;
1035 else if (direction == MOVE_FAR)
1036 step_direction = -4;
1037 else
1038 return -EINVAL;
1039
1040 if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
1041 mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
1042
1043 actual_step =
1044 (int16_t) (step_direction *
1045 (int16_t) num_steps);
1046
1047 for (i = 0; i < 4; i++)
1048 break_steps[i] =
1049 actual_step / 4 * (i + 1) - actual_step / 4 * i;
1050
1051 for (i = 0; i < 4; i++) {
1052 next_position =
1053 (int16_t)
1054 (mt9t013_ctrl->curr_lens_pos + break_steps[i]);
1055
1056 if (next_position > 255)
1057 next_position = 255;
1058 else if (next_position < 0)
1059 next_position = 0;
1060
1061 code_val_msb =
1062 ((next_position >> 4) << 2) |
1063 ((next_position << 4) >> 6);
1064
1065 code_val_lsb =
1066 ((next_position & 0x03) << 6);
1067
1068 /* Writing the digital code for current to the actuator */
1069 if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
1070 code_val_msb, code_val_lsb) < 0)
1071 return -EBUSY;
1072
1073 /* Storing the current lens Position */
1074 mt9t013_ctrl->curr_lens_pos = next_position;
1075
1076 if (i < 3)
1077 mdelay(1);
1078 } /* for */
1079
1080 return 0;
1081}
1082
1083static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
1084{
1085 gpio_direction_output(data->sensor_reset, 0);
1086 gpio_free(data->sensor_reset);
1087 return 0;
1088}
1089
1090static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
1091{
1092 int rc;
1093 uint16_t chipid;
1094
1095 rc = gpio_request(data->sensor_reset, "mt9t013");
1096 if (!rc)
1097 gpio_direction_output(data->sensor_reset, 1);
1098 else
1099 goto init_probe_done;
1100
1101 mdelay(20);
1102
1103 /* RESET the sensor image part via I2C command */
1104 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1105 MT9T013_REG_RESET_REGISTER, 0x1009);
1106 if (rc < 0)
1107 goto init_probe_fail;
1108
1109 /* 3. Read sensor Model ID: */
1110 rc = mt9t013_i2c_read_w(mt9t013_client->addr,
1111 MT9T013_REG_MODEL_ID, &chipid);
1112
1113 if (rc < 0)
1114 goto init_probe_fail;
1115
1116 CDBG("mt9t013 model_id = 0x%x\n", chipid);
1117
1118 /* 4. Compare sensor ID to MT9T012VC ID: */
1119 if (chipid != MT9T013_MODEL_ID) {
1120 rc = -ENODEV;
1121 goto init_probe_fail;
1122 }
1123
1124 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1125 0x3064, 0x0805);
1126 if (rc < 0)
1127 goto init_probe_fail;
1128
1129 mdelay(MT9T013_RESET_DELAY_MSECS);
1130
1131 goto init_probe_done;
1132
1133 /* sensor: output enable */
1134#if 0
1135 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1136 MT9T013_REG_RESET_REGISTER,
1137 MT9T013_RESET_REGISTER_PWON);
1138
1139 /* if this fails, the sensor is not the MT9T013 */
1140 rc = mt9t013_set_default_focus(0);
1141#endif
1142
1143init_probe_fail:
1144 gpio_direction_output(data->sensor_reset, 0);
1145 gpio_free(data->sensor_reset);
1146init_probe_done:
1147 return rc;
1148}
1149
1150static int32_t mt9t013_poweron_af(void)
1151{
1152 int32_t rc = 0;
1153
1154 /* enable AF actuator */
1155 CDBG("enable AF actuator, gpio = %d\n",
1156 mt9t013_ctrl->sensordata->vcm_pwd);
1157 rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
1158 if (!rc) {
1159 gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
1160 mdelay(20);
1161 rc = mt9t013_set_default_focus(0);
1162 } else
1163 pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
1164 return rc;
1165}
1166
1167static void mt9t013_poweroff_af(void)
1168{
1169 gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
1170 gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
1171}
1172
1173int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
1174{
1175 int32_t rc;
1176
1177 mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
1178 if (!mt9t013_ctrl) {
1179 pr_err("mt9t013_init failed!\n");
1180 rc = -ENOMEM;
1181 goto init_done;
1182 }
1183
1184 mt9t013_ctrl->fps_divider = 1 * 0x00000400;
1185 mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
1186 mt9t013_ctrl->set_test = TEST_OFF;
1187 mt9t013_ctrl->prev_res = QTR_SIZE;
1188 mt9t013_ctrl->pict_res = FULL_SIZE;
1189
1190 if (data)
1191 mt9t013_ctrl->sensordata = data;
1192
1193 /* enable mclk first */
1194 msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
1195 mdelay(20);
1196
1197 msm_camio_camif_pad_reg_reset();
1198 mdelay(20);
1199
1200 rc = mt9t013_probe_init_sensor(data);
1201 if (rc < 0)
1202 goto init_fail;
1203
1204 if (mt9t013_ctrl->prev_res == QTR_SIZE)
1205 rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
1206 else
1207 rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
1208
1209 if (rc >= 0)
1210 rc = mt9t013_poweron_af();
1211
1212 if (rc < 0)
1213 goto init_fail;
1214 else
1215 goto init_done;
1216
1217init_fail:
1218 kfree(mt9t013_ctrl);
1219init_done:
1220 return rc;
1221}
1222
1223static int mt9t013_init_client(struct i2c_client *client)
1224{
1225 /* Initialize the MSM_CAMI2C Chip */
1226 init_waitqueue_head(&mt9t013_wait_queue);
1227 return 0;
1228}
1229
1230
1231static int32_t mt9t013_set_sensor_mode(int mode, int res)
1232{
1233 int32_t rc = 0;
1234 rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1235 REG_GROUPED_PARAMETER_HOLD,
1236 GROUPED_PARAMETER_HOLD);
1237 if (rc < 0)
1238 return rc;
1239
1240 switch (mode) {
1241 case SENSOR_PREVIEW_MODE:
1242 rc = mt9t013_video_config(mode, res);
1243 break;
1244
1245 case SENSOR_SNAPSHOT_MODE:
1246 rc = mt9t013_snapshot_config(mode);
1247 break;
1248
1249 case SENSOR_RAW_SNAPSHOT_MODE:
1250 rc = mt9t013_raw_snapshot_config(mode);
1251 break;
1252
1253 default:
1254 return -EINVAL;
1255 }
1256
1257 /* FIXME: what should we do if rc < 0? */
1258 if (rc >= 0)
1259 return mt9t013_i2c_write_w(mt9t013_client->addr,
1260 REG_GROUPED_PARAMETER_HOLD,
1261 GROUPED_PARAMETER_UPDATE);
1262 return rc;
1263}
1264
1265int mt9t013_sensor_config(void __user *argp)
1266{
1267 struct sensor_cfg_data cdata;
1268 long rc = 0;
1269
1270 if (copy_from_user(&cdata, (void *)argp,
1271 sizeof(struct sensor_cfg_data)))
1272 return -EFAULT;
1273
1274 down(&mt9t013_sem);
1275
1276 CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
1277 switch (cdata.cfgtype) {
1278 case CFG_GET_PICT_FPS:
1279 mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
1280 &(cdata.cfg.gfps.pictfps));
1281 if (copy_to_user((void *)argp,
1282 &cdata,
1283 sizeof(struct sensor_cfg_data)))
1284 rc = -EFAULT;
1285 break;
1286
1287 case CFG_GET_PREV_L_PF:
1288 cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
1289 if (copy_to_user((void *)argp,
1290 &cdata,
1291 sizeof(struct sensor_cfg_data)))
1292 rc = -EFAULT;
1293 break;
1294
1295 case CFG_GET_PREV_P_PL:
1296 cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
1297 if (copy_to_user((void *)argp,
1298 &cdata,
1299 sizeof(struct sensor_cfg_data)))
1300 rc = -EFAULT;
1301 break;
1302
1303 case CFG_GET_PICT_L_PF:
1304 cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
1305 if (copy_to_user((void *)argp,
1306 &cdata,
1307 sizeof(struct sensor_cfg_data)))
1308 rc = -EFAULT;
1309 break;
1310
1311 case CFG_GET_PICT_P_PL:
1312 cdata.cfg.pictp_pl =
1313 mt9t013_get_pict_pixels_pl();
1314
1315 if (copy_to_user((void *)argp,
1316 &cdata,
1317 sizeof(struct sensor_cfg_data)))
1318 rc = -EFAULT;
1319 break;
1320
1321 case CFG_GET_PICT_MAX_EXP_LC:
1322 cdata.cfg.pict_max_exp_lc =
1323 mt9t013_get_pict_max_exp_lc();
1324
1325 if (copy_to_user((void *)argp,
1326 &cdata,
1327 sizeof(struct sensor_cfg_data)))
1328 rc = -EFAULT;
1329 break;
1330
1331 case CFG_SET_FPS:
1332 case CFG_SET_PICT_FPS:
1333 rc = mt9t013_set_fps(&(cdata.cfg.fps));
1334 break;
1335
1336 case CFG_SET_EXP_GAIN:
1337 rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
1338 cdata.cfg.exp_gain.line);
1339 break;
1340
1341 case CFG_SET_PICT_EXP_GAIN:
1342 rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
1343 cdata.cfg.exp_gain.line);
1344 break;
1345
1346 case CFG_SET_MODE:
1347 rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
1348 break;
1349
1350 case CFG_PWR_DOWN:
1351 rc = mt9t013_power_down();
1352 break;
1353
1354 case CFG_MOVE_FOCUS:
1355 rc = mt9t013_move_focus(cdata.cfg.focus.dir,
1356 cdata.cfg.focus.steps);
1357 break;
1358
1359 case CFG_SET_DEFAULT_FOCUS:
1360 rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
1361 break;
1362
1363 case CFG_GET_AF_MAX_STEPS:
1364 cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
1365 if (copy_to_user((void *)argp,
1366 &cdata,
1367 sizeof(struct sensor_cfg_data)))
1368 rc = -EFAULT;
1369 break;
1370
1371 case CFG_SET_EFFECT:
1372 default:
1373 rc = -EINVAL;
1374 break;
1375 }
1376
1377 up(&mt9t013_sem);
1378 return rc;
1379}
1380
1381int mt9t013_sensor_release(void)
1382{
1383 int rc = -EBADF;
1384
1385 down(&mt9t013_sem);
1386
1387 mt9t013_poweroff_af();
1388 mt9t013_power_down();
1389
1390 gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
1391 0);
1392 gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
1393
1394 kfree(mt9t013_ctrl);
1395
1396 up(&mt9t013_sem);
1397 CDBG("mt9t013_release completed!\n");
1398 return rc;
1399}
1400
1401static int mt9t013_i2c_probe(struct i2c_client *client,
1402 const struct i2c_device_id *id)
1403{
1404 int rc = 0;
1405 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1406 rc = -ENOTSUPP;
1407 goto probe_failure;
1408 }
1409
1410 mt9t013_sensorw =
1411 kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
1412
1413 if (!mt9t013_sensorw) {
1414 rc = -ENOMEM;
1415 goto probe_failure;
1416 }
1417
1418 i2c_set_clientdata(client, mt9t013_sensorw);
1419 mt9t013_init_client(client);
1420 mt9t013_client = client;
1421 mt9t013_client->addr = mt9t013_client->addr >> 1;
1422 mdelay(50);
1423
1424 CDBG("i2c probe ok\n");
1425 return 0;
1426
1427probe_failure:
1428 kfree(mt9t013_sensorw);
1429 mt9t013_sensorw = NULL;
1430 pr_err("i2c probe failure %d\n", rc);
1431 return rc;
1432}
1433
1434static const struct i2c_device_id mt9t013_i2c_id[] = {
1435 { "mt9t013", 0},
1436 { }
1437};
1438
1439static struct i2c_driver mt9t013_i2c_driver = {
1440 .id_table = mt9t013_i2c_id,
1441 .probe = mt9t013_i2c_probe,
1442 .remove = __exit_p(mt9t013_i2c_remove),
1443 .driver = {
1444 .name = "mt9t013",
1445 },
1446};
1447
1448static int mt9t013_sensor_probe(
1449 const struct msm_camera_sensor_info *info,
1450 struct msm_sensor_ctrl *s)
1451{
1452 /* We expect this driver to match with the i2c device registered
1453 * in the board file immediately. */
1454 int rc = i2c_add_driver(&mt9t013_i2c_driver);
1455 if (rc < 0 || mt9t013_client == NULL) {
1456 rc = -ENOTSUPP;
1457 goto probe_done;
1458 }
1459
1460 /* enable mclk first */
1461 msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
1462 mdelay(20);
1463
1464 rc = mt9t013_probe_init_sensor(info);
1465 if (rc < 0) {
1466 i2c_del_driver(&mt9t013_i2c_driver);
1467 goto probe_done;
1468 }
1469
1470 s->s_init = mt9t013_sensor_open_init;
1471 s->s_release = mt9t013_sensor_release;
1472 s->s_config = mt9t013_sensor_config;
1473 mt9t013_sensor_init_done(info);
1474
1475probe_done:
1476 return rc;
1477}
1478
1479static int __mt9t013_probe(struct platform_device *pdev)
1480{
1481 return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
1482}
1483
1484static struct platform_driver msm_camera_driver = {
1485 .probe = __mt9t013_probe,
1486 .driver = {
1487 .name = "msm_camera_mt9t013",
1488 .owner = THIS_MODULE,
1489 },
1490};
1491
1492static int __init mt9t013_init(void)
1493{
1494 return platform_driver_register(&msm_camera_driver);
1495}
1496
1497module_init(mt9t013_init);
diff --git a/drivers/staging/dream/camera/mt9t013.h b/drivers/staging/dream/camera/mt9t013.h
deleted file mode 100644
index 9bce2036e3b6..000000000000
--- a/drivers/staging/dream/camera/mt9t013.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef MT9T013_H
6#define MT9T013_H
7
8#include <linux/types.h>
9
10struct reg_struct {
11 uint16_t vt_pix_clk_div; /* 0x0300 */
12 uint16_t vt_sys_clk_div; /* 0x0302 */
13 uint16_t pre_pll_clk_div; /* 0x0304 */
14 uint16_t pll_multiplier; /* 0x0306 */
15 uint16_t op_pix_clk_div; /* 0x0308 */
16 uint16_t op_sys_clk_div; /* 0x030A */
17 uint16_t scale_m; /* 0x0404 */
18 uint16_t row_speed; /* 0x3016 */
19 uint16_t x_addr_start; /* 0x3004 */
20 uint16_t x_addr_end; /* 0x3008 */
21 uint16_t y_addr_start; /* 0x3002 */
22 uint16_t y_addr_end; /* 0x3006 */
23 uint16_t read_mode; /* 0x3040 */
24 uint16_t x_output_size; /* 0x034C */
25 uint16_t y_output_size; /* 0x034E */
26 uint16_t line_length_pck; /* 0x300C */
27 uint16_t frame_length_lines; /* 0x300A */
28 uint16_t coarse_int_time; /* 0x3012 */
29 uint16_t fine_int_time; /* 0x3014 */
30};
31
32struct mt9t013_i2c_reg_conf {
33 unsigned short waddr;
34 unsigned short wdata;
35};
36
37struct mt9t013_reg {
38 struct reg_struct *reg_pat;
39 uint16_t reg_pat_size;
40 struct mt9t013_i2c_reg_conf *ttbl;
41 uint16_t ttbl_size;
42 struct mt9t013_i2c_reg_conf *lctbl;
43 uint16_t lctbl_size;
44 struct mt9t013_i2c_reg_conf *rftbl;
45 uint16_t rftbl_size;
46};
47
48#endif /* #define MT9T013_H */
diff --git a/drivers/staging/dream/camera/mt9t013_reg.c b/drivers/staging/dream/camera/mt9t013_reg.c
deleted file mode 100644
index ba0a1d4b4d5f..000000000000
--- a/drivers/staging/dream/camera/mt9t013_reg.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * Copyright (C) 2009 QUALCOMM Incorporated.
3 */
4
5#include "mt9t013.h"
6#include <linux/kernel.h>
7
8struct reg_struct const mt9t013_reg_pat[2] = {
9 { /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
10 /* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
11 * if this change */
12 8,
13
14 /* vt_sys_clk_div: REG=0x0302 update get_snapshot_fps
15 * if this change */
16 1,
17
18 /* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
19 * if this change */
20 2,
21
22 /* pll_multiplier REG=0x0306 60 for 30fps preview, 40
23 * for 20fps preview
24 * 46 for 30fps preview, try 47/48 to increase further */
25 46,
26
27 /* op_pix_clk_div REG=0x0308 */
28 8,
29
30 /* op_sys_clk_div REG=0x030A */
31 1,
32
33 /* scale_m REG=0x0404 */
34 16,
35
36 /* row_speed REG=0x3016 */
37 0x0111,
38
39 /* x_addr_start REG=0x3004 */
40 8,
41
42 /* x_addr_end REG=0x3008 */
43 2053,
44
45 /* y_addr_start REG=0x3002 */
46 8,
47
48 /* y_addr_end REG=0x3006 */
49 1541,
50
51 /* read_mode REG=0x3040 */
52 0x046C,
53
54 /* x_output_size REG=0x034C */
55 1024,
56
57 /* y_output_size REG=0x034E */
58 768,
59
60 /* line_length_pck REG=0x300C */
61 2616,
62
63 /* frame_length_lines REG=0x300A */
64 916,
65
66 /* coarse_int_time REG=0x3012 */
67 16,
68
69 /* fine_int_time REG=0x3014 */
70 1461
71 },
72 { /*Snapshot */
73 /* vt_pix_clk_div REG=0x0300 update get_snapshot_fps
74 * if this change */
75 8,
76
77 /* vt_sys_clk_div REG=0x0302 update get_snapshot_fps
78 * if this change */
79 1,
80
81 /* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
82 * if this change */
83 2,
84
85 /* pll_multiplier REG=0x0306 50 for 15fps snapshot,
86 * 40 for 10fps snapshot
87 * 46 for 30fps snapshot, try 47/48 to increase further */
88 46,
89
90 /* op_pix_clk_div REG=0x0308 */
91 8,
92
93 /* op_sys_clk_div REG=0x030A */
94 1,
95
96 /* scale_m REG=0x0404 */
97 16,
98
99 /* row_speed REG=0x3016 */
100 0x0111,
101
102 /* x_addr_start REG=0x3004 */
103 8,
104
105 /* x_addr_end REG=0x3008 */
106 2071,
107
108 /* y_addr_start REG=0x3002 */
109 8,
110
111 /* y_addr_end REG=0x3006 */
112 1551,
113
114 /* read_mode REG=0x3040 */
115 0x0024,
116
117 /* x_output_size REG=0x034C */
118 2064,
119
120 /* y_output_size REG=0x034E */
121 1544,
122
123 /* line_length_pck REG=0x300C */
124 2952,
125
126 /* frame_length_lines REG=0x300A */
127 1629,
128
129 /* coarse_int_time REG=0x3012 */
130 16,
131
132 /* fine_int_time REG=0x3014 */
133 733
134 }
135};
136
137struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = {
138 { 0x3044, 0x0544 & 0xFBFF },
139 { 0x30CA, 0x0004 | 0x0001 },
140 { 0x30D4, 0x9020 & 0x7FFF },
141 { 0x31E0, 0x0003 & 0xFFFE },
142 { 0x3180, 0x91FF & 0x7FFF },
143 { 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
144 { 0x301E, 0x0000 },
145 { 0x3780, 0x0000 },
146};
147
148/* [Lens shading 85 Percent TL84] */
149struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = {
150 { 0x360A, 0x0290 }, /* P_RD_P0Q0 */
151 { 0x360C, 0xC92D }, /* P_RD_P0Q1 */
152 { 0x360E, 0x0771 }, /* P_RD_P0Q2 */
153 { 0x3610, 0xE38C }, /* P_RD_P0Q3 */
154 { 0x3612, 0xD74F }, /* P_RD_P0Q4 */
155 { 0x364A, 0x168C }, /* P_RD_P1Q0 */
156 { 0x364C, 0xCACB }, /* P_RD_P1Q1 */
157 { 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
158 { 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
159 { 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
160 { 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
161 { 0x368C, 0x200B }, /* P_RD_P2Q1 */
162 { 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
163 { 0x3690, 0xD04F }, /* P_RD_P2Q3 */
164 { 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
165 { 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
166 { 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
167 { 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
168 { 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
169 { 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
170 { 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
171 { 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
172 { 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
173 { 0x3710, 0x8195 }, /* P_RD_P4Q3 */
174 { 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
175 { 0x3600, 0x0230 }, /* P_GR_P0Q0 */
176 { 0x3602, 0x58AD }, /* P_GR_P0Q1 */
177 { 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
178 { 0x3606, 0x260D }, /* P_GR_P0Q3 */
179 { 0x3608, 0xF530 }, /* P_GR_P0Q4 */
180 { 0x3640, 0x17EB }, /* P_GR_P1Q0 */
181 { 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
182 { 0x3644, 0x87CE }, /* P_GR_P1Q2 */
183 { 0x3646, 0xC02E }, /* P_GR_P1Q3 */
184 { 0x3648, 0xF48F }, /* P_GR_P1Q4 */
185 { 0x3680, 0x5350 }, /* P_GR_P2Q0 */
186 { 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
187 { 0x3684, 0x4312 }, /* P_GR_P2Q2 */
188 { 0x3686, 0xC652 }, /* P_GR_P2Q3 */
189 { 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
190 { 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
191 { 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
192 { 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
193 { 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
194 { 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
195 { 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
196 { 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
197 { 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
198 { 0x3706, 0xB594 }, /* P_GR_P4Q3 */
199 { 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
200 { 0x3614, 0x0230 }, /* P_BL_P0Q0 */
201 { 0x3616, 0x160D }, /* P_BL_P0Q1 */
202 { 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
203 { 0x361A, 0x98AB }, /* P_BL_P0Q3 */
204 { 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
205 { 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
206 { 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
207 { 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
208 { 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
209 { 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
210 { 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
211 { 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
212 { 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
213 { 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
214 { 0x369C, 0xC374 }, /* P_BL_P2Q4 */
215 { 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
216 { 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
217 { 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
218 { 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
219 { 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
220 { 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
221 { 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
222 { 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
223 { 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
224 { 0x371C, 0x6338 }, /* P_BL_P4Q4 */
225 { 0x361E, 0x0350 }, /* P_GB_P0Q0 */
226 { 0x3620, 0x91AE }, /* P_GB_P0Q1 */
227 { 0x3622, 0x0571 }, /* P_GB_P0Q2 */
228 { 0x3624, 0x100D }, /* P_GB_P0Q3 */
229 { 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
230 { 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
231 { 0x3660, 0x50ED }, /* P_GB_P1Q1 */
232 { 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
233 { 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
234 { 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
235 { 0x369E, 0x5470 }, /* P_GB_P2Q0 */
236 { 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
237 { 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
238 { 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
239 { 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
240 { 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
241 { 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
242 { 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
243 { 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
244 { 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
245 { 0x371E, 0x9651 }, /* P_GB_P4Q0 */
246 { 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
247 { 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
248 { 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
249 { 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
250 { 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
251 { 0x3784, 0x0320 }, /* POLY_ORIGIN_R */
252 { 0x3780, 0x8000 } /* POLY_SC_ENABLE */
253};
254
255struct mt9t013_reg mt9t013_regs = {
256 .reg_pat = &mt9t013_reg_pat[0],
257 .reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
258 .ttbl = &mt9t013_test_tbl[0],
259 .ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
260 .lctbl = &mt9t013_lc_tbl[0],
261 .lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
262 .rftbl = &mt9t013_lc_tbl[0], /* &mt9t013_rolloff_tbl[0], */
263 .rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
264};
265
266
diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c
deleted file mode 100644
index 1459903a339d..000000000000
--- a/drivers/staging/dream/camera/s5k3e2fx.c
+++ /dev/null
@@ -1,1307 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/delay.h>
6#include <linux/slab.h>
7#include <linux/types.h>
8#include <linux/i2c.h>
9#include <linux/uaccess.h>
10#include <linux/miscdevice.h>
11#include <media/msm_camera.h>
12#include <mach/gpio.h>
13#include <mach/camera.h>
14#include "s5k3e2fx.h"
15
16#define S5K3E2FX_REG_MODEL_ID 0x0000
17#define S5K3E2FX_MODEL_ID 0x3E2F
18
19/* PLL Registers */
20#define REG_PRE_PLL_CLK_DIV 0x0305
21#define REG_PLL_MULTIPLIER_MSB 0x0306
22#define REG_PLL_MULTIPLIER_LSB 0x0307
23#define REG_VT_PIX_CLK_DIV 0x0301
24#define REG_VT_SYS_CLK_DIV 0x0303
25#define REG_OP_PIX_CLK_DIV 0x0309
26#define REG_OP_SYS_CLK_DIV 0x030B
27
28/* Data Format Registers */
29#define REG_CCP_DATA_FORMAT_MSB 0x0112
30#define REG_CCP_DATA_FORMAT_LSB 0x0113
31
32/* Output Size */
33#define REG_X_OUTPUT_SIZE_MSB 0x034C
34#define REG_X_OUTPUT_SIZE_LSB 0x034D
35#define REG_Y_OUTPUT_SIZE_MSB 0x034E
36#define REG_Y_OUTPUT_SIZE_LSB 0x034F
37
38/* Binning */
39#define REG_X_EVEN_INC 0x0381
40#define REG_X_ODD_INC 0x0383
41#define REG_Y_EVEN_INC 0x0385
42#define REG_Y_ODD_INC 0x0387
43/*Reserved register */
44#define REG_BINNING_ENABLE 0x3014
45
46/* Frame Fotmat */
47#define REG_FRAME_LENGTH_LINES_MSB 0x0340
48#define REG_FRAME_LENGTH_LINES_LSB 0x0341
49#define REG_LINE_LENGTH_PCK_MSB 0x0342
50#define REG_LINE_LENGTH_PCK_LSB 0x0343
51
52/* MSR setting */
53/* Reserved registers */
54#define REG_SHADE_CLK_ENABLE 0x30AC
55#define REG_SEL_CCP 0x30C4
56#define REG_VPIX 0x3024
57#define REG_CLAMP_ON 0x3015
58#define REG_OFFSET 0x307E
59
60/* CDS timing settings */
61/* Reserved registers */
62#define REG_LD_START 0x3000
63#define REG_LD_END 0x3001
64#define REG_SL_START 0x3002
65#define REG_SL_END 0x3003
66#define REG_RX_START 0x3004
67#define REG_S1_START 0x3005
68#define REG_S1_END 0x3006
69#define REG_S1S_START 0x3007
70#define REG_S1S_END 0x3008
71#define REG_S3_START 0x3009
72#define REG_S3_END 0x300A
73#define REG_CMP_EN_START 0x300B
74#define REG_CLP_SL_START 0x300C
75#define REG_CLP_SL_END 0x300D
76#define REG_OFF_START 0x300E
77#define REG_RMP_EN_START 0x300F
78#define REG_TX_START 0x3010
79#define REG_TX_END 0x3011
80#define REG_STX_WIDTH 0x3012
81#define REG_TYPE1_AF_ENABLE 0x3130
82#define DRIVER_ENABLED 0x0001
83#define AUTO_START_ENABLED 0x0010
84#define REG_NEW_POSITION 0x3131
85#define REG_3152_RESERVED 0x3152
86#define REG_315A_RESERVED 0x315A
87#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204
88#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205
89#define REG_FINE_INTEGRATION_TIME 0x0200
90#define REG_COARSE_INTEGRATION_TIME 0x0202
91#define REG_COARSE_INTEGRATION_TIME_LSB 0x0203
92
93/* Mode select register */
94#define S5K3E2FX_REG_MODE_SELECT 0x0100
95#define S5K3E2FX_MODE_SELECT_STREAM 0x01 /* start streaming */
96#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00 /* software standby */
97#define S5K3E2FX_REG_SOFTWARE_RESET 0x0103
98#define S5K3E2FX_SOFTWARE_RESET 0x01
99#define REG_TEST_PATTERN_MODE 0x0601
100
101struct reg_struct {
102 uint8_t pre_pll_clk_div; /* 0x0305 */
103 uint8_t pll_multiplier_msb; /* 0x0306 */
104 uint8_t pll_multiplier_lsb; /* 0x0307 */
105 uint8_t vt_pix_clk_div; /* 0x0301 */
106 uint8_t vt_sys_clk_div; /* 0x0303 */
107 uint8_t op_pix_clk_div; /* 0x0309 */
108 uint8_t op_sys_clk_div; /* 0x030B */
109 uint8_t ccp_data_format_msb; /* 0x0112 */
110 uint8_t ccp_data_format_lsb; /* 0x0113 */
111 uint8_t x_output_size_msb; /* 0x034C */
112 uint8_t x_output_size_lsb; /* 0x034D */
113 uint8_t y_output_size_msb; /* 0x034E */
114 uint8_t y_output_size_lsb; /* 0x034F */
115 uint8_t x_even_inc; /* 0x0381 */
116 uint8_t x_odd_inc; /* 0x0383 */
117 uint8_t y_even_inc; /* 0x0385 */
118 uint8_t y_odd_inc; /* 0x0387 */
119 uint8_t binning_enable; /* 0x3014 */
120 uint8_t frame_length_lines_msb; /* 0x0340 */
121 uint8_t frame_length_lines_lsb; /* 0x0341 */
122 uint8_t line_length_pck_msb; /* 0x0342 */
123 uint8_t line_length_pck_lsb; /* 0x0343 */
124 uint8_t shade_clk_enable ; /* 0x30AC */
125 uint8_t sel_ccp; /* 0x30C4 */
126 uint8_t vpix; /* 0x3024 */
127 uint8_t clamp_on; /* 0x3015 */
128 uint8_t offset; /* 0x307E */
129 uint8_t ld_start; /* 0x3000 */
130 uint8_t ld_end; /* 0x3001 */
131 uint8_t sl_start; /* 0x3002 */
132 uint8_t sl_end; /* 0x3003 */
133 uint8_t rx_start; /* 0x3004 */
134 uint8_t s1_start; /* 0x3005 */
135 uint8_t s1_end; /* 0x3006 */
136 uint8_t s1s_start; /* 0x3007 */
137 uint8_t s1s_end; /* 0x3008 */
138 uint8_t s3_start; /* 0x3009 */
139 uint8_t s3_end; /* 0x300A */
140 uint8_t cmp_en_start; /* 0x300B */
141 uint8_t clp_sl_start; /* 0x300C */
142 uint8_t clp_sl_end; /* 0x300D */
143 uint8_t off_start; /* 0x300E */
144 uint8_t rmp_en_start; /* 0x300F */
145 uint8_t tx_start; /* 0x3010 */
146 uint8_t tx_end; /* 0x3011 */
147 uint8_t stx_width; /* 0x3012 */
148 uint8_t reg_3152_reserved; /* 0x3152 */
149 uint8_t reg_315A_reserved; /* 0x315A */
150 uint8_t analogue_gain_code_global_msb; /* 0x0204 */
151 uint8_t analogue_gain_code_global_lsb; /* 0x0205 */
152 uint8_t fine_integration_time; /* 0x0200 */
153 uint8_t coarse_integration_time; /* 0x0202 */
154 uint32_t size_h;
155 uint32_t blk_l;
156 uint32_t size_w;
157 uint32_t blk_p;
158};
159
160struct reg_struct s5k3e2fx_reg_pat[2] = {
161 { /* Preview */
162 0x06, /* pre_pll_clk_div REG=0x0305 */
163 0x00, /* pll_multiplier_msb REG=0x0306 */
164 0x88, /* pll_multiplier_lsb REG=0x0307 */
165 0x0a, /* vt_pix_clk_div REG=0x0301 */
166 0x01, /* vt_sys_clk_div REG=0x0303 */
167 0x0a, /* op_pix_clk_div REG=0x0309 */
168 0x01, /* op_sys_clk_div REG=0x030B */
169 0x0a, /* ccp_data_format_msb REG=0x0112 */
170 0x0a, /* ccp_data_format_lsb REG=0x0113 */
171 0x05, /* x_output_size_msb REG=0x034C */
172 0x10, /* x_output_size_lsb REG=0x034D */
173 0x03, /* y_output_size_msb REG=0x034E */
174 0xcc, /* y_output_size_lsb REG=0x034F */
175
176 /* enable binning for preview */
177 0x01, /* x_even_inc REG=0x0381 */
178 0x01, /* x_odd_inc REG=0x0383 */
179 0x01, /* y_even_inc REG=0x0385 */
180 0x03, /* y_odd_inc REG=0x0387 */
181 0x06, /* binning_enable REG=0x3014 */
182
183 0x03, /* frame_length_lines_msb REG=0x0340 */
184 0xde, /* frame_length_lines_lsb REG=0x0341 */
185 0x0a, /* line_length_pck_msb REG=0x0342 */
186 0xac, /* line_length_pck_lsb REG=0x0343 */
187 0x81, /* shade_clk_enable REG=0x30AC */
188 0x01, /* sel_ccp REG=0x30C4 */
189 0x04, /* vpix REG=0x3024 */
190 0x00, /* clamp_on REG=0x3015 */
191 0x02, /* offset REG=0x307E */
192 0x03, /* ld_start REG=0x3000 */
193 0x9c, /* ld_end REG=0x3001 */
194 0x02, /* sl_start REG=0x3002 */
195 0x9e, /* sl_end REG=0x3003 */
196 0x05, /* rx_start REG=0x3004 */
197 0x0f, /* s1_start REG=0x3005 */
198 0x24, /* s1_end REG=0x3006 */
199 0x7c, /* s1s_start REG=0x3007 */
200 0x9a, /* s1s_end REG=0x3008 */
201 0x10, /* s3_start REG=0x3009 */
202 0x14, /* s3_end REG=0x300A */
203 0x10, /* cmp_en_start REG=0x300B */
204 0x04, /* clp_sl_start REG=0x300C */
205 0x26, /* clp_sl_end REG=0x300D */
206 0x02, /* off_start REG=0x300E */
207 0x0e, /* rmp_en_start REG=0x300F */
208 0x30, /* tx_start REG=0x3010 */
209 0x4e, /* tx_end REG=0x3011 */
210 0x1E, /* stx_width REG=0x3012 */
211 0x08, /* reg_3152_reserved REG=0x3152 */
212 0x10, /* reg_315A_reserved REG=0x315A */
213 0x00, /* analogue_gain_code_global_msb REG=0x0204 */
214 0x80, /* analogue_gain_code_global_lsb REG=0x0205 */
215 0x02, /* fine_integration_time REG=0x0200 */
216 0x03, /* coarse_integration_time REG=0x0202 */
217 972,
218 18,
219 1296,
220 1436
221 },
222 { /* Snapshot */
223 0x06, /* pre_pll_clk_div REG=0x0305 */
224 0x00, /* pll_multiplier_msb REG=0x0306 */
225 0x88, /* pll_multiplier_lsb REG=0x0307 */
226 0x0a, /* vt_pix_clk_div REG=0x0301 */
227 0x01, /* vt_sys_clk_div REG=0x0303 */
228 0x0a, /* op_pix_clk_div REG=0x0309 */
229 0x01, /* op_sys_clk_div REG=0x030B */
230 0x0a, /* ccp_data_format_msb REG=0x0112 */
231 0x0a, /* ccp_data_format_lsb REG=0x0113 */
232 0x0a, /* x_output_size_msb REG=0x034C */
233 0x30, /* x_output_size_lsb REG=0x034D */
234 0x07, /* y_output_size_msb REG=0x034E */
235 0xa8, /* y_output_size_lsb REG=0x034F */
236
237 /* disable binning for snapshot */
238 0x01, /* x_even_inc REG=0x0381 */
239 0x01, /* x_odd_inc REG=0x0383 */
240 0x01, /* y_even_inc REG=0x0385 */
241 0x01, /* y_odd_inc REG=0x0387 */
242 0x00, /* binning_enable REG=0x3014 */
243
244 0x07, /* frame_length_lines_msb REG=0x0340 */
245 0xb6, /* frame_length_lines_lsb REG=0x0341 */
246 0x0a, /* line_length_pck_msb REG=0x0342 */
247 0xac, /* line_length_pck_lsb REG=0x0343 */
248 0x81, /* shade_clk_enable REG=0x30AC */
249 0x01, /* sel_ccp REG=0x30C4 */
250 0x04, /* vpix REG=0x3024 */
251 0x00, /* clamp_on REG=0x3015 */
252 0x02, /* offset REG=0x307E */
253 0x03, /* ld_start REG=0x3000 */
254 0x9c, /* ld_end REG=0x3001 */
255 0x02, /* sl_start REG=0x3002 */
256 0x9e, /* sl_end REG=0x3003 */
257 0x05, /* rx_start REG=0x3004 */
258 0x0f, /* s1_start REG=0x3005 */
259 0x24, /* s1_end REG=0x3006 */
260 0x7c, /* s1s_start REG=0x3007 */
261 0x9a, /* s1s_end REG=0x3008 */
262 0x10, /* s3_start REG=0x3009 */
263 0x14, /* s3_end REG=0x300A */
264 0x10, /* cmp_en_start REG=0x300B */
265 0x04, /* clp_sl_start REG=0x300C */
266 0x26, /* clp_sl_end REG=0x300D */
267 0x02, /* off_start REG=0x300E */
268 0x0e, /* rmp_en_start REG=0x300F */
269 0x30, /* tx_start REG=0x3010 */
270 0x4e, /* tx_end REG=0x3011 */
271 0x1E, /* stx_width REG=0x3012 */
272 0x08, /* reg_3152_reserved REG=0x3152 */
273 0x10, /* reg_315A_reserved REG=0x315A */
274 0x00, /* analogue_gain_code_global_msb REG=0x0204 */
275 0x80, /* analogue_gain_code_global_lsb REG=0x0205 */
276 0x02, /* fine_integration_time REG=0x0200 */
277 0x03, /* coarse_integration_time REG=0x0202 */
278 1960,
279 14,
280 2608,
281 124
282 }
283};
284
285struct s5k3e2fx_work {
286 struct work_struct work;
287};
288static struct s5k3e2fx_work *s5k3e2fx_sensorw;
289static struct i2c_client *s5k3e2fx_client;
290
291struct s5k3e2fx_ctrl {
292 const struct msm_camera_sensor_info *sensordata;
293
294 int sensormode;
295 uint32_t fps_divider; /* init to 1 * 0x00000400 */
296 uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
297
298 uint16_t curr_lens_pos;
299 uint16_t init_curr_lens_pos;
300 uint16_t my_reg_gain;
301 uint32_t my_reg_line_count;
302
303 enum msm_s_resolution prev_res;
304 enum msm_s_resolution pict_res;
305 enum msm_s_resolution curr_res;
306 enum msm_s_test_mode set_test;
307};
308
309struct s5k3e2fx_i2c_reg_conf {
310 unsigned short waddr;
311 unsigned char bdata;
312};
313
314static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl;
315static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue);
316DECLARE_MUTEX(s5k3e2fx_sem);
317
318static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
319 int length)
320{
321 struct i2c_msg msgs[] = {
322 {
323 .addr = saddr,
324 .flags = 0,
325 .len = 2,
326 .buf = rxdata,
327 },
328 {
329 .addr = saddr,
330 .flags = I2C_M_RD,
331 .len = length,
332 .buf = rxdata,
333 },
334 };
335
336 if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) {
337 CDBG("s5k3e2fx_i2c_rxdata failed!\n");
338 return -EIO;
339 }
340
341 return 0;
342}
343
344static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr,
345 unsigned char *txdata, int length)
346{
347 struct i2c_msg msg[] = {
348 {
349 .addr = saddr,
350 .flags = 0,
351 .len = length,
352 .buf = txdata,
353 },
354 };
355
356 if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) {
357 CDBG("s5k3e2fx_i2c_txdata failed\n");
358 return -EIO;
359 }
360
361 return 0;
362}
363
364static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr,
365 unsigned char bdata)
366{
367 int32_t rc = -EIO;
368 unsigned char buf[4];
369
370 memset(buf, 0, sizeof(buf));
371 buf[0] = (waddr & 0xFF00)>>8;
372 buf[1] = (waddr & 0x00FF);
373 buf[2] = bdata;
374
375 rc = s5k3e2fx_i2c_txdata(saddr, buf, 3);
376
377 if (rc < 0)
378 CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
379 waddr, bdata);
380
381 return rc;
382}
383
384static int32_t s5k3e2fx_i2c_write_table(
385 struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num)
386{
387 int i;
388 int32_t rc = -EIO;
389 for (i = 0; i < num; i++) {
390 if (rc < 0)
391 break;
392 reg_cfg_tbl++;
393 }
394
395 return rc;
396}
397
398static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr,
399 unsigned short *rdata)
400{
401 int32_t rc = 0;
402 unsigned char buf[4];
403
404 if (!rdata)
405 return -EIO;
406
407 memset(buf, 0, sizeof(buf));
408
409 buf[0] = (raddr & 0xFF00)>>8;
410 buf[1] = (raddr & 0x00FF);
411
412 rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2);
413 if (rc < 0)
414 return rc;
415
416 *rdata = buf[0] << 8 | buf[1];
417
418 if (rc < 0)
419 CDBG("s5k3e2fx_i2c_read failed!\n");
420
421 return rc;
422}
423
424static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data)
425{
426 gpio_direction_output(data->sensor_reset, 0);
427 gpio_free(data->sensor_reset);
428 return 0;
429}
430
431static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data)
432{
433 int32_t rc;
434 uint16_t chipid = 0;
435
436 rc = gpio_request(data->sensor_reset, "s5k3e2fx");
437 if (!rc)
438 gpio_direction_output(data->sensor_reset, 1);
439 else
440 goto init_probe_done;
441
442 mdelay(20);
443
444 CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n");
445
446 rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr,
447 S5K3E2FX_REG_MODEL_ID, &chipid);
448 if (rc < 0)
449 goto init_probe_fail;
450
451 if (chipid != S5K3E2FX_MODEL_ID) {
452 CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid);
453 rc = -ENODEV;
454 goto init_probe_fail;
455 }
456
457 goto init_probe_done;
458
459init_probe_fail:
460 s5k3e2fx_probe_init_done(data);
461init_probe_done:
462 return rc;
463}
464
465static int s5k3e2fx_init_client(struct i2c_client *client)
466{
467 /* Initialize the MSM_CAMI2C Chip */
468 init_waitqueue_head(&s5k3e2fx_wait_queue);
469 return 0;
470}
471
472static const struct i2c_device_id s5k3e2fx_i2c_id[] = {
473 { "s5k3e2fx", 0},
474 { }
475};
476
477static int s5k3e2fx_i2c_probe(struct i2c_client *client,
478 const struct i2c_device_id *id)
479{
480 int rc = 0;
481 CDBG("s5k3e2fx_probe called!\n");
482
483 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
484 CDBG("i2c_check_functionality failed\n");
485 goto probe_failure;
486 }
487
488 s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL);
489 if (!s5k3e2fx_sensorw) {
490 CDBG("kzalloc failed.\n");
491 rc = -ENOMEM;
492 goto probe_failure;
493 }
494
495 i2c_set_clientdata(client, s5k3e2fx_sensorw);
496 s5k3e2fx_init_client(client);
497 s5k3e2fx_client = client;
498
499 mdelay(50);
500
501 CDBG("s5k3e2fx_probe successed! rc = %d\n", rc);
502 return 0;
503
504probe_failure:
505 CDBG("s5k3e2fx_probe failed! rc = %d\n", rc);
506 return rc;
507}
508
509static struct i2c_driver s5k3e2fx_i2c_driver = {
510 .id_table = s5k3e2fx_i2c_id,
511 .probe = s5k3e2fx_i2c_probe,
512 .remove = __exit_p(s5k3e2fx_i2c_remove),
513 .driver = {
514 .name = "s5k3e2fx",
515 },
516};
517
518static int32_t s5k3e2fx_test(enum msm_s_test_mode mo)
519{
520 int32_t rc = 0;
521
522 if (mo == S_TEST_OFF)
523 rc = 0;
524 else
525 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
526 REG_TEST_PATTERN_MODE, (uint16_t)mo);
527
528 return rc;
529}
530
531static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate,
532 enum msm_s_setting rt)
533{
534 int32_t rc = 0;
535 uint16_t num_lperf;
536
537 switch (rupdate) {
538 case S_UPDATE_PERIODIC:
539 if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
540
541 struct s5k3e2fx_i2c_reg_conf tbl_1[] = {
542 {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
543 {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
544 {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
545 {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
546 {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
547 {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
548 {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
549 {REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc},
550 {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
551 {REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
552 {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
553 };
554
555 struct s5k3e2fx_i2c_reg_conf tbl_2[] = {
556 {REG_FRAME_LENGTH_LINES_MSB, 0},
557 {REG_FRAME_LENGTH_LINES_LSB, 0},
558 {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
559 {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
560 {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
561 {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
562 {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
563 {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
564 {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
565 {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
566 {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
567 {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
568 {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
569 {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
570 {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
571 {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
572 {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
573 {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
574 {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
575 {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
576 {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
577 {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
578 {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
579 {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
580 {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
581 {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
582 {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
583 {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
584 {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
585 {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
586 {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
587 {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
588 {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
589 {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
590 {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
591 };
592
593 rc = s5k3e2fx_i2c_write_table(&tbl_1[0],
594 ARRAY_SIZE(tbl_1));
595 if (rc < 0)
596 return rc;
597
598 num_lperf =
599 (uint16_t)((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8) & 0xFF00) +
600 s5k3e2fx_reg_pat[rt].frame_length_lines_lsb;
601
602 num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400;
603
604 tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8};
605 tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)};
606
607 rc = s5k3e2fx_i2c_write_table(&tbl_2[0],
608 ARRAY_SIZE(tbl_2));
609 if (rc < 0)
610 return rc;
611
612 mdelay(5);
613
614 rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test);
615 if (rc < 0)
616 return rc;
617 }
618 break; /* UPDATE_PERIODIC */
619
620 case S_REG_INIT:
621 if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
622
623 struct s5k3e2fx_i2c_reg_conf tbl_3[] = {
624 {S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET},
625 {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_SW_STANDBY},
626 /* PLL setting */
627 {REG_PRE_PLL_CLK_DIV, s5k3e2fx_reg_pat[rt].pre_pll_clk_div},
628 {REG_PLL_MULTIPLIER_MSB, s5k3e2fx_reg_pat[rt].pll_multiplier_msb},
629 {REG_PLL_MULTIPLIER_LSB, s5k3e2fx_reg_pat[rt].pll_multiplier_lsb},
630 {REG_VT_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_pix_clk_div},
631 {REG_VT_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_sys_clk_div},
632 {REG_OP_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].op_pix_clk_div},
633 {REG_OP_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].op_sys_clk_div},
634 /*Data Format */
635 {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
636 {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
637 /*Output Size */
638 {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
639 {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
640 {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
641 {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
642 /* Binning */
643 {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
644 {REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc },
645 {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
646 {REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
647 {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
648 /* Frame format */
649 {REG_FRAME_LENGTH_LINES_MSB, s5k3e2fx_reg_pat[rt].frame_length_lines_msb},
650 {REG_FRAME_LENGTH_LINES_LSB, s5k3e2fx_reg_pat[rt].frame_length_lines_lsb},
651 {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
652 {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
653 /* MSR setting */
654 {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
655 {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
656 {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
657 {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
658 {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
659 /* CDS timing setting */
660 {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
661 {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
662 {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
663 {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
664 {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
665 {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
666 {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
667 {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
668 {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
669 {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
670 {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
671 {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
672 {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
673 {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
674 {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
675 {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
676 {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
677 {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
678 {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
679 {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
680 {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
681 {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
682 {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
683 {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
684 {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
685 {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
686 };
687
688 /* reset fps_divider */
689 s5k3e2fx_ctrl->fps_divider = 1 * 0x0400;
690 rc = s5k3e2fx_i2c_write_table(&tbl_3[0],
691 ARRAY_SIZE(tbl_3));
692 if (rc < 0)
693 return rc;
694 }
695 break; /* case REG_INIT: */
696
697 default:
698 rc = -EINVAL;
699 break;
700 } /* switch (rupdate) */
701
702 return rc;
703}
704
705static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
706{
707 int32_t rc;
708
709 s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL);
710 if (!s5k3e2fx_ctrl) {
711 CDBG("s5k3e2fx_init failed!\n");
712 rc = -ENOMEM;
713 goto init_done;
714 }
715
716 s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400;
717 s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400;
718 s5k3e2fx_ctrl->set_test = S_TEST_OFF;
719 s5k3e2fx_ctrl->prev_res = S_QTR_SIZE;
720 s5k3e2fx_ctrl->pict_res = S_FULL_SIZE;
721
722 if (data)
723 s5k3e2fx_ctrl->sensordata = data;
724
725 /* enable mclk first */
726 msm_camio_clk_rate_set(24000000);
727 mdelay(20);
728
729 msm_camio_camif_pad_reg_reset();
730 mdelay(20);
731
732 rc = s5k3e2fx_probe_init_sensor(data);
733 if (rc < 0)
734 goto init_fail1;
735
736 if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE)
737 rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW);
738 else
739 rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE);
740
741 if (rc < 0) {
742 CDBG("s5k3e2fx_setting failed. rc = %d\n", rc);
743 goto init_fail1;
744 }
745
746 /* initialize AF */
747 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A);
748 if (rc < 0)
749 goto init_fail1;
750
751 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03);
752 if (rc < 0)
753 goto init_fail1;
754
755 goto init_done;
756
757init_fail1:
758 s5k3e2fx_probe_init_done(data);
759 kfree(s5k3e2fx_ctrl);
760init_done:
761 return rc;
762}
763
764static int32_t s5k3e2fx_power_down(void)
765{
766 int32_t rc = 0;
767 return rc;
768}
769
770static int s5k3e2fx_sensor_release(void)
771{
772 int rc = -EBADF;
773
774 down(&s5k3e2fx_sem);
775
776 s5k3e2fx_power_down();
777
778 gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset,
779 0);
780 gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset);
781
782 kfree(s5k3e2fx_ctrl);
783 s5k3e2fx_ctrl = NULL;
784
785 CDBG("s5k3e2fx_release completed\n");
786
787 up(&s5k3e2fx_sem);
788 return rc;
789}
790
791static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps)
792{
793 /* input fps is preview fps in Q8 format */
794 uint32_t divider; /* Q10 */
795
796 divider = (uint32_t)
797 ((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
798 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
799 (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
800 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 /
801 ((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
802 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) *
803 (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
804 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p));
805
806 /* Verify PCLK settings and frame sizes. */
807 *pfps = (uint16_t)(fps * divider / 0x00000400);
808}
809
810static uint16_t s5k3e2fx_get_prev_lines_pf(void)
811{
812 return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
813 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l);
814}
815
816static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
817{
818 return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
819 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
820}
821
822static uint16_t s5k3e2fx_get_pict_lines_pf(void)
823{
824 return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
825 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
826}
827
828static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
829{
830 return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
831 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
832}
833
834static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
835{
836 uint32_t snapshot_lines_per_frame;
837
838 if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE)
839 snapshot_lines_per_frame =
840 s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
841 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
842 else
843 snapshot_lines_per_frame = 3961 * 3;
844
845 return snapshot_lines_per_frame;
846}
847
848static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps)
849{
850 /* input is new fps in Q10 format */
851 int32_t rc = 0;
852
853 s5k3e2fx_ctrl->fps_divider = fps->fps_div;
854
855 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
856 REG_FRAME_LENGTH_LINES_MSB,
857 (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
858 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
859 s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8);
860 if (rc < 0)
861 goto set_fps_done;
862
863 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
864 REG_FRAME_LENGTH_LINES_LSB,
865 (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
866 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
867 s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00));
868
869set_fps_done:
870 return rc;
871}
872
873static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line)
874{
875 int32_t rc = 0;
876
877 uint16_t max_legal_gain = 0x0200;
878 uint32_t ll_ratio; /* Q10 */
879 uint16_t ll_pck, fl_lines;
880 uint16_t offset = 4;
881 uint8_t gain_msb, gain_lsb;
882 uint8_t intg_t_msb, intg_t_lsb;
883 uint8_t ll_pck_msb, ll_pck_lsb, tmp;
884
885 struct s5k3e2fx_i2c_reg_conf tbl[2];
886
887 CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__);
888
889 if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
890
891 s5k3e2fx_ctrl->my_reg_gain = gain;
892 s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line;
893
894 fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
895 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
896
897 ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
898 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
899
900 } else {
901
902 fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
903 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
904
905 ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
906 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
907 }
908
909 if (gain > max_legal_gain)
910 gain = max_legal_gain;
911
912 /* in Q10 */
913 line = (line * s5k3e2fx_ctrl->fps_divider);
914
915 if (fl_lines < (line / 0x400))
916 ll_ratio = (line / (fl_lines - offset));
917 else
918 ll_ratio = 0x400;
919
920 /* update gain registers */
921 gain_msb = (gain & 0xFF00) >> 8;
922 gain_lsb = gain & 0x00FF;
923 tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB;
924 tbl[0].bdata = gain_msb;
925 tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB;
926 tbl[1].bdata = gain_lsb;
927 rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
928 if (rc < 0)
929 goto write_gain_done;
930
931 ll_pck = ll_pck * ll_ratio;
932 ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8;
933 ll_pck_lsb = (ll_pck / 0x400) & 0x00FF;
934 tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB;
935 tbl[0].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_msb;
936 tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB;
937 tbl[1].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_lsb;
938 rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
939 if (rc < 0)
940 goto write_gain_done;
941
942 tmp = (ll_pck * 0x400) / ll_ratio;
943 intg_t_msb = (tmp & 0xFF00) >> 8;
944 intg_t_lsb = (tmp & 0x00FF);
945 tbl[0].waddr = REG_COARSE_INTEGRATION_TIME;
946 tbl[0].bdata = intg_t_msb;
947 tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB;
948 tbl[1].bdata = intg_t_lsb;
949 rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
950
951write_gain_done:
952 return rc;
953}
954
955static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line)
956{
957 int32_t rc = 0;
958
959 CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__);
960
961 rc =
962 s5k3e2fx_write_exp_gain(gain, line);
963
964 return rc;
965}
966
967static int32_t s5k3e2fx_video_config(int mode, int res)
968{
969 int32_t rc;
970
971 switch (res) {
972 case S_QTR_SIZE:
973 rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
974 if (rc < 0)
975 return rc;
976
977 CDBG("s5k3e2fx sensor configuration done!\n");
978 break;
979
980 case S_FULL_SIZE:
981 rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
982 if (rc < 0)
983 return rc;
984
985 break;
986
987 default:
988 return 0;
989 } /* switch */
990
991 s5k3e2fx_ctrl->prev_res = res;
992 s5k3e2fx_ctrl->curr_res = res;
993 s5k3e2fx_ctrl->sensormode = mode;
994
995 rc =
996 s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain,
997 s5k3e2fx_ctrl->my_reg_line_count);
998
999 return rc;
1000}
1001
1002static int32_t s5k3e2fx_snapshot_config(int mode)
1003{
1004 int32_t rc = 0;
1005
1006 rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
1007 if (rc < 0)
1008 return rc;
1009
1010 s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
1011 s5k3e2fx_ctrl->sensormode = mode;
1012
1013 return rc;
1014}
1015
1016static int32_t s5k3e2fx_raw_snapshot_config(int mode)
1017{
1018 int32_t rc = 0;
1019
1020 rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
1021 if (rc < 0)
1022 return rc;
1023
1024 s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
1025 s5k3e2fx_ctrl->sensormode = mode;
1026
1027 return rc;
1028}
1029
1030static int32_t s5k3e2fx_set_sensor_mode(int mode, int res)
1031{
1032 int32_t rc = 0;
1033
1034 switch (mode) {
1035 case SENSOR_PREVIEW_MODE:
1036 rc = s5k3e2fx_video_config(mode, res);
1037 break;
1038
1039 case SENSOR_SNAPSHOT_MODE:
1040 rc = s5k3e2fx_snapshot_config(mode);
1041 break;
1042
1043 case SENSOR_RAW_SNAPSHOT_MODE:
1044 rc = s5k3e2fx_raw_snapshot_config(mode);
1045 break;
1046
1047 default:
1048 rc = -EINVAL;
1049 break;
1050 }
1051
1052 return rc;
1053}
1054
1055static int32_t s5k3e2fx_set_default_focus(void)
1056{
1057 int32_t rc = 0;
1058
1059 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
1060 0x3131, 0);
1061 if (rc < 0)
1062 return rc;
1063
1064 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
1065 0x3132, 0);
1066 if (rc < 0)
1067 return rc;
1068
1069 s5k3e2fx_ctrl->curr_lens_pos = 0;
1070
1071 return rc;
1072}
1073
1074static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
1075{
1076 int32_t rc = 0;
1077 int32_t i;
1078 int16_t step_direction;
1079 int16_t actual_step;
1080 int16_t next_pos, pos_offset;
1081 int16_t init_code = 50;
1082 uint8_t next_pos_msb, next_pos_lsb;
1083 int16_t s_move[5];
1084 uint32_t gain; /* Q10 format */
1085
1086 if (direction == MOVE_NEAR)
1087 step_direction = 20;
1088 else if (direction == MOVE_FAR)
1089 step_direction = -20;
1090 else {
1091 CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__);
1092 return -EINVAL;
1093 }
1094
1095 actual_step = step_direction * (int16_t)num_steps;
1096 pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
1097 gain = ((actual_step << 10) / 5) >> 10;
1098
1099 for (i = 0; i <= 4; i++)
1100 s_move[i] = gain;
1101
1102 /* Ring Damping Code */
1103 for (i = 0; i <= 4; i++) {
1104 next_pos = (int16_t)(pos_offset + s_move[i]);
1105
1106 if (next_pos > (738 + init_code))
1107 next_pos = 738 + init_code;
1108 else if (next_pos < 0)
1109 next_pos = 0;
1110
1111 CDBG("next_position in damping mode = %d\n", next_pos);
1112 /* Writing the Values to the actuator */
1113 if (next_pos == init_code)
1114 next_pos = 0x00;
1115
1116 next_pos_msb = next_pos >> 8;
1117 next_pos_lsb = next_pos & 0x00FF;
1118
1119 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3131, next_pos_msb);
1120 if (rc < 0)
1121 break;
1122
1123 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3132, next_pos_lsb);
1124 if (rc < 0)
1125 break;
1126
1127 pos_offset = next_pos;
1128 s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code;
1129 if (i < 4)
1130 mdelay(3);
1131 }
1132
1133 return rc;
1134}
1135
1136static int s5k3e2fx_sensor_config(void __user *argp)
1137{
1138 struct sensor_cfg_data cdata;
1139 long rc = 0;
1140
1141 if (copy_from_user(&cdata,
1142 (void *)argp,
1143 sizeof(struct sensor_cfg_data)))
1144 return -EFAULT;
1145
1146 down(&s5k3e2fx_sem);
1147
1148 CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
1149 switch (cdata.cfgtype) {
1150 case CFG_GET_PICT_FPS:
1151 s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps,
1152 &(cdata.cfg.gfps.pictfps));
1153
1154 if (copy_to_user((void *)argp, &cdata,
1155 sizeof(struct sensor_cfg_data)))
1156 rc = -EFAULT;
1157 break;
1158
1159 case CFG_GET_PREV_L_PF:
1160 cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf();
1161
1162 if (copy_to_user((void *)argp,
1163 &cdata,
1164 sizeof(struct sensor_cfg_data)))
1165 rc = -EFAULT;
1166 break;
1167
1168 case CFG_GET_PREV_P_PL:
1169 cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl();
1170
1171 if (copy_to_user((void *)argp,
1172 &cdata,
1173 sizeof(struct sensor_cfg_data)))
1174 rc = -EFAULT;
1175 break;
1176
1177 case CFG_GET_PICT_L_PF:
1178 cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf();
1179
1180 if (copy_to_user((void *)argp,
1181 &cdata,
1182 sizeof(struct sensor_cfg_data)))
1183 rc = -EFAULT;
1184 break;
1185
1186 case CFG_GET_PICT_P_PL:
1187 cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl();
1188
1189 if (copy_to_user((void *)argp,
1190 &cdata,
1191 sizeof(struct sensor_cfg_data)))
1192 rc = -EFAULT;
1193 break;
1194
1195 case CFG_GET_PICT_MAX_EXP_LC:
1196 cdata.cfg.pict_max_exp_lc =
1197 s5k3e2fx_get_pict_max_exp_lc();
1198
1199 if (copy_to_user((void *)argp,
1200 &cdata,
1201 sizeof(struct sensor_cfg_data)))
1202 rc = -EFAULT;
1203 break;
1204
1205 case CFG_SET_FPS:
1206 case CFG_SET_PICT_FPS:
1207 rc = s5k3e2fx_set_fps(&(cdata.cfg.fps));
1208 break;
1209
1210 case CFG_SET_EXP_GAIN:
1211 rc =
1212 s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain,
1213 cdata.cfg.exp_gain.line);
1214 break;
1215
1216 case CFG_SET_PICT_EXP_GAIN:
1217 CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
1218 rc =
1219 s5k3e2fx_set_pict_exp_gain(
1220 cdata.cfg.exp_gain.gain,
1221 cdata.cfg.exp_gain.line);
1222 break;
1223
1224 case CFG_SET_MODE:
1225 rc =
1226 s5k3e2fx_set_sensor_mode(
1227 cdata.mode, cdata.rs);
1228 break;
1229
1230 case CFG_PWR_DOWN:
1231 rc = s5k3e2fx_power_down();
1232 break;
1233
1234 case CFG_MOVE_FOCUS:
1235 rc =
1236 s5k3e2fx_move_focus(
1237 cdata.cfg.focus.dir,
1238 cdata.cfg.focus.steps);
1239 break;
1240
1241 case CFG_SET_DEFAULT_FOCUS:
1242 rc =
1243 s5k3e2fx_set_default_focus();
1244 break;
1245
1246 case CFG_GET_AF_MAX_STEPS:
1247 case CFG_SET_EFFECT:
1248 case CFG_SET_LENS_SHADING:
1249 default:
1250 rc = -EINVAL;
1251 break;
1252 }
1253
1254 up(&s5k3e2fx_sem);
1255 return rc;
1256}
1257
1258static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info,
1259 struct msm_sensor_ctrl *s)
1260{
1261 int rc = 0;
1262
1263 rc = i2c_add_driver(&s5k3e2fx_i2c_driver);
1264 if (rc < 0 || s5k3e2fx_client == NULL) {
1265 rc = -ENOTSUPP;
1266 goto probe_fail;
1267 }
1268
1269 msm_camio_clk_rate_set(24000000);
1270 mdelay(20);
1271
1272 rc = s5k3e2fx_probe_init_sensor(info);
1273 if (rc < 0)
1274 goto probe_fail;
1275
1276 s->s_init = s5k3e2fx_sensor_open_init;
1277 s->s_release = s5k3e2fx_sensor_release;
1278 s->s_config = s5k3e2fx_sensor_config;
1279 s5k3e2fx_probe_init_done(info);
1280
1281 return rc;
1282
1283probe_fail:
1284 CDBG("SENSOR PROBE FAILS!\n");
1285 return rc;
1286}
1287
1288static int __s5k3e2fx_probe(struct platform_device *pdev)
1289{
1290 return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe);
1291}
1292
1293static struct platform_driver msm_camera_driver = {
1294 .probe = __s5k3e2fx_probe,
1295 .driver = {
1296 .name = "msm_camera_s5k3e2fx",
1297 .owner = THIS_MODULE,
1298 },
1299};
1300
1301static int __init s5k3e2fx_init(void)
1302{
1303 return platform_driver_register(&msm_camera_driver);
1304}
1305
1306module_init(s5k3e2fx_init);
1307
diff --git a/drivers/staging/dream/camera/s5k3e2fx.h b/drivers/staging/dream/camera/s5k3e2fx.h
deleted file mode 100644
index 69bc75084457..000000000000
--- a/drivers/staging/dream/camera/s5k3e2fx.h
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef CAMSENSOR_S5K3E2FX
6#define CAMSENSOR_S5K3E2FX
7
8#include <mach/board.h>
9#endif /* CAMSENSOR_S5K3E2FX */
diff --git a/drivers/staging/dream/generic_gpio.c b/drivers/staging/dream/generic_gpio.c
deleted file mode 100644
index fe24d38345d0..000000000000
--- a/drivers/staging/dream/generic_gpio.c
+++ /dev/null
@@ -1,274 +0,0 @@
1/* arch/arm/mach-msm/generic_gpio.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/errno.h>
19#include <linux/slab.h>
20#include <linux/spinlock.h>
21#include <asm/gpio.h>
22#include "gpio_chip.h"
23
24#define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5)
25
26struct gpio_state {
27 unsigned long flags;
28 int refcount;
29};
30
31static DEFINE_SPINLOCK(gpio_chips_lock);
32static LIST_HEAD(gpio_chip_list);
33static struct gpio_chip **gpio_chip_array;
34static unsigned long gpio_chip_array_size;
35
36int register_gpio_chip(struct gpio_chip *new_gpio_chip)
37{
38 int err = 0;
39 struct gpio_chip *gpio_chip;
40 int i;
41 unsigned long irq_flags;
42 unsigned int chip_array_start_index, chip_array_end_index;
43
44 new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL);
45 if (new_gpio_chip->state == NULL) {
46 printk(KERN_ERR "register_gpio_chip: failed to allocate state\n");
47 return -ENOMEM;
48 }
49
50 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
51 chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start);
52 chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end);
53 if (chip_array_end_index >= gpio_chip_array_size) {
54 struct gpio_chip **new_gpio_chip_array;
55 unsigned long new_gpio_chip_array_size = chip_array_end_index + 1;
56
57 new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC);
58 if (new_gpio_chip_array == NULL) {
59 printk(KERN_ERR "register_gpio_chip: failed to allocate array\n");
60 err = -ENOMEM;
61 goto failed;
62 }
63 for (i = 0; i < gpio_chip_array_size; i++)
64 new_gpio_chip_array[i] = gpio_chip_array[i];
65 for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++)
66 new_gpio_chip_array[i] = NULL;
67 gpio_chip_array = new_gpio_chip_array;
68 gpio_chip_array_size = new_gpio_chip_array_size;
69 }
70 list_for_each_entry(gpio_chip, &gpio_chip_list, list) {
71 if (gpio_chip->start > new_gpio_chip->end) {
72 list_add_tail(&new_gpio_chip->list, &gpio_chip->list);
73 goto added;
74 }
75 if (gpio_chip->end >= new_gpio_chip->start) {
76 printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n",
77 new_gpio_chip->start, new_gpio_chip->end,
78 gpio_chip->start, gpio_chip->end);
79 err = -EBUSY;
80 goto failed;
81 }
82 }
83 list_add_tail(&new_gpio_chip->list, &gpio_chip_list);
84added:
85 for (i = chip_array_start_index; i <= chip_array_end_index; i++) {
86 if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start)
87 gpio_chip_array[i] = new_gpio_chip;
88 }
89failed:
90 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
91 if (err)
92 kfree(new_gpio_chip->state);
93 return err;
94}
95
96static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio)
97{
98 unsigned long i;
99 struct gpio_chip *chip;
100
101 i = GPIO_NUM_TO_CHIP_INDEX(gpio);
102 if (i >= gpio_chip_array_size)
103 return NULL;
104 chip = gpio_chip_array[i];
105 if (chip == NULL)
106 return NULL;
107 list_for_each_entry_from(chip, &gpio_chip_list, list) {
108 if (gpio < chip->start)
109 return NULL;
110 if (gpio <= chip->end)
111 return chip;
112 }
113 return NULL;
114}
115
116static int request_gpio(unsigned int gpio, unsigned long flags)
117{
118 int err = 0;
119 struct gpio_chip *chip;
120 unsigned long irq_flags;
121 unsigned long chip_index;
122
123 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
124 chip = get_gpio_chip_locked(gpio);
125 if (chip == NULL) {
126 err = -EINVAL;
127 goto err;
128 }
129 chip_index = gpio - chip->start;
130 if (chip->state[chip_index].refcount == 0) {
131 chip->configure(chip, gpio, flags);
132 chip->state[chip_index].flags = flags;
133 chip->state[chip_index].refcount++;
134 } else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED))
135 chip->state[chip_index].refcount++;
136 else
137 err = -EBUSY;
138err:
139 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
140 return err;
141}
142
143int gpio_request(unsigned gpio, const char *label)
144{
145 return request_gpio(gpio, 0);
146}
147EXPORT_SYMBOL(gpio_request);
148
149void gpio_free(unsigned gpio)
150{
151 struct gpio_chip *chip;
152 unsigned long irq_flags;
153 unsigned long chip_index;
154
155 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
156 chip = get_gpio_chip_locked(gpio);
157 if (chip) {
158 chip_index = gpio - chip->start;
159 chip->state[chip_index].refcount--;
160 }
161 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
162}
163EXPORT_SYMBOL(gpio_free);
164
165static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp)
166{
167 int ret = -ENOTSUPP;
168 struct gpio_chip *chip;
169 unsigned long irq_flags;
170
171 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
172 chip = get_gpio_chip_locked(gpio);
173 if (chip && chip->get_irq_num)
174 ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp);
175 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
176 return ret;
177}
178
179int gpio_to_irq(unsigned gpio)
180{
181 int ret, irq;
182 ret = gpio_get_irq_num(gpio, &irq, NULL);
183 if (ret)
184 return ret;
185 return irq;
186}
187EXPORT_SYMBOL(gpio_to_irq);
188
189int gpio_configure(unsigned int gpio, unsigned long flags)
190{
191 int ret = -ENOTSUPP;
192 struct gpio_chip *chip;
193 unsigned long irq_flags;
194
195 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
196 chip = get_gpio_chip_locked(gpio);
197 if (chip)
198 ret = chip->configure(chip, gpio, flags);
199 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
200 return ret;
201}
202EXPORT_SYMBOL(gpio_configure);
203
204int gpio_direction_input(unsigned gpio)
205{
206 return gpio_configure(gpio, GPIOF_INPUT);
207}
208EXPORT_SYMBOL(gpio_direction_input);
209
210int gpio_direction_output(unsigned gpio, int value)
211{
212 gpio_set_value(gpio, value);
213 return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT);
214}
215EXPORT_SYMBOL(gpio_direction_output);
216
217int gpio_get_value(unsigned gpio)
218{
219 int ret = -ENOTSUPP;
220 struct gpio_chip *chip;
221 unsigned long irq_flags;
222
223 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
224 chip = get_gpio_chip_locked(gpio);
225 if (chip && chip->read)
226 ret = chip->read(chip, gpio);
227 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
228 return ret;
229}
230EXPORT_SYMBOL(gpio_get_value);
231
232void gpio_set_value(unsigned gpio, int on)
233{
234 int ret = -ENOTSUPP;
235 struct gpio_chip *chip;
236 unsigned long irq_flags;
237
238 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
239 chip = get_gpio_chip_locked(gpio);
240 if (chip && chip->write)
241 ret = chip->write(chip, gpio, on);
242 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
243}
244EXPORT_SYMBOL(gpio_set_value);
245
246int gpio_read_detect_status(unsigned int gpio)
247{
248 int ret = -ENOTSUPP;
249 struct gpio_chip *chip;
250 unsigned long irq_flags;
251
252 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
253 chip = get_gpio_chip_locked(gpio);
254 if (chip && chip->read_detect_status)
255 ret = chip->read_detect_status(chip, gpio);
256 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
257 return ret;
258}
259EXPORT_SYMBOL(gpio_read_detect_status);
260
261int gpio_clear_detect_status(unsigned int gpio)
262{
263 int ret = -ENOTSUPP;
264 struct gpio_chip *chip;
265 unsigned long irq_flags;
266
267 spin_lock_irqsave(&gpio_chips_lock, irq_flags);
268 chip = get_gpio_chip_locked(gpio);
269 if (chip && chip->clear_detect_status)
270 ret = chip->clear_detect_status(chip, gpio);
271 spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
272 return ret;
273}
274EXPORT_SYMBOL(gpio_clear_detect_status);
diff --git a/drivers/staging/dream/gpio_axis.c b/drivers/staging/dream/gpio_axis.c
deleted file mode 100644
index eb54724b1d3a..000000000000
--- a/drivers/staging/dream/gpio_axis.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/* drivers/input/misc/gpio_axis.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/gpio.h>
19#include <linux/gpio_event.h>
20#include <linux/interrupt.h>
21
22struct gpio_axis_state {
23 struct input_dev *input_dev;
24 struct gpio_event_axis_info *info;
25 uint32_t pos;
26};
27
28uint16_t gpio_axis_4bit_gray_map_table[] = {
29 [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */
30 [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */
31 [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */
32 [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */
33 [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */
34 [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */
35 [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */
36 [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */
37};
38uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in)
39{
40 return gpio_axis_4bit_gray_map_table[in];
41}
42
43uint16_t gpio_axis_5bit_singletrack_map_table[] = {
44 [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */
45 [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */
46 [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */
47 [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */
48 [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */
49 [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */
50 [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */
51 [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */
52 [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */
53 [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */
54};
55uint16_t gpio_axis_5bit_singletrack_map(
56 struct gpio_event_axis_info *info, uint16_t in)
57{
58 return gpio_axis_5bit_singletrack_map_table[in];
59}
60
61static void gpio_event_update_axis(struct gpio_axis_state *as, int report)
62{
63 struct gpio_event_axis_info *ai = as->info;
64 int i;
65 int change;
66 uint16_t state = 0;
67 uint16_t pos;
68 uint16_t old_pos = as->pos;
69 for (i = ai->count - 1; i >= 0; i--)
70 state = (state << 1) | gpio_get_value(ai->gpio[i]);
71 pos = ai->map(ai, state);
72 if (ai->flags & GPIOEAF_PRINT_RAW)
73 pr_info("axis %d-%d raw %x, pos %d -> %d\n",
74 ai->type, ai->code, state, old_pos, pos);
75 if (report && pos != old_pos) {
76 if (ai->type == EV_REL) {
77 change = (ai->decoded_size + pos - old_pos) %
78 ai->decoded_size;
79 if (change > ai->decoded_size / 2)
80 change -= ai->decoded_size;
81 if (change == ai->decoded_size / 2) {
82 if (ai->flags & GPIOEAF_PRINT_EVENT)
83 pr_info("axis %d-%d unknown direction, "
84 "pos %d -> %d\n", ai->type,
85 ai->code, old_pos, pos);
86 change = 0; /* no closest direction */
87 }
88 if (ai->flags & GPIOEAF_PRINT_EVENT)
89 pr_info("axis %d-%d change %d\n",
90 ai->type, ai->code, change);
91 input_report_rel(as->input_dev, ai->code, change);
92 } else {
93 if (ai->flags & GPIOEAF_PRINT_EVENT)
94 pr_info("axis %d-%d now %d\n",
95 ai->type, ai->code, pos);
96 input_event(as->input_dev, ai->type, ai->code, pos);
97 }
98 input_sync(as->input_dev);
99 }
100 as->pos = pos;
101}
102
103static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id)
104{
105 struct gpio_axis_state *as = dev_id;
106 gpio_event_update_axis(as, 1);
107 return IRQ_HANDLED;
108}
109
110int gpio_event_axis_func(struct input_dev *input_dev,
111 struct gpio_event_info *info, void **data, int func)
112{
113 int ret;
114 int i;
115 int irq;
116 struct gpio_event_axis_info *ai;
117 struct gpio_axis_state *as;
118
119 ai = container_of(info, struct gpio_event_axis_info, info);
120 if (func == GPIO_EVENT_FUNC_SUSPEND) {
121 for (i = 0; i < ai->count; i++)
122 disable_irq(gpio_to_irq(ai->gpio[i]));
123 return 0;
124 }
125 if (func == GPIO_EVENT_FUNC_RESUME) {
126 for (i = 0; i < ai->count; i++)
127 enable_irq(gpio_to_irq(ai->gpio[i]));
128 return 0;
129 }
130
131 if (func == GPIO_EVENT_FUNC_INIT) {
132 *data = as = kmalloc(sizeof(*as), GFP_KERNEL);
133 if (as == NULL) {
134 ret = -ENOMEM;
135 goto err_alloc_axis_state_failed;
136 }
137 as->input_dev = input_dev;
138 as->info = ai;
139
140 input_set_capability(input_dev, ai->type, ai->code);
141 if (ai->type == EV_ABS) {
142 input_set_abs_params(input_dev, ai->code, 0,
143 ai->decoded_size - 1, 0, 0);
144 }
145 for (i = 0; i < ai->count; i++) {
146 ret = gpio_request(ai->gpio[i], "gpio_event_axis");
147 if (ret < 0)
148 goto err_request_gpio_failed;
149 ret = gpio_direction_input(ai->gpio[i]);
150 if (ret < 0)
151 goto err_gpio_direction_input_failed;
152 ret = irq = gpio_to_irq(ai->gpio[i]);
153 if (ret < 0)
154 goto err_get_irq_num_failed;
155 ret = request_irq(irq, gpio_axis_irq_handler,
156 IRQF_TRIGGER_RISING |
157 IRQF_TRIGGER_FALLING,
158 "gpio_event_axis", as);
159 if (ret < 0)
160 goto err_request_irq_failed;
161 }
162 gpio_event_update_axis(as, 0);
163 return 0;
164 }
165
166 ret = 0;
167 as = *data;
168 for (i = ai->count - 1; i >= 0; i--) {
169 free_irq(gpio_to_irq(ai->gpio[i]), as);
170err_request_irq_failed:
171err_get_irq_num_failed:
172err_gpio_direction_input_failed:
173 gpio_free(ai->gpio[i]);
174err_request_gpio_failed:
175 ;
176 }
177 kfree(as);
178 *data = NULL;
179err_alloc_axis_state_failed:
180 return ret;
181}
diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c
deleted file mode 100644
index 97a511d11f49..000000000000
--- a/drivers/staging/dream/gpio_event.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/* drivers/input/misc/gpio_event.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/input.h>
20#include <linux/gpio_event.h>
21#include <linux/hrtimer.h>
22#include <linux/platform_device.h>
23
24struct gpio_event {
25 struct input_dev *input_dev;
26 const struct gpio_event_platform_data *info;
27 void *state[0];
28};
29
30static int gpio_input_event(
31 struct input_dev *dev, unsigned int type, unsigned int code, int value)
32{
33 int i;
34 int ret = 0;
35 int tmp_ret;
36 struct gpio_event_info **ii;
37 struct gpio_event *ip = input_get_drvdata(dev);
38
39 for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
40 if ((*ii)->event) {
41 tmp_ret = (*ii)->event(ip->input_dev, *ii,
42 &ip->state[i], type, code, value);
43 if (tmp_ret)
44 ret = tmp_ret;
45 }
46 }
47 return ret;
48}
49
50static int gpio_event_call_all_func(struct gpio_event *ip, int func)
51{
52 int i;
53 int ret;
54 struct gpio_event_info **ii;
55
56 if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
57 ii = ip->info->info;
58 for (i = 0; i < ip->info->info_count; i++, ii++) {
59 if ((*ii)->func == NULL) {
60 ret = -ENODEV;
61 pr_err("gpio_event_probe: Incomplete pdata, "
62 "no function\n");
63 goto err_no_func;
64 }
65 ret = (*ii)->func(ip->input_dev, *ii, &ip->state[i],
66 func);
67 if (ret) {
68 pr_err("gpio_event_probe: function failed\n");
69 goto err_func_failed;
70 }
71 }
72 return 0;
73 }
74
75 ret = 0;
76 i = ip->info->info_count;
77 ii = ip->info->info + i;
78 while (i > 0) {
79 i--;
80 ii--;
81 (*ii)->func(ip->input_dev, *ii, &ip->state[i], func & ~1);
82err_func_failed:
83err_no_func:
84 ;
85 }
86 return ret;
87}
88
89#ifdef CONFIG_HAS_EARLYSUSPEND
90void gpio_event_suspend(struct early_suspend *h)
91{
92 struct gpio_event *ip;
93 ip = container_of(h, struct gpio_event, early_suspend);
94 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
95 ip->info->power(ip->info, 0);
96}
97
98void gpio_event_resume(struct early_suspend *h)
99{
100 struct gpio_event *ip;
101 ip = container_of(h, struct gpio_event, early_suspend);
102 ip->info->power(ip->info, 1);
103 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
104}
105#endif
106
107static int __init gpio_event_probe(struct platform_device *pdev)
108{
109 int err;
110 struct gpio_event *ip;
111 struct input_dev *input_dev;
112 struct gpio_event_platform_data *event_info;
113
114 event_info = pdev->dev.platform_data;
115 if (event_info == NULL) {
116 pr_err("gpio_event_probe: No pdata\n");
117 return -ENODEV;
118 }
119 if (event_info->name == NULL ||
120 event_info->info == NULL ||
121 event_info->info_count == 0) {
122 pr_err("gpio_event_probe: Incomplete pdata\n");
123 return -ENODEV;
124 }
125 ip = kzalloc(sizeof(*ip) +
126 sizeof(ip->state[0]) * event_info->info_count, GFP_KERNEL);
127 if (ip == NULL) {
128 err = -ENOMEM;
129 pr_err("gpio_event_probe: Failed to allocate private data\n");
130 goto err_kp_alloc_failed;
131 }
132 platform_set_drvdata(pdev, ip);
133
134 input_dev = input_allocate_device();
135 if (input_dev == NULL) {
136 err = -ENOMEM;
137 pr_err("gpio_event_probe: Failed to allocate input device\n");
138 goto err_input_dev_alloc_failed;
139 }
140 input_set_drvdata(input_dev, ip);
141 ip->input_dev = input_dev;
142 ip->info = event_info;
143 if (event_info->power) {
144#ifdef CONFIG_HAS_EARLYSUSPEND
145 ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
146 ip->early_suspend.suspend = gpio_event_suspend;
147 ip->early_suspend.resume = gpio_event_resume;
148 register_early_suspend(&ip->early_suspend);
149#endif
150 ip->info->power(ip->info, 1);
151 }
152
153 input_dev->name = ip->info->name;
154 input_dev->event = gpio_input_event;
155
156 err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
157 if (err)
158 goto err_call_all_func_failed;
159
160 err = input_register_device(input_dev);
161 if (err) {
162 pr_err("gpio_event_probe: Unable to register %s input device\n",
163 input_dev->name);
164 goto err_input_register_device_failed;
165 }
166
167 return 0;
168
169err_input_register_device_failed:
170 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
171err_call_all_func_failed:
172 if (event_info->power) {
173#ifdef CONFIG_HAS_EARLYSUSPEND
174 unregister_early_suspend(&ip->early_suspend);
175#endif
176 ip->info->power(ip->info, 0);
177 }
178 input_free_device(input_dev);
179err_input_dev_alloc_failed:
180 kfree(ip);
181err_kp_alloc_failed:
182 return err;
183}
184
185static int gpio_event_remove(struct platform_device *pdev)
186{
187 struct gpio_event *ip = platform_get_drvdata(pdev);
188
189 gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
190 if (ip->info->power) {
191#ifdef CONFIG_HAS_EARLYSUSPEND
192 unregister_early_suspend(&ip->early_suspend);
193#endif
194 ip->info->power(ip->info, 0);
195 }
196 input_unregister_device(ip->input_dev);
197 kfree(ip);
198 return 0;
199}
200
201static struct platform_driver gpio_event_driver = {
202 .probe = gpio_event_probe,
203 .remove = gpio_event_remove,
204 .driver = {
205 .name = GPIO_EVENT_DEV_NAME,
206 },
207};
208
209static int __devinit gpio_event_init(void)
210{
211 return platform_driver_register(&gpio_event_driver);
212}
213
214static void __exit gpio_event_exit(void)
215{
216 platform_driver_unregister(&gpio_event_driver);
217}
218
219module_init(gpio_event_init);
220module_exit(gpio_event_exit);
221
222MODULE_DESCRIPTION("GPIO Event Driver");
223MODULE_LICENSE("GPL");
224
diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c
deleted file mode 100644
index ca29e5eb070a..000000000000
--- a/drivers/staging/dream/gpio_input.c
+++ /dev/null
@@ -1,337 +0,0 @@
1/* drivers/input/misc/gpio_input.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19#include <linux/hrtimer.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/slab.h>
23
24enum {
25 DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */
26 DEBOUNCE_PRESSED = BIT(1),
27 DEBOUNCE_NOTPRESSED = BIT(2),
28 DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */
29 DEBOUNCE_POLL = BIT(4), /* Stable polling state */
30
31 DEBOUNCE_UNKNOWN =
32 DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
33};
34
35struct gpio_key_state {
36 struct gpio_input_state *ds;
37 uint8_t debounce;
38};
39
40struct gpio_input_state {
41 struct input_dev *input_dev;
42 const struct gpio_event_input_info *info;
43 struct hrtimer timer;
44 int use_irq;
45 int debounce_count;
46 spinlock_t irq_lock;
47 struct gpio_key_state key_state[0];
48};
49
50static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
51{
52 int i;
53 int pressed;
54 struct gpio_input_state *ds =
55 container_of(timer, struct gpio_input_state, timer);
56 unsigned gpio_flags = ds->info->flags;
57 unsigned npolarity;
58 int nkeys = ds->info->keymap_size;
59 const struct gpio_event_direct_entry *key_entry;
60 struct gpio_key_state *key_state;
61 unsigned long irqflags;
62 uint8_t debounce;
63
64#if 0
65 key_entry = kp->keys_info->keymap;
66 key_state = kp->key_state;
67 for (i = 0; i < nkeys; i++, key_entry++, key_state++)
68 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
69 gpio_read_detect_status(key_entry->gpio));
70#endif
71 key_entry = ds->info->keymap;
72 key_state = ds->key_state;
73 spin_lock_irqsave(&ds->irq_lock, irqflags);
74 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
75 debounce = key_state->debounce;
76 if (debounce & DEBOUNCE_WAIT_IRQ)
77 continue;
78 if (key_state->debounce & DEBOUNCE_UNSTABLE) {
79 debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
80 enable_irq(gpio_to_irq(key_entry->gpio));
81 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
82 "(%d) continue debounce\n",
83 ds->info->type, key_entry->code,
84 i, key_entry->gpio);
85 }
86 npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
87 pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
88 if (debounce & DEBOUNCE_POLL) {
89 if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
90 ds->debounce_count++;
91 key_state->debounce = DEBOUNCE_UNKNOWN;
92 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
93 pr_info("gpio_keys_scan_keys: key %x-"
94 "%x, %d (%d) start debounce\n",
95 ds->info->type, key_entry->code,
96 i, key_entry->gpio);
97 }
98 continue;
99 }
100 if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
101 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
102 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
103 "(%d) debounce pressed 1\n",
104 ds->info->type, key_entry->code,
105 i, key_entry->gpio);
106 key_state->debounce = DEBOUNCE_PRESSED;
107 continue;
108 }
109 if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
110 if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
111 pr_info("gpio_keys_scan_keys: key %x-%x, %d "
112 "(%d) debounce pressed 0\n",
113 ds->info->type, key_entry->code,
114 i, key_entry->gpio);
115 key_state->debounce = DEBOUNCE_NOTPRESSED;
116 continue;
117 }
118 /* key is stable */
119 ds->debounce_count--;
120 if (ds->use_irq)
121 key_state->debounce |= DEBOUNCE_WAIT_IRQ;
122 else
123 key_state->debounce |= DEBOUNCE_POLL;
124 if (gpio_flags & GPIOEDF_PRINT_KEYS)
125 pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
126 "changed to %d\n", ds->info->type,
127 key_entry->code, i, key_entry->gpio, pressed);
128 input_event(ds->input_dev, ds->info->type,
129 key_entry->code, pressed);
130 }
131
132#if 0
133 key_entry = kp->keys_info->keymap;
134 key_state = kp->key_state;
135 for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
136 pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
137 gpio_read_detect_status(key_entry->gpio));
138 }
139#endif
140
141 if (ds->debounce_count)
142 hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
143 else if (!ds->use_irq)
144 hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
145
146 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
147
148 return HRTIMER_NORESTART;
149}
150
151static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
152{
153 struct gpio_key_state *ks = dev_id;
154 struct gpio_input_state *ds = ks->ds;
155 int keymap_index = ks - ds->key_state;
156 const struct gpio_event_direct_entry *key_entry;
157 unsigned long irqflags;
158 int pressed;
159
160 if (!ds->use_irq)
161 return IRQ_HANDLED;
162
163 key_entry = &ds->info->keymap[keymap_index];
164
165 if (ds->info->debounce_time.tv64) {
166 spin_lock_irqsave(&ds->irq_lock, irqflags);
167 if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
168 ks->debounce = DEBOUNCE_UNKNOWN;
169 if (ds->debounce_count++ == 0) {
170 hrtimer_start(
171 &ds->timer, ds->info->debounce_time,
172 HRTIMER_MODE_REL);
173 }
174 if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
175 pr_info("gpio_event_input_irq_handler: "
176 "key %x-%x, %d (%d) start debounce\n",
177 ds->info->type, key_entry->code,
178 keymap_index, key_entry->gpio);
179 } else {
180 disable_irq(irq);
181 ks->debounce = DEBOUNCE_UNSTABLE;
182 }
183 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
184 } else {
185 pressed = gpio_get_value(key_entry->gpio) ^
186 !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
187 if (ds->info->flags & GPIOEDF_PRINT_KEYS)
188 pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
189 "(%d) changed to %d\n",
190 ds->info->type, key_entry->code, keymap_index,
191 key_entry->gpio, pressed);
192 input_event(ds->input_dev, ds->info->type,
193 key_entry->code, pressed);
194 }
195 return IRQ_HANDLED;
196}
197
198static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
199{
200 int i;
201 int err;
202 unsigned int irq;
203 unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
204
205 for (i = 0; i < ds->info->keymap_size; i++) {
206 err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
207 if (err < 0)
208 goto err_gpio_get_irq_num_failed;
209 err = request_irq(irq, gpio_event_input_irq_handler,
210 req_flags, "gpio_keys", &ds->key_state[i]);
211 if (err) {
212 pr_err("gpio_event_input_request_irqs: request_irq "
213 "failed for input %d, irq %d\n",
214 ds->info->keymap[i].gpio, irq);
215 goto err_request_irq_failed;
216 }
217 enable_irq_wake(irq);
218 }
219 return 0;
220
221 for (i = ds->info->keymap_size - 1; i >= 0; i--) {
222 free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
223 &ds->key_state[i]);
224err_request_irq_failed:
225err_gpio_get_irq_num_failed:
226 ;
227 }
228 return err;
229}
230
231int gpio_event_input_func(struct input_dev *input_dev,
232 struct gpio_event_info *info, void **data, int func)
233{
234 int ret;
235 int i;
236 unsigned long irqflags;
237 struct gpio_event_input_info *di;
238 struct gpio_input_state *ds = *data;
239
240 di = container_of(info, struct gpio_event_input_info, info);
241
242 if (func == GPIO_EVENT_FUNC_SUSPEND) {
243 spin_lock_irqsave(&ds->irq_lock, irqflags);
244 if (ds->use_irq)
245 for (i = 0; i < di->keymap_size; i++)
246 disable_irq(gpio_to_irq(di->keymap[i].gpio));
247 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
248 hrtimer_cancel(&ds->timer);
249 return 0;
250 }
251 if (func == GPIO_EVENT_FUNC_RESUME) {
252 spin_lock_irqsave(&ds->irq_lock, irqflags);
253 if (ds->use_irq)
254 for (i = 0; i < di->keymap_size; i++)
255 enable_irq(gpio_to_irq(di->keymap[i].gpio));
256 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
257 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
258 return 0;
259 }
260
261 if (func == GPIO_EVENT_FUNC_INIT) {
262 if (ktime_to_ns(di->poll_time) <= 0)
263 di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
264
265 *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
266 di->keymap_size, GFP_KERNEL);
267 if (ds == NULL) {
268 ret = -ENOMEM;
269 pr_err("gpio_event_input_func: "
270 "Failed to allocate private data\n");
271 goto err_ds_alloc_failed;
272 }
273 ds->debounce_count = di->keymap_size;
274 ds->input_dev = input_dev;
275 ds->info = di;
276 spin_lock_init(&ds->irq_lock);
277
278 for (i = 0; i < di->keymap_size; i++) {
279 input_set_capability(input_dev, di->type,
280 di->keymap[i].code);
281 ds->key_state[i].ds = ds;
282 ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
283 }
284
285 for (i = 0; i < di->keymap_size; i++) {
286 ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
287 if (ret) {
288 pr_err("gpio_event_input_func: gpio_request "
289 "failed for %d\n", di->keymap[i].gpio);
290 goto err_gpio_request_failed;
291 }
292 ret = gpio_direction_input(di->keymap[i].gpio);
293 if (ret) {
294 pr_err("gpio_event_input_func: "
295 "gpio_direction_input failed for %d\n",
296 di->keymap[i].gpio);
297 goto err_gpio_configure_failed;
298 }
299 }
300
301 ret = gpio_event_input_request_irqs(ds);
302
303 spin_lock_irqsave(&ds->irq_lock, irqflags);
304 ds->use_irq = ret == 0;
305
306 pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
307 "mode\n",
308 input_dev->name, ret == 0 ? "interrupt" : "polling");
309
310 hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
311 ds->timer.function = gpio_event_input_timer_func;
312 hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
313 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
314 return 0;
315 }
316
317 ret = 0;
318 spin_lock_irqsave(&ds->irq_lock, irqflags);
319 hrtimer_cancel(&ds->timer);
320 if (ds->use_irq) {
321 for (i = di->keymap_size - 1; i >= 0; i--) {
322 free_irq(gpio_to_irq(di->keymap[i].gpio),
323 &ds->key_state[i]);
324 }
325 }
326 spin_unlock_irqrestore(&ds->irq_lock, irqflags);
327
328 for (i = di->keymap_size - 1; i >= 0; i--) {
329err_gpio_configure_failed:
330 gpio_free(di->keymap[i].gpio);
331err_gpio_request_failed:
332 ;
333 }
334 kfree(ds);
335err_ds_alloc_failed:
336 return ret;
337}
diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c
deleted file mode 100644
index b377ee1f5a5f..000000000000
--- a/drivers/staging/dream/gpio_matrix.c
+++ /dev/null
@@ -1,399 +0,0 @@
1/* drivers/input/misc/gpio_matrix.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/gpio.h>
19#include <linux/gpio_event.h>
20#include <linux/hrtimer.h>
21#include <linux/interrupt.h>
22
23struct gpio_kp {
24 struct input_dev *input_dev;
25 struct gpio_event_matrix_info *keypad_info;
26 struct hrtimer timer;
27 int current_output;
28 unsigned int use_irq:1;
29 unsigned int key_state_changed:1;
30 unsigned int last_key_state_changed:1;
31 unsigned int some_keys_pressed:2;
32 unsigned long keys_pressed[0];
33};
34
35static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
36{
37 struct gpio_event_matrix_info *mi = kp->keypad_info;
38 int key_index = out * mi->ninputs + in;
39 unsigned short keycode = mi->keymap[key_index];;
40
41 if (!test_bit(keycode, kp->input_dev->key)) {
42 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
43 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
44 "cleared\n", keycode, out, in,
45 mi->output_gpios[out], mi->input_gpios[in]);
46 __clear_bit(key_index, kp->keys_pressed);
47 } else {
48 if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
49 pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
50 "not cleared\n", keycode, out, in,
51 mi->output_gpios[out], mi->input_gpios[in]);
52 }
53}
54
55static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
56{
57 int rv = 0;
58 int key_index;
59
60 key_index = out * kp->keypad_info->ninputs + in;
61 while (out < kp->keypad_info->noutputs) {
62 if (test_bit(key_index, kp->keys_pressed)) {
63 rv = 1;
64 clear_phantom_key(kp, out, in);
65 }
66 key_index += kp->keypad_info->ninputs;
67 out++;
68 }
69 return rv;
70}
71
72static void remove_phantom_keys(struct gpio_kp *kp)
73{
74 int out, in, inp;
75 int key_index;
76
77 if (kp->some_keys_pressed < 3)
78 return;
79
80 for (out = 0; out < kp->keypad_info->noutputs; out++) {
81 inp = -1;
82 key_index = out * kp->keypad_info->ninputs;
83 for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
84 if (test_bit(key_index, kp->keys_pressed)) {
85 if (inp == -1) {
86 inp = in;
87 continue;
88 }
89 if (inp >= 0) {
90 if (!restore_keys_for_input(kp, out + 1,
91 inp))
92 break;
93 clear_phantom_key(kp, out, inp);
94 inp = -2;
95 }
96 restore_keys_for_input(kp, out, in);
97 }
98 }
99 }
100}
101
102static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
103{
104 struct gpio_event_matrix_info *mi = kp->keypad_info;
105 int pressed = test_bit(key_index, kp->keys_pressed);
106 unsigned short keycode = mi->keymap[key_index];
107 if (pressed != test_bit(keycode, kp->input_dev->key)) {
108 if (keycode == KEY_RESERVED) {
109 if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
110 pr_info("gpiomatrix: unmapped key, %d-%d "
111 "(%d-%d) changed to %d\n",
112 out, in, mi->output_gpios[out],
113 mi->input_gpios[in], pressed);
114 } else {
115 if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
116 pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
117 "changed to %d\n", keycode,
118 out, in, mi->output_gpios[out],
119 mi->input_gpios[in], pressed);
120 input_report_key(kp->input_dev, keycode, pressed);
121 }
122 }
123}
124
125static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
126{
127 int out, in;
128 int key_index;
129 int gpio;
130 struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
131 struct gpio_event_matrix_info *mi = kp->keypad_info;
132 unsigned gpio_keypad_flags = mi->flags;
133 unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
134
135 out = kp->current_output;
136 if (out == mi->noutputs) {
137 out = 0;
138 kp->last_key_state_changed = kp->key_state_changed;
139 kp->key_state_changed = 0;
140 kp->some_keys_pressed = 0;
141 } else {
142 key_index = out * mi->ninputs;
143 for (in = 0; in < mi->ninputs; in++, key_index++) {
144 gpio = mi->input_gpios[in];
145 if (gpio_get_value(gpio) ^ !polarity) {
146 if (kp->some_keys_pressed < 3)
147 kp->some_keys_pressed++;
148 kp->key_state_changed |= !__test_and_set_bit(
149 key_index, kp->keys_pressed);
150 } else
151 kp->key_state_changed |= __test_and_clear_bit(
152 key_index, kp->keys_pressed);
153 }
154 gpio = mi->output_gpios[out];
155 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
156 gpio_set_value(gpio, !polarity);
157 else
158 gpio_direction_input(gpio);
159 out++;
160 }
161 kp->current_output = out;
162 if (out < mi->noutputs) {
163 gpio = mi->output_gpios[out];
164 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
165 gpio_set_value(gpio, polarity);
166 else
167 gpio_direction_output(gpio, polarity);
168 hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
169 return HRTIMER_NORESTART;
170 }
171 if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
172 if (kp->key_state_changed) {
173 hrtimer_start(&kp->timer, mi->debounce_delay,
174 HRTIMER_MODE_REL);
175 return HRTIMER_NORESTART;
176 }
177 kp->key_state_changed = kp->last_key_state_changed;
178 }
179 if (kp->key_state_changed) {
180 if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
181 remove_phantom_keys(kp);
182 key_index = 0;
183 for (out = 0; out < mi->noutputs; out++)
184 for (in = 0; in < mi->ninputs; in++, key_index++)
185 report_key(kp, key_index, out, in);
186 }
187 if (!kp->use_irq || kp->some_keys_pressed) {
188 hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
189 return HRTIMER_NORESTART;
190 }
191
192 /* No keys are pressed, reenable interrupt */
193 for (out = 0; out < mi->noutputs; out++) {
194 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
195 gpio_set_value(mi->output_gpios[out], polarity);
196 else
197 gpio_direction_output(mi->output_gpios[out], polarity);
198 }
199 for (in = 0; in < mi->ninputs; in++)
200 enable_irq(gpio_to_irq(mi->input_gpios[in]));
201 return HRTIMER_NORESTART;
202}
203
204static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
205{
206 int i;
207 struct gpio_kp *kp = dev_id;
208 struct gpio_event_matrix_info *mi = kp->keypad_info;
209 unsigned gpio_keypad_flags = mi->flags;
210
211 if (!kp->use_irq) /* ignore interrupt while registering the handler */
212 return IRQ_HANDLED;
213
214 for (i = 0; i < mi->ninputs; i++)
215 disable_irq(gpio_to_irq(mi->input_gpios[i]));
216 for (i = 0; i < mi->noutputs; i++) {
217 if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
218 gpio_set_value(mi->output_gpios[i],
219 !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
220 else
221 gpio_direction_input(mi->output_gpios[i]);
222 }
223 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
224 return IRQ_HANDLED;
225}
226
227static int gpio_keypad_request_irqs(struct gpio_kp *kp)
228{
229 int i;
230 int err;
231 unsigned int irq;
232 unsigned long request_flags;
233 struct gpio_event_matrix_info *mi = kp->keypad_info;
234
235 switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
236 default:
237 request_flags = IRQF_TRIGGER_FALLING;
238 break;
239 case GPIOKPF_ACTIVE_HIGH:
240 request_flags = IRQF_TRIGGER_RISING;
241 break;
242 case GPIOKPF_LEVEL_TRIGGERED_IRQ:
243 request_flags = IRQF_TRIGGER_LOW;
244 break;
245 case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
246 request_flags = IRQF_TRIGGER_HIGH;
247 break;
248 }
249
250 for (i = 0; i < mi->ninputs; i++) {
251 err = irq = gpio_to_irq(mi->input_gpios[i]);
252 if (err < 0)
253 goto err_gpio_get_irq_num_failed;
254 err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
255 "gpio_kp", kp);
256 if (err) {
257 pr_err("gpiomatrix: request_irq failed for input %d, "
258 "irq %d\n", mi->input_gpios[i], irq);
259 goto err_request_irq_failed;
260 }
261 err = set_irq_wake(irq, 1);
262 if (err) {
263 pr_err("gpiomatrix: set_irq_wake failed for input %d, "
264 "irq %d\n", mi->input_gpios[i], irq);
265 }
266 disable_irq(irq);
267 }
268 return 0;
269
270 for (i = mi->noutputs - 1; i >= 0; i--) {
271 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
272err_request_irq_failed:
273err_gpio_get_irq_num_failed:
274 ;
275 }
276 return err;
277}
278
279int gpio_event_matrix_func(struct input_dev *input_dev,
280 struct gpio_event_info *info, void **data, int func)
281{
282 int i;
283 int err;
284 int key_count;
285 struct gpio_kp *kp;
286 struct gpio_event_matrix_info *mi;
287
288 mi = container_of(info, struct gpio_event_matrix_info, info);
289 if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
290 /* TODO: disable scanning */
291 return 0;
292 }
293
294 if (func == GPIO_EVENT_FUNC_INIT) {
295 if (mi->keymap == NULL ||
296 mi->input_gpios == NULL ||
297 mi->output_gpios == NULL) {
298 err = -ENODEV;
299 pr_err("gpiomatrix: Incomplete pdata\n");
300 goto err_invalid_platform_data;
301 }
302 key_count = mi->ninputs * mi->noutputs;
303
304 *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
305 BITS_TO_LONGS(key_count), GFP_KERNEL);
306 if (kp == NULL) {
307 err = -ENOMEM;
308 pr_err("gpiomatrix: Failed to allocate private data\n");
309 goto err_kp_alloc_failed;
310 }
311 kp->input_dev = input_dev;
312 kp->keypad_info = mi;
313 set_bit(EV_KEY, input_dev->evbit);
314 for (i = 0; i < key_count; i++) {
315 if (mi->keymap[i])
316 set_bit(mi->keymap[i] & KEY_MAX,
317 input_dev->keybit);
318 }
319
320 for (i = 0; i < mi->noutputs; i++) {
321 if (gpio_cansleep(mi->output_gpios[i])) {
322 pr_err("gpiomatrix: unsupported output gpio %d,"
323 " can sleep\n", mi->output_gpios[i]);
324 err = -EINVAL;
325 goto err_request_output_gpio_failed;
326 }
327 err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
328 if (err) {
329 pr_err("gpiomatrix: gpio_request failed for "
330 "output %d\n", mi->output_gpios[i]);
331 goto err_request_output_gpio_failed;
332 }
333 if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
334 err = gpio_direction_output(mi->output_gpios[i],
335 !(mi->flags & GPIOKPF_ACTIVE_HIGH));
336 else
337 err = gpio_direction_input(mi->output_gpios[i]);
338 if (err) {
339 pr_err("gpiomatrix: gpio_configure failed for "
340 "output %d\n", mi->output_gpios[i]);
341 goto err_output_gpio_configure_failed;
342 }
343 }
344 for (i = 0; i < mi->ninputs; i++) {
345 err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
346 if (err) {
347 pr_err("gpiomatrix: gpio_request failed for "
348 "input %d\n", mi->input_gpios[i]);
349 goto err_request_input_gpio_failed;
350 }
351 err = gpio_direction_input(mi->input_gpios[i]);
352 if (err) {
353 pr_err("gpiomatrix: gpio_direction_input failed"
354 " for input %d\n", mi->input_gpios[i]);
355 goto err_gpio_direction_input_failed;
356 }
357 }
358 kp->current_output = mi->noutputs;
359 kp->key_state_changed = 1;
360
361 hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
362 kp->timer.function = gpio_keypad_timer_func;
363 err = gpio_keypad_request_irqs(kp);
364 kp->use_irq = err == 0;
365
366 pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s "
367 "in %s mode\n", input_dev->name,
368 kp->use_irq ? "interrupt" : "polling");
369
370 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
371
372 return 0;
373 }
374
375 err = 0;
376 kp = *data;
377
378 if (kp->use_irq)
379 for (i = mi->noutputs - 1; i >= 0; i--)
380 free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
381
382 hrtimer_cancel(&kp->timer);
383 for (i = mi->noutputs - 1; i >= 0; i--) {
384err_gpio_direction_input_failed:
385 gpio_free(mi->input_gpios[i]);
386err_request_input_gpio_failed:
387 ;
388 }
389 for (i = mi->noutputs - 1; i >= 0; i--) {
390err_output_gpio_configure_failed:
391 gpio_free(mi->output_gpios[i]);
392err_request_output_gpio_failed:
393 ;
394 }
395 kfree(kp);
396err_kp_alloc_failed:
397err_invalid_platform_data:
398 return err;
399}
diff --git a/drivers/staging/dream/gpio_output.c b/drivers/staging/dream/gpio_output.c
deleted file mode 100644
index 6f8453c97bd2..000000000000
--- a/drivers/staging/dream/gpio_output.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/* drivers/input/misc/gpio_output.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/gpio.h>
18#include <linux/gpio_event.h>
19
20int gpio_event_output_event(
21 struct input_dev *input_dev, struct gpio_event_info *info, void **data,
22 unsigned int type, unsigned int code, int value)
23{
24 int i;
25 struct gpio_event_output_info *oi;
26 oi = container_of(info, struct gpio_event_output_info, info);
27 if (type != oi->type)
28 return 0;
29 if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
30 value = !value;
31 for (i = 0; i < oi->keymap_size; i++)
32 if (code == oi->keymap[i].code)
33 gpio_set_value(oi->keymap[i].gpio, value);
34 return 0;
35}
36
37int gpio_event_output_func(
38 struct input_dev *input_dev, struct gpio_event_info *info, void **data,
39 int func)
40{
41 int ret;
42 int i;
43 struct gpio_event_output_info *oi;
44 oi = container_of(info, struct gpio_event_output_info, info);
45
46 if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
47 return 0;
48
49 if (func == GPIO_EVENT_FUNC_INIT) {
50 int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
51 for (i = 0; i < oi->keymap_size; i++)
52 input_set_capability(input_dev, oi->type,
53 oi->keymap[i].code);
54
55 for (i = 0; i < oi->keymap_size; i++) {
56 ret = gpio_request(oi->keymap[i].gpio,
57 "gpio_event_output");
58 if (ret) {
59 pr_err("gpio_event_output_func: gpio_request "
60 "failed for %d\n", oi->keymap[i].gpio);
61 goto err_gpio_request_failed;
62 }
63 ret = gpio_direction_output(oi->keymap[i].gpio,
64 output_level);
65 if (ret) {
66 pr_err("gpio_event_output_func: "
67 "gpio_direction_output failed for %d\n",
68 oi->keymap[i].gpio);
69 goto err_gpio_direction_output_failed;
70 }
71 }
72 return 0;
73 }
74
75 ret = 0;
76 for (i = oi->keymap_size - 1; i >= 0; i--) {
77err_gpio_direction_output_failed:
78 gpio_free(oi->keymap[i].gpio);
79err_gpio_request_failed:
80 ;
81 }
82 return ret;
83}
84
diff --git a/drivers/staging/dream/include/linux/android_pmem.h b/drivers/staging/dream/include/linux/android_pmem.h
deleted file mode 100644
index 2fc05d7d335b..000000000000
--- a/drivers/staging/dream/include/linux/android_pmem.h
+++ /dev/null
@@ -1,80 +0,0 @@
1/* drivers/staging/dream/include/linux/android_pmem.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _ANDROID_PMEM_H_
17#define _ANDROID_PMEM_H_
18
19#define PMEM_IOCTL_MAGIC 'p'
20#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
21#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
22#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
23#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
24/* This ioctl will allocate pmem space, backing the file, it will fail
25 * if the file already has an allocation, pass it the len as the argument
26 * to the ioctl */
27#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
28/* This will connect a one pmem file to another, pass the file that is already
29 * backed in memory as the argument to the ioctl
30 */
31#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
32/* Returns the total size of the pmem region it is sent to as a pmem_region
33 * struct (with offset set to 0).
34 */
35#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
36/* Revokes gpu registers and resets the gpu. Pass a pointer to the
37 * start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
38 */
39#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
40#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
41#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
42
43int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
44 unsigned long *end, struct file **filp);
45int get_pmem_user_addr(struct file *file, unsigned long *start,
46 unsigned long *end);
47void put_pmem_file(struct file* file);
48void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
49
50struct android_pmem_platform_data
51{
52 const char* name;
53 /* starting physical address of memory region */
54 unsigned long start;
55 /* size of memory region */
56 unsigned long size;
57 /* set to indicate the region should not be managed with an allocator */
58 unsigned no_allocator;
59 /* set to indicate maps of this region should be cached, if a mix of
60 * cached and uncached is desired, set this and open the device with
61 * O_SYNC to get an uncached region */
62 unsigned cached;
63 /* The MSM7k has bits to enable a write buffer in the bus controller*/
64 unsigned buffered;
65};
66
67struct pmem_region {
68 unsigned long offset;
69 unsigned long len;
70};
71
72int pmem_setup(struct android_pmem_platform_data *pdata,
73 long (*ioctl)(struct file *, unsigned int, unsigned long),
74 int (*release)(struct inode *, struct file *));
75
76int pmem_remap(struct pmem_region *region, struct file *file,
77 unsigned operation);
78
79#endif //_ANDROID_PPP_H_
80
diff --git a/drivers/staging/dream/include/linux/gpio_event.h b/drivers/staging/dream/include/linux/gpio_event.h
deleted file mode 100644
index ffc5da392ad7..000000000000
--- a/drivers/staging/dream/include/linux/gpio_event.h
+++ /dev/null
@@ -1,154 +0,0 @@
1/* drivers/staging/dream/include/linux/gpio_event.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _LINUX_GPIO_EVENT_H
17#define _LINUX_GPIO_EVENT_H
18
19#include <linux/input.h>
20
21enum {
22 GPIO_EVENT_FUNC_UNINIT = 0x0,
23 GPIO_EVENT_FUNC_INIT = 0x1,
24 GPIO_EVENT_FUNC_SUSPEND = 0x2,
25 GPIO_EVENT_FUNC_RESUME = 0x3,
26};
27struct gpio_event_info {
28 int (*func)(struct input_dev *input_dev,
29 struct gpio_event_info *info,
30 void **data, int func);
31 int (*event)(struct input_dev *input_dev,
32 struct gpio_event_info *info,
33 void **data, unsigned int type,
34 unsigned int code, int value); /* out events */
35};
36
37struct gpio_event_platform_data {
38 const char *name;
39 struct gpio_event_info **info;
40 size_t info_count;
41 int (*power)(const struct gpio_event_platform_data *pdata, bool on);
42};
43
44#define GPIO_EVENT_DEV_NAME "gpio-event"
45
46/* Key matrix */
47
48enum gpio_event_matrix_flags {
49 /* unset: drive active output low, set: drive active output high */
50 GPIOKPF_ACTIVE_HIGH = 1U << 0,
51 GPIOKPF_DEBOUNCE = 1U << 1,
52 GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
53 GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
54 GPIOKPF_DEBOUNCE,
55 GPIOKPF_DRIVE_INACTIVE = 1U << 3,
56 GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4,
57 GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16,
58 GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17,
59 GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18,
60};
61
62extern int gpio_event_matrix_func(struct input_dev *input_dev,
63 struct gpio_event_info *info, void **data, int func);
64struct gpio_event_matrix_info {
65 /* initialize to gpio_event_matrix_func */
66 struct gpio_event_info info;
67 /* size must be ninputs * noutputs */
68 const unsigned short *keymap;
69 unsigned int *input_gpios;
70 unsigned int *output_gpios;
71 unsigned int ninputs;
72 unsigned int noutputs;
73 /* time to wait before reading inputs after driving each output */
74 ktime_t settle_time;
75 /* time to wait before scanning the keypad a second time */
76 ktime_t debounce_delay;
77 ktime_t poll_time;
78 unsigned flags;
79};
80
81/* Directly connected inputs and outputs */
82
83enum gpio_event_direct_flags {
84 GPIOEDF_ACTIVE_HIGH = 1U << 0,
85/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */
86/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
87 GPIOEDF_PRINT_KEYS = 1U << 8,
88 GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9,
89};
90
91struct gpio_event_direct_entry {
92 uint32_t gpio:23;
93 uint32_t code:9;
94};
95
96/* inputs */
97extern int gpio_event_input_func(struct input_dev *input_dev,
98 struct gpio_event_info *info, void **data, int func);
99struct gpio_event_input_info {
100 /* initialize to gpio_event_input_func */
101 struct gpio_event_info info;
102 ktime_t debounce_time;
103 ktime_t poll_time;
104 uint16_t flags;
105 uint16_t type;
106 const struct gpio_event_direct_entry *keymap;
107 size_t keymap_size;
108};
109
110/* outputs */
111extern int gpio_event_output_func(struct input_dev *input_dev,
112 struct gpio_event_info *info, void **data, int func);
113extern int gpio_event_output_event(struct input_dev *input_dev,
114 struct gpio_event_info *info, void **data,
115 unsigned int type, unsigned int code, int value);
116struct gpio_event_output_info {
117 /* initialize to gpio_event_output_func and gpio_event_output_event */
118 struct gpio_event_info info;
119 uint16_t flags;
120 uint16_t type;
121 const struct gpio_event_direct_entry *keymap;
122 size_t keymap_size;
123};
124
125
126/* axes */
127
128enum gpio_event_axis_flags {
129 GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16,
130 GPIOEAF_PRINT_RAW = 1U << 17,
131 GPIOEAF_PRINT_EVENT = 1U << 18,
132};
133
134extern int gpio_event_axis_func(struct input_dev *input_dev,
135 struct gpio_event_info *info, void **data, int func);
136struct gpio_event_axis_info {
137 /* initialize to gpio_event_axis_func */
138 struct gpio_event_info info;
139 uint8_t count;
140 uint8_t type; /* EV_REL or EV_ABS */
141 uint16_t code;
142 uint16_t decoded_size;
143 uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
144 uint32_t *gpio;
145 uint32_t flags;
146};
147#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
148#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
149uint16_t gpio_axis_4bit_gray_map(
150 struct gpio_event_axis_info *info, uint16_t in);
151uint16_t gpio_axis_5bit_singletrack_map(
152 struct gpio_event_axis_info *info, uint16_t in);
153
154#endif
diff --git a/drivers/staging/dream/include/linux/msm_adsp.h b/drivers/staging/dream/include/linux/msm_adsp.h
deleted file mode 100644
index e775f3e94f1d..000000000000
--- a/drivers/staging/dream/include/linux/msm_adsp.h
+++ /dev/null
@@ -1,84 +0,0 @@
1/* drivers/staging/dream/include/linux/msm_adsp.h
2 *
3 * Copyright (c) QUALCOMM Incorporated
4 * Copyright (C) 2007 Google, Inc.
5 * Author: Iliyan Malchev <ibm@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17#ifndef __LINUX_MSM_ADSP_H
18#define __LINUX_MSM_ADSP_H
19
20#include <linux/types.h>
21#include <linux/ioctl.h>
22
23#define ADSP_IOCTL_MAGIC 'q'
24
25/* ADSP_IOCTL_WRITE_COMMAND */
26struct adsp_command_t {
27 uint16_t queue;
28 uint32_t len; /* bytes */
29 uint8_t *data;
30};
31
32/* ADSP_IOCTL_GET_EVENT */
33struct adsp_event_t {
34 uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */
35 uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */
36 uint16_t msg_id;
37 uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */
38 uint32_t len; /* size in, number of bytes out */
39 uint8_t *data;
40};
41
42#define ADSP_IOCTL_ENABLE \
43 _IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
44
45#define ADSP_IOCTL_DISABLE \
46 _IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
47
48#define ADSP_IOCTL_DISABLE_ACK \
49 _IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
50
51#define ADSP_IOCTL_WRITE_COMMAND \
52 _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
53
54#define ADSP_IOCTL_GET_EVENT \
55 _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
56
57#define ADSP_IOCTL_SET_CLKRATE \
58 _IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
59
60#define ADSP_IOCTL_DISABLE_EVENT_RSP \
61 _IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
62
63struct adsp_pmem_info {
64 int fd;
65 void *vaddr;
66};
67
68#define ADSP_IOCTL_REGISTER_PMEM \
69 _IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
70
71#define ADSP_IOCTL_UNREGISTER_PMEM \
72 _IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
73
74/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
75 * until the device is closed and reopened. Useful for
76 * terminating event dispatch threads
77 */
78#define ADSP_IOCTL_ABORT_EVENT_READ \
79 _IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
80
81#define ADSP_IOCTL_LINK_TASK \
82 _IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
83
84#endif
diff --git a/drivers/staging/dream/include/linux/msm_audio.h b/drivers/staging/dream/include/linux/msm_audio.h
deleted file mode 100644
index cfbdaa0d98b2..000000000000
--- a/drivers/staging/dream/include/linux/msm_audio.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/* drivers/staging/dream/include/linux/msm_audio.h
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __LINUX_MSM_AUDIO_H
17#define __LINUX_MSM_AUDIO_H
18
19#include <linux/types.h>
20#include <linux/ioctl.h>
21#include <asm/sizes.h>
22
23/* PCM Audio */
24
25#define AUDIO_IOCTL_MAGIC 'a'
26
27#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
28#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
29#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
30#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
31#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
32#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
33#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
34#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
35#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
36#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
37#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
38#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
39#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
40#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
41#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
42#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
43#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
44#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
45#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
46
47#define AUDIO_MAX_COMMON_IOCTL_NUM 100
48
49#define AUDIO_MAX_COMMON_IOCTL_NUM 100
50
51struct msm_audio_config {
52 uint32_t buffer_size;
53 uint32_t buffer_count;
54 uint32_t channel_count;
55 uint32_t sample_rate;
56 uint32_t type;
57 uint32_t unused[3];
58};
59
60struct msm_audio_stats {
61 uint32_t byte_count;
62 uint32_t sample_count;
63 uint32_t unused[2];
64};
65
66/* Audio routing */
67
68#define SND_IOCTL_MAGIC 's'
69
70#define SND_MUTE_UNMUTED 0
71#define SND_MUTE_MUTED 1
72
73struct msm_snd_device_config {
74 uint32_t device;
75 uint32_t ear_mute;
76 uint32_t mic_mute;
77};
78
79#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
80
81#define SND_METHOD_VOICE 0
82
83struct msm_snd_volume_config {
84 uint32_t device;
85 uint32_t method;
86 uint32_t volume;
87};
88
89#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
90
91/* Returns the number of SND endpoints supported. */
92
93#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
94
95struct msm_snd_endpoint {
96 int id; /* input and output */
97 char name[64]; /* output only */
98};
99
100/* Takes an index between 0 and one less than the number returned by
101 * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
102 * SND endpoint. On input, the .id field contains the number of the
103 * endpoint, and on exit it contains the SND index, while .name contains
104 * the description of the endpoint.
105 */
106
107#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
108
109struct msm_audio_pcm_config {
110 uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
111 uint32_t buffer_count; /* Number of buffers to allocate */
112 uint32_t buffer_size; /* Size of buffer for capturing of
113 PCM samples */
114};
115#endif
diff --git a/drivers/staging/dream/include/linux/msm_rpcrouter.h b/drivers/staging/dream/include/linux/msm_rpcrouter.h
deleted file mode 100644
index 64845fb481f1..000000000000
--- a/drivers/staging/dream/include/linux/msm_rpcrouter.h
+++ /dev/null
@@ -1,47 +0,0 @@
1/* drivers/staging/dream/include/linux/msm_rpcrouter.h
2 *
3 * Copyright (c) QUALCOMM Incorporated
4 * Copyright (C) 2007 Google, Inc.
5 * Author: San Mehat <san@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17#ifndef __LINUX_MSM_RPCROUTER_H
18#define __LINUX_MSM_RPCROUTER_H
19
20#include <linux/types.h>
21#include <linux/ioctl.h>
22
23#define RPC_ROUTER_VERSION_V1 0x00010000
24
25struct rpcrouter_ioctl_server_args {
26 uint32_t prog;
27 uint32_t vers;
28};
29
30#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
31
32#define RPC_ROUTER_IOCTL_GET_VERSION \
33 _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
34
35#define RPC_ROUTER_IOCTL_GET_MTU \
36 _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
37
38#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
39 _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
40
41#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
42 _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
43
44#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
45 _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
46
47#endif
diff --git a/drivers/staging/dream/include/linux/wakelock.h b/drivers/staging/dream/include/linux/wakelock.h
deleted file mode 100644
index 93c31a4d1ca7..000000000000
--- a/drivers/staging/dream/include/linux/wakelock.h
+++ /dev/null
@@ -1,91 +0,0 @@
1/* drivers/staging/dream/include/linux/wakelock.h
2 *
3 * Copyright (C) 2007-2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _LINUX_WAKELOCK_H
17#define _LINUX_WAKELOCK_H
18
19#include <linux/list.h>
20#include <linux/ktime.h>
21
22/* A wake_lock prevents the system from entering suspend or other low power
23 * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
24 * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
25 * states that cause large interrupt latencies or that disable a set of
26 * interrupts will not entered from idle until the wake_locks are released.
27 */
28
29enum {
30 WAKE_LOCK_SUSPEND, /* Prevent suspend */
31 WAKE_LOCK_IDLE, /* Prevent low power idle */
32 WAKE_LOCK_TYPE_COUNT
33};
34
35struct wake_lock {
36#ifdef CONFIG_HAS_WAKELOCK
37 struct list_head link;
38 int flags;
39 const char *name;
40 unsigned long expires;
41#ifdef CONFIG_WAKELOCK_STAT
42 struct {
43 int count;
44 int expire_count;
45 int wakeup_count;
46 ktime_t total_time;
47 ktime_t prevent_suspend_time;
48 ktime_t max_time;
49 ktime_t last_time;
50 } stat;
51#endif
52#endif
53};
54
55#ifdef CONFIG_HAS_WAKELOCK
56
57void wake_lock_init(struct wake_lock *lock, int type, const char *name);
58void wake_lock_destroy(struct wake_lock *lock);
59void wake_lock(struct wake_lock *lock);
60void wake_lock_timeout(struct wake_lock *lock, long timeout);
61void wake_unlock(struct wake_lock *lock);
62
63/* wake_lock_active returns a non-zero value if the wake_lock is currently
64 * locked. If the wake_lock has a timeout, it does not check the timeout
65 * but if the timeout had aready been checked it will return 0.
66 */
67int wake_lock_active(struct wake_lock *lock);
68
69/* has_wake_lock returns 0 if no wake locks of the specified type are active,
70 * and non-zero if one or more wake locks are held. Specifically it returns
71 * -1 if one or more wake locks with no timeout are active or the
72 * number of jiffies until all active wake locks time out.
73 */
74long has_wake_lock(int type);
75
76#else
77
78static inline void wake_lock_init(struct wake_lock *lock, int type,
79 const char *name) {}
80static inline void wake_lock_destroy(struct wake_lock *lock) {}
81static inline void wake_lock(struct wake_lock *lock) {}
82static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
83static inline void wake_unlock(struct wake_lock *lock) {}
84
85static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
86static inline long has_wake_lock(int type) { return 0; }
87
88#endif
89
90#endif
91
diff --git a/drivers/staging/dream/include/mach/camera.h b/drivers/staging/dream/include/mach/camera.h
deleted file mode 100644
index c20f0423abd4..000000000000
--- a/drivers/staging/dream/include/mach/camera.h
+++ /dev/null
@@ -1,279 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef __ASM__ARCH_CAMERA_H
6#define __ASM__ARCH_CAMERA_H
7
8#include <linux/list.h>
9#include <linux/poll.h>
10#include <linux/cdev.h>
11#include <linux/platform_device.h>
12#include "linux/types.h"
13
14#include <mach/board.h>
15#include <media/msm_camera.h>
16
17#ifdef CONFIG_MSM_CAMERA_DEBUG
18#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
19#else
20#define CDBG(fmt, args...) do { } while (0)
21#endif
22
23#define MSM_CAMERA_MSG 0
24#define MSM_CAMERA_EVT 1
25#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
26#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3
27#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
28#define NUM_AF_STAT_OUTPUT_BUFFERS 3
29
30enum msm_queue {
31 MSM_CAM_Q_CTRL, /* control command or control command status */
32 MSM_CAM_Q_VFE_EVT, /* adsp event */
33 MSM_CAM_Q_VFE_MSG, /* adsp message */
34 MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
35};
36
37enum vfe_resp_msg {
38 VFE_EVENT,
39 VFE_MSG_GENERAL,
40 VFE_MSG_SNAPSHOT,
41 VFE_MSG_OUTPUT1,
42 VFE_MSG_OUTPUT2,
43 VFE_MSG_STATS_AF,
44 VFE_MSG_STATS_WE,
45};
46
47struct msm_vfe_phy_info {
48 uint32_t sbuf_phy;
49 uint32_t y_phy;
50 uint32_t cbcr_phy;
51};
52
53struct msm_vfe_resp {
54 enum vfe_resp_msg type;
55 struct msm_vfe_evt_msg evt_msg;
56 struct msm_vfe_phy_info phy;
57 void *extdata;
58 int32_t extlen;
59};
60
61struct msm_vfe_callback {
62 void (*vfe_resp)(struct msm_vfe_resp *,
63 enum msm_queue, void *syncdata);
64 void* (*vfe_alloc)(int, void *syncdata);
65};
66
67struct msm_camvfe_fn {
68 int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
69 int (*vfe_enable)(struct camera_enable_cmd *);
70 int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
71 int (*vfe_disable)(struct camera_enable_cmd *,
72 struct platform_device *dev);
73 void (*vfe_release)(struct platform_device *);
74};
75
76struct msm_sensor_ctrl {
77 int (*s_init)(const struct msm_camera_sensor_info *);
78 int (*s_release)(void);
79 int (*s_config)(void __user *);
80};
81
82struct msm_sync {
83 /* These two queues are accessed from a process context only. */
84 struct hlist_head frame; /* most-frequently accessed */
85 struct hlist_head stats;
86
87 /* The message queue is used by the control thread to send commands
88 * to the config thread, and also by the DSP to send messages to the
89 * config thread. Thus it is the only queue that is accessed from
90 * both interrupt and process context.
91 */
92 spinlock_t msg_event_q_lock;
93 struct list_head msg_event_q;
94 wait_queue_head_t msg_event_wait;
95
96 /* This queue contains preview frames. It is accessed by the DSP (in
97 * in interrupt context, and by the frame thread.
98 */
99 spinlock_t prev_frame_q_lock;
100 struct list_head prev_frame_q;
101 wait_queue_head_t prev_frame_wait;
102 int unblock_poll_frame;
103
104 /* This queue contains snapshot frames. It is accessed by the DSP (in
105 * interrupt context, and by the control thread.
106 */
107 spinlock_t pict_frame_q_lock;
108 struct list_head pict_frame_q;
109 wait_queue_head_t pict_frame_wait;
110
111 struct msm_camera_sensor_info *sdata;
112 struct msm_camvfe_fn vfefn;
113 struct msm_sensor_ctrl sctrl;
114 struct platform_device *pdev;
115 uint8_t opencnt;
116 void *cropinfo;
117 int croplen;
118 unsigned pict_pp;
119
120 const char *apps_id;
121
122 struct mutex lock;
123 struct list_head list;
124};
125
126#define MSM_APPS_ID_V4L2 "msm_v4l2"
127#define MSM_APPS_ID_PROP "msm_qct"
128
129struct msm_device {
130 struct msm_sync *sync; /* most-frequently accessed */
131 struct device *device;
132 struct cdev cdev;
133 /* opened is meaningful only for the config and frame nodes,
134 * which may be opened only once.
135 */
136 atomic_t opened;
137};
138
139struct msm_control_device_queue {
140 spinlock_t ctrl_status_q_lock;
141 struct list_head ctrl_status_q;
142 wait_queue_head_t ctrl_status_wait;
143};
144
145struct msm_control_device {
146 struct msm_device *pmsm;
147
148 /* This queue used by the config thread to send responses back to the
149 * control thread. It is accessed only from a process context.
150 */
151 struct msm_control_device_queue ctrl_q;
152};
153
154/* this structure is used in kernel */
155struct msm_queue_cmd {
156 struct list_head list;
157 enum msm_queue type;
158 void *command;
159};
160
161struct register_address_value_pair {
162 uint16_t register_address;
163 uint16_t register_value;
164};
165
166struct msm_pmem_region {
167 struct hlist_node list;
168 int type;
169 void *vaddr;
170 unsigned long paddr;
171 unsigned long len;
172 struct file *file;
173 uint32_t y_off;
174 uint32_t cbcr_off;
175 int fd;
176 uint8_t active;
177};
178
179struct axidata {
180 uint32_t bufnum1;
181 uint32_t bufnum2;
182 struct msm_pmem_region *region;
183};
184
185#ifdef CONFIG_MSM_CAMERA_FLASH
186int msm_camera_flash_set_led_state(unsigned led_state);
187#else
188static inline int msm_camera_flash_set_led_state(unsigned led_state)
189{
190 return -ENOTSUPP;
191}
192#endif
193
194/* Below functions are added for V4L2 kernel APIs */
195struct msm_v4l2_driver {
196 struct msm_sync *sync;
197 int (*open)(struct msm_sync *, const char *apps_id);
198 int (*release)(struct msm_sync *);
199 int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
200 int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
201 int (*get_frame) (struct msm_sync *, struct msm_frame *);
202 int (*put_frame) (struct msm_sync *, struct msm_frame *);
203 int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
204 unsigned int (*drv_poll) (struct msm_sync *, struct file *,
205 struct poll_table_struct *);
206};
207
208int msm_v4l2_register(struct msm_v4l2_driver *);
209int msm_v4l2_unregister(struct msm_v4l2_driver *);
210
211void msm_camvfe_init(void);
212int msm_camvfe_check(void *);
213void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
214int msm_camera_drv_start(struct platform_device *dev,
215 int (*sensor_probe)(const struct msm_camera_sensor_info *,
216 struct msm_sensor_ctrl *));
217
218enum msm_camio_clk_type {
219 CAMIO_VFE_MDC_CLK,
220 CAMIO_MDC_CLK,
221 CAMIO_VFE_CLK,
222 CAMIO_VFE_AXI_CLK,
223
224 CAMIO_MAX_CLK
225};
226
227enum msm_camio_clk_src_type {
228 MSM_CAMIO_CLK_SRC_INTERNAL,
229 MSM_CAMIO_CLK_SRC_EXTERNAL,
230 MSM_CAMIO_CLK_SRC_MAX
231};
232
233enum msm_s_test_mode {
234 S_TEST_OFF,
235 S_TEST_1,
236 S_TEST_2,
237 S_TEST_3
238};
239
240enum msm_s_resolution {
241 S_QTR_SIZE,
242 S_FULL_SIZE,
243 S_INVALID_SIZE
244};
245
246enum msm_s_reg_update {
247 /* Sensor egisters that need to be updated during initialization */
248 S_REG_INIT,
249 /* Sensor egisters that needs periodic I2C writes */
250 S_UPDATE_PERIODIC,
251 /* All the sensor Registers will be updated */
252 S_UPDATE_ALL,
253 /* Not valid update */
254 S_UPDATE_INVALID
255};
256
257enum msm_s_setting {
258 S_RES_PREVIEW,
259 S_RES_CAPTURE
260};
261
262int msm_camio_enable(struct platform_device *dev);
263
264int msm_camio_clk_enable(enum msm_camio_clk_type clk);
265int msm_camio_clk_disable(enum msm_camio_clk_type clk);
266int msm_camio_clk_config(uint32_t freq);
267void msm_camio_clk_rate_set(int rate);
268void msm_camio_clk_axi_rate_set(int rate);
269
270void msm_camio_camif_pad_reg_reset(void);
271void msm_camio_camif_pad_reg_reset_2(void);
272
273void msm_camio_vfe_blk_reset(void);
274
275void msm_camio_clk_sel(enum msm_camio_clk_src_type);
276void msm_camio_disable(struct platform_device *);
277int msm_camio_probe_on(struct platform_device *);
278int msm_camio_probe_off(struct platform_device *);
279#endif
diff --git a/drivers/staging/dream/include/mach/msm_adsp.h b/drivers/staging/dream/include/mach/msm_adsp.h
deleted file mode 100644
index a081683328a3..000000000000
--- a/drivers/staging/dream/include/mach/msm_adsp.h
+++ /dev/null
@@ -1,112 +0,0 @@
1/* include/asm-arm/arch-msm/msm_adsp.h
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __ASM__ARCH_MSM_ADSP_H
17#define __ASM__ARCH_MSM_ADSP_H
18
19struct msm_adsp_module;
20
21struct msm_adsp_ops {
22 /* event is called from interrupt context when a message
23 * arrives from the DSP. Use the provided function pointer
24 * to copy the message into a local buffer. Do NOT call
25 * it multiple times.
26 */
27 void (*event)(void *driver_data, unsigned id, size_t len,
28 void (*getevent)(void *ptr, size_t len));
29};
30
31/* Get, Put, Enable, and Disable are synchronous and must only
32 * be called from thread context. Enable and Disable will block
33 * up to one second in the event of a fatal DSP error but are
34 * much faster otherwise.
35 */
36int msm_adsp_get(const char *name, struct msm_adsp_module **module,
37 struct msm_adsp_ops *ops, void *driver_data);
38void msm_adsp_put(struct msm_adsp_module *module);
39int msm_adsp_enable(struct msm_adsp_module *module);
40int msm_adsp_disable(struct msm_adsp_module *module);
41int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
42
43/* Write is safe to call from interrupt context.
44 */
45int msm_adsp_write(struct msm_adsp_module *module,
46 unsigned queue_id,
47 void *data, size_t len);
48
49#if CONFIG_MSM_AMSS_VERSION >= 6350
50/* Command Queue Indexes */
51#define QDSP_lpmCommandQueue 0
52#define QDSP_mpuAfeQueue 1
53#define QDSP_mpuGraphicsCmdQueue 2
54#define QDSP_mpuModmathCmdQueue 3
55#define QDSP_mpuVDecCmdQueue 4
56#define QDSP_mpuVDecPktQueue 5
57#define QDSP_mpuVEncCmdQueue 6
58#define QDSP_rxMpuDecCmdQueue 7
59#define QDSP_rxMpuDecPktQueue 8
60#define QDSP_txMpuEncQueue 9
61#define QDSP_uPAudPPCmd1Queue 10
62#define QDSP_uPAudPPCmd2Queue 11
63#define QDSP_uPAudPPCmd3Queue 12
64#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
65#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
66#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
67#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
68#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
69#define QDSP_uPAudPreProcCmdQueue 18
70#define QDSP_uPAudRecBitStreamQueue 19
71#define QDSP_uPAudRecCmdQueue 20
72#define QDSP_uPDiagQueue 21
73#define QDSP_uPJpegActionCmdQueue 22
74#define QDSP_uPJpegCfgCmdQueue 23
75#define QDSP_uPVocProcQueue 24
76#define QDSP_vfeCommandQueue 25
77#define QDSP_vfeCommandScaleQueue 26
78#define QDSP_vfeCommandTableQueue 27
79#define QDSP_MAX_NUM_QUEUES 28
80#else
81/* Command Queue Indexes */
82#define QDSP_lpmCommandQueue 0
83#define QDSP_mpuAfeQueue 1
84#define QDSP_mpuGraphicsCmdQueue 2
85#define QDSP_mpuModmathCmdQueue 3
86#define QDSP_mpuVDecCmdQueue 4
87#define QDSP_mpuVDecPktQueue 5
88#define QDSP_mpuVEncCmdQueue 6
89#define QDSP_rxMpuDecCmdQueue 7
90#define QDSP_rxMpuDecPktQueue 8
91#define QDSP_txMpuEncQueue 9
92#define QDSP_uPAudPPCmd1Queue 10
93#define QDSP_uPAudPPCmd2Queue 11
94#define QDSP_uPAudPPCmd3Queue 12
95#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
96#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
97#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
98#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
99#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
100#define QDSP_uPAudPreProcCmdQueue 18
101#define QDSP_uPAudRecBitStreamQueue 19
102#define QDSP_uPAudRecCmdQueue 20
103#define QDSP_uPJpegActionCmdQueue 21
104#define QDSP_uPJpegCfgCmdQueue 22
105#define QDSP_uPVocProcQueue 23
106#define QDSP_vfeCommandQueue 24
107#define QDSP_vfeCommandScaleQueue 25
108#define QDSP_vfeCommandTableQueue 26
109#define QDSP_QUEUE_MAX 26
110#endif
111
112#endif
diff --git a/drivers/staging/dream/include/mach/msm_rpcrouter.h b/drivers/staging/dream/include/mach/msm_rpcrouter.h
deleted file mode 100644
index 9724ece1c97c..000000000000
--- a/drivers/staging/dream/include/mach/msm_rpcrouter.h
+++ /dev/null
@@ -1,179 +0,0 @@
1/** include/asm-arm/arch-msm/msm_rpcrouter.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007-2009 QUALCOMM Incorporated
5 * Author: San Mehat <san@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#ifndef __ASM__ARCH_MSM_RPCROUTER_H
19#define __ASM__ARCH_MSM_RPCROUTER_H
20
21#include <linux/types.h>
22#include <linux/list.h>
23#include <linux/platform_device.h>
24
25#if CONFIG_MSM_AMSS_VERSION >= 6350
26/* RPC API version structure
27 * Version bit 31 : 1->hashkey versioning,
28 * 0->major-minor (backward compatible) versioning
29 * hashkey versioning:
30 * Version bits 31-0 hashkey
31 * major-minor (backward compatible) versioning
32 * Version bits 30-28 reserved (no match)
33 * Version bits 27-16 major (must match)
34 * Version bits 15-0 minor (greater or equal)
35 */
36#define RPC_VERSION_MODE_MASK 0x80000000
37#define RPC_VERSION_MAJOR_MASK 0x0fff0000
38#define RPC_VERSION_MAJOR_OFFSET 16
39#define RPC_VERSION_MINOR_MASK 0x0000ffff
40
41#define MSM_RPC_VERS(major, minor) \
42 ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \
43 RPC_VERSION_MAJOR_MASK) | \
44 ((minor) & RPC_VERSION_MINOR_MASK)))
45#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \
46 RPC_VERSION_MAJOR_OFFSET)
47#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
48#else
49#define MSM_RPC_VERS(major, minor) (major)
50#define MSM_RPC_GET_MAJOR(vers) (vers)
51#define MSM_RPC_GET_MINOR(vers) 0
52#endif
53
54struct msm_rpc_endpoint;
55
56struct rpcsvr_platform_device
57{
58 struct platform_device base;
59 uint32_t prog;
60 uint32_t vers;
61};
62
63#define RPC_DATA_IN 0
64/*
65 * Structures for sending / receiving direct RPC requests
66 * XXX: Any cred/verif lengths > 0 not supported
67 */
68
69struct rpc_request_hdr
70{
71 uint32_t xid;
72 uint32_t type; /* 0 */
73 uint32_t rpc_vers; /* 2 */
74 uint32_t prog;
75 uint32_t vers;
76 uint32_t procedure;
77 uint32_t cred_flavor;
78 uint32_t cred_length;
79 uint32_t verf_flavor;
80 uint32_t verf_length;
81};
82
83typedef struct
84{
85 uint32_t low;
86 uint32_t high;
87} rpc_reply_progmismatch_data;
88
89typedef struct
90{
91} rpc_denied_reply_hdr;
92
93typedef struct
94{
95 uint32_t verf_flavor;
96 uint32_t verf_length;
97 uint32_t accept_stat;
98#define RPC_ACCEPTSTAT_SUCCESS 0
99#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
100#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
101#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
102#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
103#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
104#define RPC_ACCEPTSTAT_PROG_LOCKED 6
105 /*
106 * Following data is dependant on accept_stat
107 * If ACCEPTSTAT == PROG_MISMATCH then there is a
108 * 'rpc_reply_progmismatch_data' structure following the header.
109 * Otherwise the data is procedure specific
110 */
111} rpc_accepted_reply_hdr;
112
113struct rpc_reply_hdr
114{
115 uint32_t xid;
116 uint32_t type;
117 uint32_t reply_stat;
118#define RPCMSG_REPLYSTAT_ACCEPTED 0
119#define RPCMSG_REPLYSTAT_DENIED 1
120 union {
121 rpc_accepted_reply_hdr acc_hdr;
122 rpc_denied_reply_hdr dny_hdr;
123 } data;
124};
125
126/* flags for msm_rpc_connect() */
127#define MSM_RPC_UNINTERRUPTIBLE 0x0001
128
129/* use IS_ERR() to check for failure */
130struct msm_rpc_endpoint *msm_rpc_open(void);
131/* Connect with the specified server version */
132struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
133uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
134/* check if server version can handle client requested version */
135int msm_rpc_is_compatible_version(uint32_t server_version,
136 uint32_t client_version);
137
138int msm_rpc_close(struct msm_rpc_endpoint *ept);
139int msm_rpc_write(struct msm_rpc_endpoint *ept,
140 void *data, int len);
141int msm_rpc_read(struct msm_rpc_endpoint *ept,
142 void **data, unsigned len, long timeout);
143void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
144 uint32_t prog, uint32_t vers, uint32_t proc);
145int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
146 uint32_t prog, uint32_t vers);
147int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
148 uint32_t prog, uint32_t vers);
149
150/* simple blocking rpc call
151 *
152 * request is mandatory and must have a rpc_request_hdr
153 * at the start. The header will be filled out for you.
154 *
155 * reply provides a buffer for replies of reply_max_size
156 */
157int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
158 void *request, int request_size,
159 void *reply, int reply_max_size,
160 long timeout);
161int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
162 void *request, int request_size,
163 long timeout);
164
165struct msm_rpc_server
166{
167 struct list_head list;
168 uint32_t flags;
169
170 uint32_t prog;
171 uint32_t vers;
172
173 int (*rpc_call)(struct msm_rpc_server *server,
174 struct rpc_request_hdr *req, unsigned len);
175};
176
177int msm_rpc_create_server(struct msm_rpc_server *server);
178
179#endif
diff --git a/drivers/staging/dream/include/mach/msm_smd.h b/drivers/staging/dream/include/mach/msm_smd.h
deleted file mode 100644
index bdf7731ab680..000000000000
--- a/drivers/staging/dream/include/mach/msm_smd.h
+++ /dev/null
@@ -1,107 +0,0 @@
1/* linux/include/asm-arm/arch-msm/msm_smd.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __ASM_ARCH_MSM_SMD_H
18#define __ASM_ARCH_MSM_SMD_H
19
20typedef struct smd_channel smd_channel_t;
21
22/* warning: notify() may be called before open returns */
23int smd_open(const char *name, smd_channel_t **ch, void *priv,
24 void (*notify)(void *priv, unsigned event));
25
26#define SMD_EVENT_DATA 1
27#define SMD_EVENT_OPEN 2
28#define SMD_EVENT_CLOSE 3
29
30int smd_close(smd_channel_t *ch);
31
32/* passing a null pointer for data reads and discards */
33int smd_read(smd_channel_t *ch, void *data, int len);
34
35/* Write to stream channels may do a partial write and return
36** the length actually written.
37** Write to packet channels will never do a partial write --
38** it will return the requested length written or an error.
39*/
40int smd_write(smd_channel_t *ch, const void *data, int len);
41
42int smd_write_avail(smd_channel_t *ch);
43int smd_read_avail(smd_channel_t *ch);
44
45/* Returns the total size of the current packet being read.
46** Returns 0 if no packets available or a stream channel.
47*/
48int smd_cur_packet_size(smd_channel_t *ch);
49
50/* used for tty unthrottling and the like -- causes the notify()
51** callback to be called from the same lock context as is used
52** when it is called from channel updates
53*/
54void smd_kick(smd_channel_t *ch);
55
56
57#if 0
58/* these are interruptable waits which will block you until the specified
59** number of bytes are readable or writable.
60*/
61int smd_wait_until_readable(smd_channel_t *ch, int bytes);
62int smd_wait_until_writable(smd_channel_t *ch, int bytes);
63#endif
64
65typedef enum
66{
67 SMD_PORT_DS = 0,
68 SMD_PORT_DIAG,
69 SMD_PORT_RPC_CALL,
70 SMD_PORT_RPC_REPLY,
71 SMD_PORT_BT,
72 SMD_PORT_CONTROL,
73 SMD_PORT_MEMCPY_SPARE1,
74 SMD_PORT_DATA1,
75 SMD_PORT_DATA2,
76 SMD_PORT_DATA3,
77 SMD_PORT_DATA4,
78 SMD_PORT_DATA5,
79 SMD_PORT_DATA6,
80 SMD_PORT_DATA7,
81 SMD_PORT_DATA8,
82 SMD_PORT_DATA9,
83 SMD_PORT_DATA10,
84 SMD_PORT_DATA11,
85 SMD_PORT_DATA12,
86 SMD_PORT_DATA13,
87 SMD_PORT_DATA14,
88 SMD_PORT_DATA15,
89 SMD_PORT_DATA16,
90 SMD_PORT_DATA17,
91 SMD_PORT_DATA18,
92 SMD_PORT_DATA19,
93 SMD_PORT_DATA20,
94 SMD_PORT_GPS_NMEA,
95 SMD_PORT_BRIDGE_1,
96 SMD_PORT_BRIDGE_2,
97 SMD_PORT_BRIDGE_3,
98 SMD_PORT_BRIDGE_4,
99 SMD_PORT_BRIDGE_5,
100 SMD_PORT_LOOPBACK,
101 SMD_PORT_CS_APPS_MODEM,
102 SMD_PORT_CS_APPS_DSP,
103 SMD_PORT_CS_MODEM_DSP,
104 SMD_NUM_PORTS,
105} smd_port_id_type;
106
107#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
deleted file mode 100644
index 0b6a31259bb0..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
+++ /dev/null
@@ -1,94 +0,0 @@
1#ifndef QDSP5AUDPLAYCMDI_H
2#define QDSP5AUDPLAYCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S
7
8GENERAL DESCRIPTION
9 Command Interface for AUDPLAYTASK on QDSP5
10
11REFERENCES
12 None
13
14EXTERNALIZED FUNCTIONS
15
16 audplay_cmd_dec_data_avail
17 Send buffer to AUDPLAY task
18
19
20Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
21
22This software is licensed under the terms of the GNU General Public
23License version 2, as published by the Free Software Foundation, and
24may be copied, distributed, and modified under those terms.
25
26This program is distributed in the hope that it will be useful,
27but WITHOUT ANY WARRANTY; without even the implied warranty of
28MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29GNU General Public License for more details.
30
31*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
32/*===========================================================================
33
34 EDIT HISTORY FOR FILE
35
36This section contains comments describing changes made to this file.
37Notice that changes are listed in reverse chronological order.
38
39$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
40
41===========================================================================*/
42
43#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000
44#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \
45 sizeof(audplay_cmd_bitstream_data_avail)
46
47/* Type specification of dec_data_avail message sent to AUDPLAYTASK
48*/
49typedef struct {
50 /*command ID*/
51 unsigned int cmd_id;
52
53 /* Decoder ID for which message is being sent */
54 unsigned int decoder_id;
55
56 /* Start address of data in ARM global memory */
57 unsigned int buf_ptr;
58
59 /* Number of 16-bit words of bit-stream data contiguously available at the
60 * above-mentioned address. */
61 unsigned int buf_size;
62
63 /* Partition number used by audPlayTask to communicate with DSP's RTOS
64 * kernel */
65 unsigned int partition_number;
66} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
67
68#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
69#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
70 sizeof(struct audplay_cmd_hpcm_buf_cfg)
71
72struct audplay_cmd_hpcm_buf_cfg {
73 unsigned int cmd_id;
74 unsigned int hostpcm_config;
75 unsigned int feedback_frequency;
76 unsigned int byte_swap;
77 unsigned int max_buffers;
78 unsigned int partition_number;
79} __attribute__((packed));
80
81#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
82#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
83 sizeof(struct audplay_cmd_buffer_update)
84
85struct audplay_cmd_buffer_refresh {
86 unsigned int cmd_id;
87 unsigned int num_buffers;
88 unsigned int buf_read_count;
89 unsigned int buf0_address;
90 unsigned int buf0_length;
91 unsigned int buf1_address;
92 unsigned int buf1_length;
93} __attribute__((packed));
94#endif /* QDSP5AUDPLAYCMD_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
deleted file mode 100644
index c63034b8bf13..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
+++ /dev/null
@@ -1,70 +0,0 @@
1#ifndef QDSP5AUDPLAYMSG_H
2#define QDSP5AUDPLAYMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P L A Y T A S K M S G
7
8GENERAL DESCRIPTION
9 Message sent by AUDPLAY task
10
11REFERENCES
12 None
13
14
15Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
16
17This software is licensed under the terms of the GNU General Public
18License version 2, as published by the Free Software Foundation, and
19may be copied, distributed, and modified under those terms.
20
21This program is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24GNU General Public License for more details.
25
26*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
27/*===========================================================================
28
29 EDIT HISTORY FOR FILE
30
31This section contains comments describing changes made to this file.
32Notice that changes are listed in reverse chronological order.
33
34$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
35
36===========================================================================*/
37#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001
38#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \
39 sizeof(audplay_msg_dec_needs_data)
40
41typedef struct{
42 /* reserved*/
43 unsigned int dec_id;
44
45 /* The read pointer offset of external memory until which the
46 * bitstream has been DMAed in. */
47 unsigned int adecDataReadPtrOffset;
48
49 /* The buffer size of external memory. */
50 unsigned int adecDataBufSize;
51
52 unsigned int bitstream_free_len;
53 unsigned int bitstream_write_ptr;
54 unsigned int bitstarem_buf_start;
55 unsigned int bitstream_buf_len;
56} __attribute__((packed)) audplay_msg_dec_needs_data;
57
58#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
59#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
60 sizeof(struct audplay_msg_buffer_update)
61
62struct audplay_msg_buffer_update {
63 unsigned int buffer_write_count;
64 unsigned int num_of_buffer;
65 unsigned int buf0_address;
66 unsigned int buf0_length;
67 unsigned int buf1_address;
68 unsigned int buf1_length;
69} __attribute__((packed));
70#endif /* QDSP5AUDPLAYMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
deleted file mode 100644
index 8bee9c62980b..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
+++ /dev/null
@@ -1,914 +0,0 @@
1#ifndef QDSP5AUDPPCMDI_H
2#define QDSP5AUDPPCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDPP Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
38
39===========================================================================*/
40
41/*
42 * ARM to AUDPPTASK Commands
43 *
44 * ARM uses three command queues to communicate with AUDPPTASK
45 * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
46 * Location : MEMA
47 * Buffer Size : 6 words
48 * No of buffers in a queue : 20 for gaming audio and 5 for other images
49 * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
50 * Location : MEMA
51 * Buffer Size : 23
52 * No of buffers in a queue : 2
53 * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
54 * Location : MEMA
55 * Buffer Size : 145
56 * No of buffers in a queue : 3
57 */
58
59/*
60 * Commands Related to uPAudPPCmd1Queue
61 */
62
63/*
64 * Command Structure to enable or disable the active decoders
65 */
66
67#define AUDPP_CMD_CFG_DEC_TYPE 0x0001
68#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type)
69
70/* Enable the decoder */
71#define AUDPP_CMD_DEC_TYPE_M 0x000F
72
73#define AUDPP_CMD_ENA_DEC_V 0x4000
74#define AUDPP_CMD_DIS_DEC_V 0x0000
75#define AUDPP_CMD_DEC_STATE_M 0x4000
76
77#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000
78#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000
79
80
81/* Type specification of cmd_cfg_dec */
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short dec0_cfg;
86 unsigned short dec1_cfg;
87 unsigned short dec2_cfg;
88 unsigned short dec3_cfg;
89 unsigned short dec4_cfg;
90} __attribute__((packed)) audpp_cmd_cfg_dec_type;
91
92/*
93 * Command Structure to Pause , Resume and flushes the selected audio decoders
94 */
95
96#define AUDPP_CMD_DEC_CTRL 0x0002
97#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl)
98
99/* Decoder control commands for pause, resume and flush */
100#define AUDPP_CMD_FLUSH_V 0x2000
101
102#define AUDPP_CMD_PAUSE_V 0x4000
103#define AUDPP_CMD_RESUME_V 0x0000
104
105#define AUDPP_CMD_UPDATE_V 0x8000
106#define AUDPP_CMD_IGNORE_V 0x0000
107
108
109/* Type Spec for decoder control command*/
110
111typedef struct {
112 unsigned short cmd_id;
113 unsigned short dec0_ctrl;
114 unsigned short dec1_ctrl;
115 unsigned short dec2_ctrl;
116 unsigned short dec3_ctrl;
117 unsigned short dec4_ctrl;
118} __attribute__((packed)) audpp_cmd_dec_ctrl;
119
120/*
121 * Command Structure to Configure the AVSync FeedBack Mechanism
122 */
123
124#define AUDPP_CMD_AVSYNC 0x0003
125#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync)
126
127typedef struct {
128 unsigned short cmd_id;
129 unsigned short object_number;
130 unsigned short interrupt_interval_lsw;
131 unsigned short interrupt_interval_msw;
132} __attribute__((packed)) audpp_cmd_avsync;
133
134/*
135 * Command Structure to enable or disable(sleep) the AUDPPTASK
136 */
137
138#define AUDPP_CMD_CFG 0x0004
139#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg)
140
141#define AUDPP_CMD_CFG_SLEEP 0x0000
142#define AUDPP_CMD_CFG_ENABLE 0xFFFF
143
144typedef struct {
145 unsigned short cmd_id;
146 unsigned short cfg;
147} __attribute__((packed)) audpp_cmd_cfg;
148
149/*
150 * Command Structure to Inject or drop the specified no of samples
151 */
152
153#define AUDPP_CMD_ADJUST_SAMP 0x0005
154#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp)
155
156#define AUDPP_CMD_SAMP_DROP -1
157#define AUDPP_CMD_SAMP_INSERT 0x0001
158
159#define AUDPP_CMD_NUM_SAMPLES 0x0001
160
161typedef struct {
162 unsigned short cmd_id;
163 unsigned short object_no;
164 signed short sample_insert_or_drop;
165 unsigned short num_samples;
166} __attribute__((packed)) audpp_cmd_adjust_samp;
167
168/*
169 * Command Structure to Configure AVSync Feedback Mechanism
170 */
171
172#define AUDPP_CMD_AVSYNC_CMD_2 0x0006
173#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2)
174
175typedef struct {
176 unsigned short cmd_id;
177 unsigned short object_number;
178 unsigned short interrupt_interval_lsw;
179 unsigned short interrupt_interval_msw;
180 unsigned short sample_counter_dlsw;
181 unsigned short sample_counter_dmsw;
182 unsigned short sample_counter_msw;
183 unsigned short byte_counter_dlsw;
184 unsigned short byte_counter_dmsw;
185 unsigned short byte_counter_msw;
186} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
187
188/*
189 * Command Structure to Configure AVSync Feedback Mechanism
190 */
191
192#define AUDPP_CMD_AVSYNC_CMD_3 0x0007
193#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3)
194
195typedef struct {
196 unsigned short cmd_id;
197 unsigned short object_number;
198 unsigned short interrupt_interval_lsw;
199 unsigned short interrupt_interval_msw;
200 unsigned short sample_counter_dlsw;
201 unsigned short sample_counter_dmsw;
202 unsigned short sample_counter_msw;
203 unsigned short byte_counter_dlsw;
204 unsigned short byte_counter_dmsw;
205 unsigned short byte_counter_msw;
206} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
207
208#define AUDPP_CMD_ROUTING_MODE 0x0008
209#define AUDPP_CMD_ROUTING_MODE_LEN \
210sizeof(struct audpp_cmd_routing_mode)
211
212struct audpp_cmd_routing_mode {
213 unsigned short cmd_id;
214 unsigned short object_number;
215 unsigned short routing_mode;
216} __attribute__((packed));
217
218/*
219 * Commands Related to uPAudPPCmd2Queue
220 */
221
222/*
223 * Command Structure to configure Per decoder Parameters (Common)
224 */
225
226#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000
227#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \
228 sizeof(audpp_cmd_cfg_adec_params_common)
229
230#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000
231#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000
232
233#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000
234#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000
235
236/* Sampling frequency*/
237#define AUDPP_CMD_SAMP_RATE_96000 0x0000
238#define AUDPP_CMD_SAMP_RATE_88200 0x0001
239#define AUDPP_CMD_SAMP_RATE_64000 0x0002
240#define AUDPP_CMD_SAMP_RATE_48000 0x0003
241#define AUDPP_CMD_SAMP_RATE_44100 0x0004
242#define AUDPP_CMD_SAMP_RATE_32000 0x0005
243#define AUDPP_CMD_SAMP_RATE_24000 0x0006
244#define AUDPP_CMD_SAMP_RATE_22050 0x0007
245#define AUDPP_CMD_SAMP_RATE_16000 0x0008
246#define AUDPP_CMD_SAMP_RATE_12000 0x0009
247#define AUDPP_CMD_SAMP_RATE_11025 0x000A
248#define AUDPP_CMD_SAMP_RATE_8000 0x000B
249
250
251/*
252 * Type specification of cmd_adec_cfg sent to all decoder
253 */
254
255typedef struct {
256 unsigned short cmd_id;
257 unsigned short length;
258 unsigned short dec_id;
259 unsigned short status_msg_flag;
260 unsigned short decoder_frame_counter_msg_period;
261 unsigned short input_sampling_frequency;
262} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
263
264/*
265 * Command Structure to configure Per decoder Parameters (Wav)
266 */
267
268#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \
269 sizeof(audpp_cmd_cfg_adec_params_wav)
270
271
272#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001
273#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002
274
275#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000
276#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001
277#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002
278
279typedef struct {
280 audpp_cmd_cfg_adec_params_common common;
281 unsigned short stereo_cfg;
282 unsigned short pcm_width;
283 unsigned short sign;
284} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
285
286/*
287 * Command Structure to configure Per decoder Parameters (ADPCM)
288 */
289
290#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \
291 sizeof(audpp_cmd_cfg_adec_params_adpcm)
292
293
294#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001
295#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002
296
297typedef struct {
298 audpp_cmd_cfg_adec_params_common common;
299 unsigned short stereo_cfg;
300 unsigned short block_size;
301} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
302
303/*
304 * Command Structure to configure Per decoder Parameters (MP3)
305 */
306
307#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \
308 sizeof(audpp_cmd_cfg_adec_params_mp3)
309
310typedef struct {
311 audpp_cmd_cfg_adec_params_common common;
312} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
313
314
315/*
316 * Command Structure to configure Per decoder Parameters (AAC)
317 */
318
319#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \
320 sizeof(audpp_cmd_cfg_adec_params_aac)
321
322
323#define AUDPP_CMD_AAC_FORMAT_ADTS -1
324#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000
325#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001
326#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002
327
328#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002
329#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004
330#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011
331
332#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001
333#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000
334
335#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001
336#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000
337
338typedef struct {
339 audpp_cmd_cfg_adec_params_common common;
340 signed short format;
341 unsigned short audio_object;
342 unsigned short ep_config;
343 unsigned short aac_section_data_resilience_flag;
344 unsigned short aac_scalefactor_data_resilience_flag;
345 unsigned short aac_spectral_data_resilience_flag;
346 unsigned short sbr_on_flag;
347 unsigned short sbr_ps_on_flag;
348 unsigned short dual_mono_mode;
349 unsigned short channel_configuration;
350} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
351
352/*
353 * Command Structure to configure Per decoder Parameters (V13K)
354 */
355
356#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \
357 sizeof(struct audpp_cmd_cfg_adec_params_v13k)
358
359
360#define AUDPP_CMD_STEREO_CFG_MONO 0x0001
361#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002
362
363struct audpp_cmd_cfg_adec_params_v13k {
364 audpp_cmd_cfg_adec_params_common common;
365 unsigned short stereo_cfg;
366} __attribute__((packed));
367
368#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
369 sizeof(struct audpp_cmd_cfg_adec_params_evrc)
370
371struct audpp_cmd_cfg_adec_params_evrc {
372 audpp_cmd_cfg_adec_params_common common;
373 unsigned short stereo_cfg;
374} __attribute__ ((packed));
375
376/*
377 * Command Structure to configure the HOST PCM interface
378 */
379
380#define AUDPP_CMD_PCM_INTF 0x0001
381#define AUDPP_CMD_PCM_INTF_2 0x0002
382#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf)
383
384#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001
385#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002
386
387/* These two values differentiate the two types of commands that could be issued
388 * Interface configuration command and Buffer update command */
389
390#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000
391#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1
392
393#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F
394#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008
395#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004
396
397/* These flags control the enabling and disabling of the interface together
398 * with host interface bit mask. */
399
400#define AUDPP_CMD_PCM_INTF_ENA_V -1
401#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000
402
403
404#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0
405#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1
406
407
408#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5
409#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6
410
411
412typedef struct {
413 unsigned short cmd_id;
414 unsigned short object_num;
415 signed short config;
416 unsigned short intf_type;
417
418 /* DSP -> ARM Configuration */
419 unsigned short read_buf1LSW;
420 unsigned short read_buf1MSW;
421 unsigned short read_buf1_len;
422
423 unsigned short read_buf2LSW;
424 unsigned short read_buf2MSW;
425 unsigned short read_buf2_len;
426 /* 0:HOST_PCM_INTF disable
427 ** 0xFFFF: HOST_PCM_INTF enable
428 */
429 signed short dsp_to_arm_flag;
430 unsigned short partition_number;
431
432 /* ARM -> DSP Configuration */
433 unsigned short write_buf1LSW;
434 unsigned short write_buf1MSW;
435 unsigned short write_buf1_len;
436
437 unsigned short write_buf2LSW;
438 unsigned short write_buf2MSW;
439 unsigned short write_buf2_len;
440
441 /* 0:HOST_PCM_INTF disable
442 ** 0xFFFF: HOST_PCM_INTF enable
443 */
444 signed short arm_to_rx_flag;
445 unsigned short weight_decoder_to_rx;
446 unsigned short weight_arm_to_rx;
447
448 unsigned short partition_number_arm_to_dsp;
449 unsigned short sample_rate;
450 unsigned short channel_mode;
451} __attribute__((packed)) audpp_cmd_pcm_intf;
452
453/*
454 ** BUFFER UPDATE COMMAND
455 */
456#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \
457 sizeof(audpp_cmd_pcm_intf_send_buffer)
458
459typedef struct {
460 unsigned short cmd_id;
461 unsigned short host_pcm_object;
462 /* set config = 0xFFFF for configuration*/
463 signed short config;
464 unsigned short intf_type;
465 unsigned short dsp_to_arm_buf_id;
466 unsigned short arm_to_dsp_buf_id;
467 unsigned short arm_to_dsp_buf_len;
468} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
469
470
471/*
472 * Commands Related to uPAudPPCmd3Queue
473 */
474
475/*
476 * Command Structure to configure post processing params (Commmon)
477 */
478
479#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000
480#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \
481 sizeof(audpp_cmd_cfg_object_params_common)
482
483#define AUDPP_CMD_OBJ0_UPDATE 0x8000
484#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000
485
486#define AUDPP_CMD_OBJ1_UPDATE 0x8000
487#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000
488
489#define AUDPP_CMD_OBJ2_UPDATE 0x8000
490#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000
491
492#define AUDPP_CMD_OBJ3_UPDATE 0x8000
493#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000
494
495#define AUDPP_CMD_OBJ4_UPDATE 0x8000
496#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000
497
498#define AUDPP_CMD_HPCM_UPDATE 0x8000
499#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000
500
501#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000
502#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000
503
504typedef struct {
505 unsigned short cmd_id;
506 unsigned short obj0_cfg;
507 unsigned short obj1_cfg;
508 unsigned short obj2_cfg;
509 unsigned short obj3_cfg;
510 unsigned short obj4_cfg;
511 unsigned short host_pcm_obj_cfg;
512 unsigned short comman_cfg;
513 unsigned short command_type;
514} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
515
516/*
517 * Command Structure to configure post processing params (Volume)
518 */
519
520#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \
521 sizeof(audpp_cmd_cfg_object_params_volume)
522
523typedef struct {
524 audpp_cmd_cfg_object_params_common common;
525 unsigned short volume;
526 unsigned short pan;
527} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
528
529/*
530 * Command Structure to configure post processing params (PCM Filter) --DOUBT
531 */
532
533typedef struct {
534 unsigned short numerator_b0_filter_lsw;
535 unsigned short numerator_b0_filter_msw;
536 unsigned short numerator_b1_filter_lsw;
537 unsigned short numerator_b1_filter_msw;
538 unsigned short numerator_b2_filter_lsw;
539 unsigned short numerator_b2_filter_msw;
540} __attribute__((packed)) numerator;
541
542typedef struct {
543 unsigned short denominator_a0_filter_lsw;
544 unsigned short denominator_a0_filter_msw;
545 unsigned short denominator_a1_filter_lsw;
546 unsigned short denominator_a1_filter_msw;
547} __attribute__((packed)) denominator;
548
549typedef struct {
550 unsigned short shift_factor_0;
551} __attribute__((packed)) shift_factor;
552
553typedef struct {
554 unsigned short pan_filter_0;
555} __attribute__((packed)) pan;
556
557typedef struct {
558 numerator numerator_filter;
559 denominator denominator_filter;
560 shift_factor shift_factor_filter;
561 pan pan_filter;
562} __attribute__((packed)) filter_1;
563
564typedef struct {
565 numerator numerator_filter[2];
566 denominator denominator_filter[2];
567 shift_factor shift_factor_filter[2];
568 pan pan_filter[2];
569} __attribute__((packed)) filter_2;
570
571typedef struct {
572 numerator numerator_filter[3];
573 denominator denominator_filter[3];
574 shift_factor shift_factor_filter[3];
575 pan pan_filter[3];
576} __attribute__((packed)) filter_3;
577
578typedef struct {
579 numerator numerator_filter[4];
580 denominator denominator_filter[4];
581 shift_factor shift_factor_filter[4];
582 pan pan_filter[4];
583} __attribute__((packed)) filter_4;
584
585#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \
586 sizeof(audpp_cmd_cfg_object_params_pcm)
587
588
589typedef struct {
590 audpp_cmd_cfg_object_params_common common;
591 unsigned short active_flag;
592 unsigned short num_bands;
593 union {
594 filter_1 filter_1_params;
595 filter_2 filter_2_params;
596 filter_3 filter_3_params;
597 filter_4 filter_4_params;
598 } __attribute__((packed)) params_filter;
599} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
600
601
602/*
603 * Command Structure to configure post processing parameters (equalizer)
604 */
605
606#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \
607 sizeof(audpp_cmd_cfg_object_params_eqalizer)
608
609typedef struct {
610 unsigned short numerator_coeff_0_lsw;
611 unsigned short numerator_coeff_0_msw;
612 unsigned short numerator_coeff_1_lsw;
613 unsigned short numerator_coeff_1_msw;
614 unsigned short numerator_coeff_2_lsw;
615 unsigned short numerator_coeff_2_msw;
616} __attribute__((packed)) eq_numerator;
617
618typedef struct {
619 unsigned short denominator_coeff_0_lsw;
620 unsigned short denominator_coeff_0_msw;
621 unsigned short denominator_coeff_1_lsw;
622 unsigned short denominator_coeff_1_msw;
623} __attribute__((packed)) eq_denominator;
624
625typedef struct {
626 unsigned short shift_factor;
627} __attribute__((packed)) eq_shiftfactor;
628
629typedef struct {
630 eq_numerator numerator;
631 eq_denominator denominator;
632 eq_shiftfactor shiftfactor;
633} __attribute__((packed)) eq_coeff_1;
634
635typedef struct {
636 eq_numerator numerator[2];
637 eq_denominator denominator[2];
638 eq_shiftfactor shiftfactor[2];
639} __attribute__((packed)) eq_coeff_2;
640
641typedef struct {
642 eq_numerator numerator[3];
643 eq_denominator denominator[3];
644 eq_shiftfactor shiftfactor[3];
645} __attribute__((packed)) eq_coeff_3;
646
647typedef struct {
648 eq_numerator numerator[4];
649 eq_denominator denominator[4];
650 eq_shiftfactor shiftfactor[4];
651} __attribute__((packed)) eq_coeff_4;
652
653typedef struct {
654 eq_numerator numerator[5];
655 eq_denominator denominator[5];
656 eq_shiftfactor shiftfactor[5];
657} __attribute__((packed)) eq_coeff_5;
658
659typedef struct {
660 eq_numerator numerator[6];
661 eq_denominator denominator[6];
662 eq_shiftfactor shiftfactor[6];
663} __attribute__((packed)) eq_coeff_6;
664
665typedef struct {
666 eq_numerator numerator[7];
667 eq_denominator denominator[7];
668 eq_shiftfactor shiftfactor[7];
669} __attribute__((packed)) eq_coeff_7;
670
671typedef struct {
672 eq_numerator numerator[8];
673 eq_denominator denominator[8];
674 eq_shiftfactor shiftfactor[8];
675} __attribute__((packed)) eq_coeff_8;
676
677typedef struct {
678 eq_numerator numerator[9];
679 eq_denominator denominator[9];
680 eq_shiftfactor shiftfactor[9];
681} __attribute__((packed)) eq_coeff_9;
682
683typedef struct {
684 eq_numerator numerator[10];
685 eq_denominator denominator[10];
686 eq_shiftfactor shiftfactor[10];
687} __attribute__((packed)) eq_coeff_10;
688
689typedef struct {
690 eq_numerator numerator[11];
691 eq_denominator denominator[11];
692 eq_shiftfactor shiftfactor[11];
693} __attribute__((packed)) eq_coeff_11;
694
695typedef struct {
696 eq_numerator numerator[12];
697 eq_denominator denominator[12];
698 eq_shiftfactor shiftfactor[12];
699} __attribute__((packed)) eq_coeff_12;
700
701
702typedef struct {
703 audpp_cmd_cfg_object_params_common common;
704 unsigned short eq_flag;
705 unsigned short num_bands;
706 union {
707 eq_coeff_1 eq_coeffs_1;
708 eq_coeff_2 eq_coeffs_2;
709 eq_coeff_3 eq_coeffs_3;
710 eq_coeff_4 eq_coeffs_4;
711 eq_coeff_5 eq_coeffs_5;
712 eq_coeff_6 eq_coeffs_6;
713 eq_coeff_7 eq_coeffs_7;
714 eq_coeff_8 eq_coeffs_8;
715 eq_coeff_9 eq_coeffs_9;
716 eq_coeff_10 eq_coeffs_10;
717 eq_coeff_11 eq_coeffs_11;
718 eq_coeff_12 eq_coeffs_12;
719 } __attribute__((packed)) eq_coeff;
720} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
721
722
723/*
724 * Command Structure to configure post processing parameters (ADRC)
725 */
726
727#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \
728 sizeof(audpp_cmd_cfg_object_params_adrc)
729
730
731#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000
732#define AUDPP_CMD_ADRC_FLAG_ENA -1
733
734typedef struct {
735 audpp_cmd_cfg_object_params_common common;
736 signed short adrc_flag;
737 unsigned short compression_th;
738 unsigned short compression_slope;
739 unsigned short rms_time;
740 unsigned short attack_const_lsw;
741 unsigned short attack_const_msw;
742 unsigned short release_const_lsw;
743 unsigned short release_const_msw;
744 unsigned short adrc_system_delay;
745} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
746
747/*
748 * Command Structure to configure post processing parameters(Spectrum Analizer)
749 */
750
751#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \
752 sizeof(audpp_cmd_cfg_object_params_spectram)
753
754
755typedef struct {
756 audpp_cmd_cfg_object_params_common common;
757 unsigned short sample_interval;
758 unsigned short num_coeff;
759} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
760
761/*
762 * Command Structure to configure post processing parameters (QConcert)
763 */
764
765#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \
766 sizeof(audpp_cmd_cfg_object_params_qconcert)
767
768
769#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1
770#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000
771
772#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1
773#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000
774#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001
775#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002
776
777#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF
778#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027
779
780
781#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF
782
783
784typedef struct {
785 audpp_cmd_cfg_object_params_common common;
786 signed short enable_flag;
787 signed short output_mode;
788 signed short gain;
789 signed short expansion;
790 signed short delay;
791 unsigned short stages_per_mode;
792} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
793
794/*
795 * Command Structure to configure post processing parameters (Side Chain)
796 */
797
798#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \
799 sizeof(audpp_cmd_cfg_object_params_sidechain)
800
801
802#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000
803#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1
804
805typedef struct {
806 audpp_cmd_cfg_object_params_common common;
807 signed short active_flag;
808 unsigned short num_bands;
809 union {
810 filter_1 filter_1_params;
811 filter_2 filter_2_params;
812 filter_3 filter_3_params;
813 filter_4 filter_4_params;
814 } __attribute__((packed)) params_filter;
815} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
816
817
818/*
819 * Command Structure to configure post processing parameters (QAFX)
820 */
821
822#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \
823 sizeof(audpp_cmd_cfg_object_params_qafx)
824
825#define AUDPP_CMD_QAFX_ENA_DISA 0x0000
826#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1
827#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001
828
829#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100
830#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010
831#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000
832
833#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100
834#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101
835#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102
836#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103
837#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107
838
839#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010
840#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011
841#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012
842#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013
843#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014
844
845
846typedef struct {
847 audpp_cmd_cfg_object_params_common common;
848 signed short enable;
849 unsigned short command_type;
850 unsigned short num_commands;
851 unsigned short commands;
852} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
853
854/*
855 * Command Structure to enable , disable or configure the reverberation effect
856 * (Common)
857 */
858
859#define AUDPP_CMD_REVERB_CONFIG 0x0001
860#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \
861 sizeof(audpp_cmd_reverb_config_common)
862
863#define AUDPP_CMD_ENA_ENA 0xFFFF
864#define AUDPP_CMD_ENA_DIS 0x0000
865#define AUDPP_CMD_ENA_CFG 0x0001
866
867#define AUDPP_CMD_CMD_TYPE_ENV 0x0104
868#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015
869#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000
870
871
872typedef struct {
873 unsigned short cmd_id;
874 unsigned short enable;
875 unsigned short cmd_type;
876} __attribute__((packed)) audpp_cmd_reverb_config_common;
877
878/*
879 * Command Structure to enable , disable or configure the reverberation effect
880 * (ENV-0x0104)
881 */
882
883#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \
884 sizeof(audpp_cmd_reverb_config_env_104)
885
886typedef struct {
887 audpp_cmd_reverb_config_common common;
888 unsigned short env_gain;
889 unsigned short decay_msw;
890 unsigned short decay_lsw;
891 unsigned short decay_timeratio_msw;
892 unsigned short decay_timeratio_lsw;
893 unsigned short delay_time;
894 unsigned short reverb_gain;
895 unsigned short reverb_delay;
896} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
897
898/*
899 * Command Structure to enable , disable or configure the reverberation effect
900 * (ENV-0x0015)
901 */
902
903#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \
904 sizeof(audpp_cmd_reverb_config_env_15)
905
906typedef struct {
907 audpp_cmd_reverb_config_common common;
908 unsigned short object_num;
909 unsigned short absolute_gain;
910} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
911
912
913#endif /* QDSP5AUDPPCMDI_H */
914
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
deleted file mode 100644
index 44fea224001a..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
+++ /dev/null
@@ -1,318 +0,0 @@
1#ifndef QDSP5AUDPPMSG_H
2#define QDSP5AUDPPMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
7
8GENERAL DESCRIPTION
9 Messages sent by AUDPPTASK to ARM
10
11REFERENCES
12 None
13
14EXTERNALIZED FUNCTIONS
15 None
16
17Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
18
19This software is licensed under the terms of the GNU General Public
20License version 2, as published by the Free Software Foundation, and
21may be copied, distributed, and modified under those terms.
22
23This program is distributed in the hope that it will be useful,
24but WITHOUT ANY WARRANTY; without even the implied warranty of
25MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26GNU General Public License for more details.
27
28*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
29/*===========================================================================
30
31 EDIT HISTORY FOR FILE
32
33This section contains comments describing changes made to this file.
34Notice that changes are listed in reverse chronological order.
35
36 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
37
38===========================================================================*/
39
40/*
41 * AUDPPTASK uses audPPuPRlist to send messages to the ARM
42 * Location : MEMA
43 * Buffer Size : 45
44 * No of Buffers in a queue : 5 for gaming audio and 1 for other images
45 */
46
47/*
48 * MSG to Informs the ARM os Success/Failure of bringing up the decoder
49 */
50
51#define AUDPP_MSG_STATUS_MSG 0x0001
52#define AUDPP_MSG_STATUS_MSG_LEN \
53 sizeof(audpp_msg_status_msg)
54
55#define AUDPP_MSG_STATUS_SLEEP 0x0000
56#define AUDPP_MSG__STATUS_INIT 0x0001
57#define AUDPP_MSG_MSG_STATUS_CFG 0x0002
58#define AUDPP_MSG_STATUS_PLAY 0x0003
59
60#define AUDPP_MSG_REASON_MIPS 0x0000
61#define AUDPP_MSG_REASON_MEM 0x0001
62
63typedef struct{
64 unsigned short dec_id;
65 unsigned short status;
66 unsigned short reason;
67} __attribute__((packed)) audpp_msg_status_msg;
68
69/*
70 * MSG to communicate the spectrum analyzer output bands to the ARM
71 */
72#define AUDPP_MSG_SPA_BANDS 0x0002
73#define AUDPP_MSG_SPA_BANDS_LEN \
74 sizeof(audpp_msg_spa_bands)
75
76typedef struct {
77 unsigned short current_object;
78 unsigned short spa_band_1;
79 unsigned short spa_band_2;
80 unsigned short spa_band_3;
81 unsigned short spa_band_4;
82 unsigned short spa_band_5;
83 unsigned short spa_band_6;
84 unsigned short spa_band_7;
85 unsigned short spa_band_8;
86 unsigned short spa_band_9;
87 unsigned short spa_band_10;
88 unsigned short spa_band_11;
89 unsigned short spa_band_12;
90 unsigned short spa_band_13;
91 unsigned short spa_band_14;
92 unsigned short spa_band_15;
93 unsigned short spa_band_16;
94 unsigned short spa_band_17;
95 unsigned short spa_band_18;
96 unsigned short spa_band_19;
97 unsigned short spa_band_20;
98 unsigned short spa_band_21;
99 unsigned short spa_band_22;
100 unsigned short spa_band_23;
101 unsigned short spa_band_24;
102 unsigned short spa_band_25;
103 unsigned short spa_band_26;
104 unsigned short spa_band_27;
105 unsigned short spa_band_28;
106 unsigned short spa_band_29;
107 unsigned short spa_band_30;
108 unsigned short spa_band_31;
109 unsigned short spa_band_32;
110} __attribute__((packed)) audpp_msg_spa_bands;
111
112/*
113 * MSG to communicate the PCM I/O buffer status to ARM
114 */
115#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003
116#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \
117 sizeof(audpp_msg_host_pcm_intf_msg)
118
119#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000
120#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001
121#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002
122#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003
123
124#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000
125#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001
126#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002
127#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003
128#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004
129#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005
130#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006
131#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007
132#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008
133#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009
134#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A
135#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B
136
137#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001
138#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002
139
140typedef struct{
141 unsigned short obj_num;
142 unsigned short numbers_of_samples;
143 unsigned short host_pcm_id;
144 unsigned short buf_indx;
145 unsigned short samp_freq_indx;
146 unsigned short channel_mode;
147} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
148
149
150/*
151 * MSG to communicate 3D position of the source and listener , source volume
152 * source rolloff, source orientation
153 */
154
155#define AUDPP_MSG_QAFX_POS 0x0004
156#define AUDPP_MSG_QAFX_POS_LEN \
157 sizeof(audpp_msg_qafx_pos)
158
159typedef struct {
160 unsigned short current_object;
161 unsigned short x_pos_lis_msw;
162 unsigned short x_pos_lis_lsw;
163 unsigned short y_pos_lis_msw;
164 unsigned short y_pos_lis_lsw;
165 unsigned short z_pos_lis_msw;
166 unsigned short z_pos_lis_lsw;
167 unsigned short x_fwd_msw;
168 unsigned short x_fwd_lsw;
169 unsigned short y_fwd_msw;
170 unsigned short y_fwd_lsw;
171 unsigned short z_fwd_msw;
172 unsigned short z_fwd_lsw;
173 unsigned short x_up_msw;
174 unsigned short x_up_lsw;
175 unsigned short y_up_msw;
176 unsigned short y_up_lsw;
177 unsigned short z_up_msw;
178 unsigned short z_up_lsw;
179 unsigned short x_vel_lis_msw;
180 unsigned short x_vel_lis_lsw;
181 unsigned short y_vel_lis_msw;
182 unsigned short y_vel_lis_lsw;
183 unsigned short z_vel_lis_msw;
184 unsigned short z_vel_lis_lsw;
185 unsigned short threed_enable_flag;
186 unsigned short volume;
187 unsigned short x_pos_source_msw;
188 unsigned short x_pos_source_lsw;
189 unsigned short y_pos_source_msw;
190 unsigned short y_pos_source_lsw;
191 unsigned short z_pos_source_msw;
192 unsigned short z_pos_source_lsw;
193 unsigned short max_dist_0_msw;
194 unsigned short max_dist_0_lsw;
195 unsigned short min_dist_0_msw;
196 unsigned short min_dist_0_lsw;
197 unsigned short roll_off_factor;
198 unsigned short mute_after_max_flag;
199 unsigned short x_vel_source_msw;
200 unsigned short x_vel_source_lsw;
201 unsigned short y_vel_source_msw;
202 unsigned short y_vel_source_lsw;
203 unsigned short z_vel_source_msw;
204 unsigned short z_vel_source_lsw;
205} __attribute__((packed)) audpp_msg_qafx_pos;
206
207/*
208 * MSG to provide AVSYNC feedback from DSP to ARM
209 */
210
211#define AUDPP_MSG_AVSYNC_MSG 0x0005
212#define AUDPP_MSG_AVSYNC_MSG_LEN \
213 sizeof(audpp_msg_avsync_msg)
214
215typedef struct {
216 unsigned short active_flag;
217 unsigned short num_samples_counter0_HSW;
218 unsigned short num_samples_counter0_MSW;
219 unsigned short num_samples_counter0_LSW;
220 unsigned short num_bytes_counter0_HSW;
221 unsigned short num_bytes_counter0_MSW;
222 unsigned short num_bytes_counter0_LSW;
223 unsigned short samp_freq_obj_0;
224 unsigned short samp_freq_obj_1;
225 unsigned short samp_freq_obj_2;
226 unsigned short samp_freq_obj_3;
227 unsigned short samp_freq_obj_4;
228 unsigned short samp_freq_obj_5;
229 unsigned short samp_freq_obj_6;
230 unsigned short samp_freq_obj_7;
231 unsigned short samp_freq_obj_8;
232 unsigned short samp_freq_obj_9;
233 unsigned short samp_freq_obj_10;
234 unsigned short samp_freq_obj_11;
235 unsigned short samp_freq_obj_12;
236 unsigned short samp_freq_obj_13;
237 unsigned short samp_freq_obj_14;
238 unsigned short samp_freq_obj_15;
239 unsigned short num_samples_counter4_HSW;
240 unsigned short num_samples_counter4_MSW;
241 unsigned short num_samples_counter4_LSW;
242 unsigned short num_bytes_counter4_HSW;
243 unsigned short num_bytes_counter4_MSW;
244 unsigned short num_bytes_counter4_LSW;
245} __attribute__((packed)) audpp_msg_avsync_msg;
246
247/*
248 * MSG to provide PCM DMA Missed feedback from the DSP to ARM
249 */
250
251#define AUDPP_MSG_PCMDMAMISSED 0x0006
252#define AUDPP_MSG_PCMDMAMISSED_LEN \
253 sizeof(audpp_msg_pcmdmamissed);
254
255typedef struct{
256 /*
257 ** Bit 0 0 = PCM DMA not missed for object 0
258 ** 1 = PCM DMA missed for object0
259 ** Bit 1 0 = PCM DMA not missed for object 1
260 ** 1 = PCM DMA missed for object1
261 ** Bit 2 0 = PCM DMA not missed for object 2
262 ** 1 = PCM DMA missed for object2
263 ** Bit 3 0 = PCM DMA not missed for object 3
264 ** 1 = PCM DMA missed for object3
265 ** Bit 4 0 = PCM DMA not missed for object 4
266 ** 1 = PCM DMA missed for object4
267 */
268 unsigned short pcmdmamissed;
269} __attribute__((packed)) audpp_msg_pcmdmamissed;
270
271/*
272 * MSG to AUDPP enable or disable feedback form DSP to ARM
273 */
274
275#define AUDPP_MSG_CFG_MSG 0x0007
276#define AUDPP_MSG_CFG_MSG_LEN \
277 sizeof(audpp_msg_cfg_msg)
278
279#define AUDPP_MSG_ENA_ENA 0xFFFF
280#define AUDPP_MSG_ENA_DIS 0x0000
281
282typedef struct{
283 /* Enabled - 0xffff
284 ** Disabled - 0
285 */
286 unsigned short enabled;
287} __attribute__((packed)) audpp_msg_cfg_msg;
288
289/*
290 * MSG to communicate the reverb per object volume
291 */
292
293#define AUDPP_MSG_QREVERB_VOLUME 0x0008
294#define AUDPP_MSG_QREVERB_VOLUME_LEN \
295 sizeof(audpp_msg_qreverb_volume)
296
297
298typedef struct {
299 unsigned short obj_0_gain;
300 unsigned short obj_1_gain;
301 unsigned short obj_2_gain;
302 unsigned short obj_3_gain;
303 unsigned short obj_4_gain;
304 unsigned short hpcm_obj_volume;
305} __attribute__((packed)) audpp_msg_qreverb_volume;
306
307#define AUDPP_MSG_ROUTING_ACK 0x0009
308#define AUDPP_MSG_ROUTING_ACK_LEN \
309 sizeof(struct audpp_msg_routing_ack)
310
311struct audpp_msg_routing_ack {
312 unsigned short dec_id;
313 unsigned short routing_mode;
314} __attribute__((packed));
315
316#define AUDPP_MSG_FLUSH_ACK 0x000A
317
318#endif /* QDSP5AUDPPMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
deleted file mode 100644
index 06d33d571583..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
+++ /dev/null
@@ -1,256 +0,0 @@
1#ifndef QDSP5AUDPREPROCCMDI_H
2#define QDSP5AUDPREPROCCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDPREPROC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
38
39===========================================================================*/
40
41/*
42 * AUDIOPREPROC COMMANDS:
43 * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
44 * Location : MEMB
45 * Buffer size : 51
46 * Number of buffers in a queue : 3
47 */
48
49/*
50 * Command to configure the parameters of AGC
51 */
52
53#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000
54#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \
55 sizeof(audpreproc_cmd_cfg_agc_params)
56
57#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009
58#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A
59#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B
60#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C
61#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D
62#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E
63#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F
64
65#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1
66#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000
67
68#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1
69#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000
70
71#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004
72#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005
73#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006
74#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007
75#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008
76#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009
77#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A
78#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B
79#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C
80#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D
81#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E
82#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F
83
84typedef struct {
85 unsigned short cmd_id;
86 unsigned short tx_agc_param_mask;
87 unsigned short tx_agc_enable_flag;
88 unsigned short static_gain;
89 signed short adaptive_gain_flag;
90 unsigned short expander_th;
91 unsigned short expander_slope;
92 unsigned short compressor_th;
93 unsigned short compressor_slope;
94 unsigned short param_mask;
95 unsigned short aig_attackk;
96 unsigned short aig_leak_down;
97 unsigned short aig_leak_up;
98 unsigned short aig_max;
99 unsigned short aig_min;
100 unsigned short aig_releasek;
101 unsigned short aig_leakrate_fast;
102 unsigned short aig_leakrate_slow;
103 unsigned short attackk_msw;
104 unsigned short attackk_lsw;
105 unsigned short delay;
106 unsigned short releasek_msw;
107 unsigned short releasek_lsw;
108 unsigned short rms_tav;
109} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
110
111
112/*
113 * Command to configure the params of Advanved AGC
114 */
115
116#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001
117#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \
118 sizeof(audpreproc_cmd_cfg_agc_params_2)
119
120#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1;
121#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000;
122
123typedef struct {
124 unsigned short cmd_id;
125 unsigned short agc_param_mask;
126 signed short tx_agc_enable_flag;
127 unsigned short comp_static_gain;
128 unsigned short exp_th;
129 unsigned short exp_slope;
130 unsigned short comp_th;
131 unsigned short comp_slope;
132 unsigned short comp_rms_tav;
133 unsigned short comp_samp_mask;
134 unsigned short comp_attackk_msw;
135 unsigned short comp_attackk_lsw;
136 unsigned short comp_releasek_msw;
137 unsigned short comp_releasek_lsw;
138 unsigned short comp_delay;
139 unsigned short comp_makeup_gain;
140} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
141
142/*
143 * Command to configure params for ns
144 */
145
146#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002
147#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \
148 sizeof(audpreproc_cmd_cfg_ns_params)
149
150#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001
151#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000
152#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002
153#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000
154#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004
155#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000
156#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008
157#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000
158
159#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010
160#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000
161#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020
162#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000
163#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040
164#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000
165#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080
166#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000
167#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100
168#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000
169#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200
170#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000
171#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400
172#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000
173#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800
174#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000
175#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000
176#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000
177
178typedef struct {
179 unsigned short cmd_id;
180 unsigned short ec_mode_new;
181 unsigned short dens_gamma_n;
182 unsigned short dens_nfe_block_size;
183 unsigned short dens_limit_ns;
184 unsigned short dens_limit_ns_d;
185 unsigned short wb_gamma_e;
186 unsigned short wb_gamma_n;
187} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
188
189/*
190 * Command to configure parameters for IIR tuning filter
191 */
192
193#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003
194#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \
195 sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
196
197#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000
198#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001
199
200typedef struct {
201 unsigned short cmd_id;
202 unsigned short active_flag;
203 unsigned short num_bands;
204 unsigned short numerator_coeff_b0_filter0_lsw;
205 unsigned short numerator_coeff_b0_filter0_msw;
206 unsigned short numerator_coeff_b1_filter0_lsw;
207 unsigned short numerator_coeff_b1_filter0_msw;
208 unsigned short numerator_coeff_b2_filter0_lsw;
209 unsigned short numerator_coeff_b2_filter0_msw;
210 unsigned short numerator_coeff_b0_filter1_lsw;
211 unsigned short numerator_coeff_b0_filter1_msw;
212 unsigned short numerator_coeff_b1_filter1_lsw;
213 unsigned short numerator_coeff_b1_filter1_msw;
214 unsigned short numerator_coeff_b2_filter1_lsw;
215 unsigned short numerator_coeff_b2_filter1_msw;
216 unsigned short numerator_coeff_b0_filter2_lsw;
217 unsigned short numerator_coeff_b0_filter2_msw;
218 unsigned short numerator_coeff_b1_filter2_lsw;
219 unsigned short numerator_coeff_b1_filter2_msw;
220 unsigned short numerator_coeff_b2_filter2_lsw;
221 unsigned short numerator_coeff_b2_filter2_msw;
222 unsigned short numerator_coeff_b0_filter3_lsw;
223 unsigned short numerator_coeff_b0_filter3_msw;
224 unsigned short numerator_coeff_b1_filter3_lsw;
225 unsigned short numerator_coeff_b1_filter3_msw;
226 unsigned short numerator_coeff_b2_filter3_lsw;
227 unsigned short numerator_coeff_b2_filter3_msw;
228 unsigned short denominator_coeff_a0_filter0_lsw;
229 unsigned short denominator_coeff_a0_filter0_msw;
230 unsigned short denominator_coeff_a1_filter0_lsw;
231 unsigned short denominator_coeff_a1_filter0_msw;
232 unsigned short denominator_coeff_a0_filter1_lsw;
233 unsigned short denominator_coeff_a0_filter1_msw;
234 unsigned short denominator_coeff_a1_filter1_lsw;
235 unsigned short denominator_coeff_a1_filter1_msw;
236 unsigned short denominator_coeff_a0_filter2_lsw;
237 unsigned short denominator_coeff_a0_filter2_msw;
238 unsigned short denominator_coeff_a1_filter2_lsw;
239 unsigned short denominator_coeff_a1_filter2_msw;
240 unsigned short denominator_coeff_a0_filter3_lsw;
241 unsigned short denominator_coeff_a0_filter3_msw;
242 unsigned short denominator_coeff_a1_filter3_lsw;
243 unsigned short denominator_coeff_a1_filter3_msw;
244
245 unsigned short shift_factor_filter0;
246 unsigned short shift_factor_filter1;
247 unsigned short shift_factor_filter2;
248 unsigned short shift_factor_filter3;
249
250 unsigned short channel_selected0;
251 unsigned short channel_selected1;
252 unsigned short channel_selected2;
253 unsigned short channel_selected3;
254} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
255
256#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
deleted file mode 100644
index f40e41e76737..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
+++ /dev/null
@@ -1,85 +0,0 @@
1#ifndef QDSP5AUDPREPROCMSG_H
2#define QDSP5AUDPREPROCMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P R E P R O C E S S I N G M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are rcvd by AUDPREPROC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
38
39===========================================================================*/
40
41/*
42 * ADSPREPROCTASK Messages
43 * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
44 * Location : MEMA
45 * Message Length : 2
46 */
47
48/*
49 * Message to indicate particular feature has been enabled or disabled
50 */
51
52
53#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000
54#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \
55 sizeof(audpreproc_msg_cmd_cfg_done_msg)
56
57#define AUDPREPROC_MSG_TYPE_AGC 0x0000
58#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001
59#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002
60
61
62#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1
63#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000
64
65typedef struct {
66 unsigned short type;
67 signed short status_flag;
68} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
69
70
71/*
72 * Message to indicate particular feature has selected for wrong samp freq
73 */
74
75#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001
76#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \
77 sizeof(audpreproc_msg_error_msg_id)
78
79#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000
80
81typedef struct {
82 unsigned short err_index;
83} __attribute__((packed)) audpreproc_msg_error_msg_id;
84
85#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
deleted file mode 100644
index d03ee024ae91..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
+++ /dev/null
@@ -1,176 +0,0 @@
1#ifndef QDSP5AUDRECCMDI_H
2#define QDSP5AUDRECCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O R E C O R D I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDREC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30
31/*===========================================================================
32
33 EDIT HISTORY FOR FILE
34
35This section contains comments describing changes made to this file.
36Notice that changes are listed in reverse chronological order.
37
38 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
39
40============================================================================*/
41
42/*
43 * AUDRECTASK COMMANDS
44 * ARM uses 2 queues to communicate with the AUDRECTASK
45 * 1.uPAudRecCmdQueue
46 * Location :MEMC
47 * Buffer Size : 8
48 * No of Buffers in a queue : 3
49 * 2.audRecUpBitStreamQueue
50 * Location : MEMC
51 * Buffer Size : 4
52 * No of buffers in a queue : 2
53 */
54
55/*
56 * Commands on uPAudRecCmdQueue
57 */
58
59/*
60 * Command to initiate and terminate the audio recording section
61 */
62
63#define AUDREC_CMD_CFG 0x0000
64#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg)
65
66#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000
67#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001
68
69#define AUDREC_CMD_TYPE_0_ENA 0x4000
70#define AUDREC_CMD_TYPE_0_DIS 0x0000
71
72#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000
73#define AUDREC_CMD_TYPE_0_UPDATE 0x8000
74
75#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002
76
77#define AUDREC_CMD_TYPE_1_ENA 0x4000
78#define AUDREC_CMD_TYPE_1_DIS 0x0000
79
80#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000
81#define AUDREC_CMD_TYPE_1_UPDATE 0x8000
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short type_0;
86 unsigned short type_1;
87} __attribute__((packed)) audrec_cmd_cfg;
88
89
90/*
91 * Command to configure the recording parameters for RecType0(AAC/WAV) encoder
92 */
93
94#define AUDREC_CMD_AREC0PARAM_CFG 0x0001
95#define AUDREC_CMD_AREC0PARAM_CFG_LEN \
96 sizeof(audrec_cmd_arec0param_cfg)
97
98#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B
99#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A
100#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009
101#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008
102#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007
103#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006
104#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005
105#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004
106#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003
107
108#define AUDREC_CMD_STEREO_MODE_MONO 0x0000
109#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001
110
111typedef struct {
112 unsigned short cmd_id;
113 unsigned short ptr_to_extpkt_buffer_msw;
114 unsigned short ptr_to_extpkt_buffer_lsw;
115 unsigned short buf_len;
116 unsigned short samp_rate_index;
117 unsigned short stereo_mode;
118 unsigned short rec_quality;
119} __attribute__((packed)) audrec_cmd_arec0param_cfg;
120
121/*
122 * Command to configure the recording parameters for RecType1(SBC) encoder
123 */
124
125#define AUDREC_CMD_AREC1PARAM_CFG 0x0002
126#define AUDREC_CMD_AREC1PARAM_CFG_LEN \
127 sizeof(audrec_cmd_arec1param_cfg)
128
129#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000
130#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001
131#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002
132#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003
133
134#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010
135#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000
136#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040
137#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050
138#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060
139#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000
140#define AUDREC_CMD_PARAM_BUF_SNR 0x0100
141#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000
142
143typedef struct {
144 unsigned short cmd_id;
145 unsigned short ptr_to_extpkt_buffer_msw;
146 unsigned short ptr_to_extpkt_buffer_lsw;
147 unsigned short buf_len;
148 unsigned short param_buf;
149 unsigned short bit_rate_0;
150 unsigned short bit_rate_1;
151} __attribute__((packed)) audrec_cmd_arec1param_cfg;
152
153
154/*
155 * Commands on audRecUpBitStreamQueue
156 */
157
158/*
159 * Command to indicate the current packet read count
160 */
161
162#define AUDREC_CMD_PACKET_EXT_PTR 0x0000
163#define AUDREC_CMD_PACKET_EXT_PTR_LEN \
164 sizeof(audrec_cmd_packet_ext_ptr)
165
166#define AUDREC_CMD_TYPE_0 0x0000
167#define AUDREC_CMD_TYPE_1 0x0001
168
169typedef struct {
170 unsigned short cmd_id;
171 unsigned short type;
172 unsigned short curr_rec_count_msw;
173 unsigned short curr_rec_count_lsw;
174} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
175
176#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
deleted file mode 100644
index bb6eb5093cf5..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
+++ /dev/null
@@ -1,127 +0,0 @@
1#ifndef QDSP5AUDRECMSGI_H
2#define QDSP5AUDRECMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O R E C O R D M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by AUDREC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30
31/*===========================================================================
32
33 EDIT HISTORY FOR FILE
34
35This section contains comments describing changes made to this file.
36Notice that changes are listed in reverse chronological order.
37
38 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
39
40============================================================================*/
41
42/*
43 * AUDRECTASK MESSAGES
44 * AUDRECTASK uses audRecUpRlist to communicate with ARM
45 * Location : MEMC
46 * Buffer size : 4
47 * No of buffers in a queue : 2
48 */
49
50/*
51 * Message to notify that config command is done
52 */
53
54#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002
55#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \
56 sizeof(audrec_msg_cmd_cfg_done_msg)
57
58
59#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000
60#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000
61
62#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000
63#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000
64
65#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000
66#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000
67
68#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000
69#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000
70
71typedef struct {
72 unsigned short type_0;
73 unsigned short type_1;
74} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
75
76
77/*
78 * Message to notify arec0/1 cfg done and recording params revd by task
79 */
80
81#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003
82#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \
83 sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
84
85#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000
86#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001
87
88typedef struct {
89 unsigned short type;
90} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
91
92
93/*
94 * Message to notify no more buffers are available in ext mem to DME
95 */
96
97#define AUDREC_MSG_FATAL_ERR_MSG 0x0004
98#define AUDREC_MSG_FATAL_ERR_MSG_LEN \
99 sizeof(audrec_msg_fatal_err_msg)
100
101#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000
102#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001
103
104typedef struct {
105 unsigned short type;
106} __attribute__((packed))audrec_msg_fatal_err_msg;
107
108/*
109 * Message to notify DME deliverd the encoded pkt to ext pkt buffer
110 */
111
112#define AUDREC_MSG_PACKET_READY_MSG 0x0005
113#define AUDREC_MSG_PACKET_READY_MSG_LEN \
114 sizeof(audrec_msg_packet_ready_msg)
115
116#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000
117#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001
118
119typedef struct {
120 unsigned short type;
121 unsigned short pkt_counter_msw;
122 unsigned short pkt_counter_lsw;
123 unsigned short pkt_read_cnt_msw;
124 unsigned short pkt_read_cnt_lsw;
125} __attribute__((packed))audrec_msg_packet_ready_msg;
126
127#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
deleted file mode 100644
index 574ad6bbcade..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
+++ /dev/null
@@ -1,376 +0,0 @@
1#ifndef QDSP5VIDJPEGCMDI_H
2#define QDSP5VIDJPEGCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 J P E G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by JPEG Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39when who what, where, why
40-------- --- ----------------------------------------------------------
4106/09/08 sv initial version
42===========================================================================*/
43
44/*
45 * ARM to JPEG configuration commands are passed through the
46 * uPJpegCfgCmdQueue
47 */
48
49/*
50 * Command to configure JPEG Encoder
51 */
52
53#define JPEG_CMD_ENC_CFG 0x0000
54#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg)
55
56#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000
57#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100
58#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200
59#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300
60#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003
61#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000
62#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001
63#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002
64
65#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF
66#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000
67#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001
68#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000
69
70#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF
71
72typedef struct {
73 unsigned int cmd_id;
74 unsigned int process_cfg;
75 unsigned int ip_size_cfg;
76 unsigned int op_size_cfg;
77 unsigned int frag_cfg;
78 unsigned int frag_cfg_part[16];
79
80 unsigned int part_num;
81
82 unsigned int op_buf_0_cfg_part1;
83 unsigned int op_buf_0_cfg_part2;
84 unsigned int op_buf_1_cfg_part1;
85 unsigned int op_buf_1_cfg_part2;
86
87 unsigned int luma_qunt_table[32];
88 unsigned int chroma_qunt_table[32];
89
90 unsigned int upsamp_ip_size_cfg;
91 unsigned int upsamp_ip_frame_off;
92 unsigned int upsamp_pp_filter_coeff[64];
93} __attribute__((packed)) jpeg_cmd_enc_cfg;
94
95/*
96 * Command to configure JPEG Decoder
97 */
98
99#define JPEG_CMD_DEC_CFG 0x0001
100#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg)
101
102#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001
103#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000
104#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001
105
106#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000
107#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000
108#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000
109#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000
110
111#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000
112#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001
113
114
115typedef struct {
116 unsigned int cmd_id;
117 unsigned int img_dimension_cfg;
118 unsigned int op_data_format;
119 unsigned int restart_interval;
120 unsigned int ip_buf_partition_num;
121 unsigned int ip_stream_buf_cfg_part1;
122 unsigned int ip_stream_buf_cfg_part2;
123 unsigned int ip_stream_buf_cfg_part3;
124 unsigned int op_stream_buf_0_cfg_part1;
125 unsigned int op_stream_buf_0_cfg_part2;
126 unsigned int op_stream_buf_0_cfg_part3;
127 unsigned int op_stream_buf_1_cfg_part1;
128 unsigned int op_stream_buf_1_cfg_part2;
129 unsigned int op_stream_buf_1_cfg_part3;
130 unsigned int luma_qunt_table_0_3;
131 unsigned int luma_qunt_table_4_7;
132 unsigned int luma_qunt_table_8_11;
133 unsigned int luma_qunt_table_12_15;
134 unsigned int luma_qunt_table_16_19;
135 unsigned int luma_qunt_table_20_23;
136 unsigned int luma_qunt_table_24_27;
137 unsigned int luma_qunt_table_28_31;
138 unsigned int luma_qunt_table_32_35;
139 unsigned int luma_qunt_table_36_39;
140 unsigned int luma_qunt_table_40_43;
141 unsigned int luma_qunt_table_44_47;
142 unsigned int luma_qunt_table_48_51;
143 unsigned int luma_qunt_table_52_55;
144 unsigned int luma_qunt_table_56_59;
145 unsigned int luma_qunt_table_60_63;
146 unsigned int chroma_qunt_table_0_3;
147 unsigned int chroma_qunt_table_4_7;
148 unsigned int chroma_qunt_table_8_11;
149 unsigned int chroma_qunt_table_12_15;
150 unsigned int chroma_qunt_table_16_19;
151 unsigned int chroma_qunt_table_20_23;
152 unsigned int chroma_qunt_table_24_27;
153 unsigned int chroma_qunt_table_28_31;
154 unsigned int chroma_qunt_table_32_35;
155 unsigned int chroma_qunt_table_36_39;
156 unsigned int chroma_qunt_table_40_43;
157 unsigned int chroma_qunt_table_44_47;
158 unsigned int chroma_qunt_table_48_51;
159 unsigned int chroma_qunt_table_52_55;
160 unsigned int chroma_qunt_table_56_59;
161 unsigned int chroma_qunt_table_60_63;
162 unsigned int luma_dc_hm_code_cnt_table_0_3;
163 unsigned int luma_dc_hm_code_cnt_table_4_7;
164 unsigned int luma_dc_hm_code_cnt_table_8_11;
165 unsigned int luma_dc_hm_code_cnt_table_12_15;
166 unsigned int luma_dc_hm_code_val_table_0_3;
167 unsigned int luma_dc_hm_code_val_table_4_7;
168 unsigned int luma_dc_hm_code_val_table_8_11;
169 unsigned int chroma_dc_hm_code_cnt_table_0_3;
170 unsigned int chroma_dc_hm_code_cnt_table_4_7;
171 unsigned int chroma_dc_hm_code_cnt_table_8_11;
172 unsigned int chroma_dc_hm_code_cnt_table_12_15;
173 unsigned int chroma_dc_hm_code_val_table_0_3;
174 unsigned int chroma_dc_hm_code_val_table_4_7;
175 unsigned int chroma_dc_hm_code_val_table_8_11;
176 unsigned int luma_ac_hm_code_cnt_table_0_3;
177 unsigned int luma_ac_hm_code_cnt_table_4_7;
178 unsigned int luma_ac_hm_code_cnt_table_8_11;
179 unsigned int luma_ac_hm_code_cnt_table_12_15;
180 unsigned int luma_ac_hm_code_val_table_0_3;
181 unsigned int luma_ac_hm_code_val_table_4_7;
182 unsigned int luma_ac_hm_code_val_table_8_11;
183 unsigned int luma_ac_hm_code_val_table_12_15;
184 unsigned int luma_ac_hm_code_val_table_16_19;
185 unsigned int luma_ac_hm_code_val_table_20_23;
186 unsigned int luma_ac_hm_code_val_table_24_27;
187 unsigned int luma_ac_hm_code_val_table_28_31;
188 unsigned int luma_ac_hm_code_val_table_32_35;
189 unsigned int luma_ac_hm_code_val_table_36_39;
190 unsigned int luma_ac_hm_code_val_table_40_43;
191 unsigned int luma_ac_hm_code_val_table_44_47;
192 unsigned int luma_ac_hm_code_val_table_48_51;
193 unsigned int luma_ac_hm_code_val_table_52_55;
194 unsigned int luma_ac_hm_code_val_table_56_59;
195 unsigned int luma_ac_hm_code_val_table_60_63;
196 unsigned int luma_ac_hm_code_val_table_64_67;
197 unsigned int luma_ac_hm_code_val_table_68_71;
198 unsigned int luma_ac_hm_code_val_table_72_75;
199 unsigned int luma_ac_hm_code_val_table_76_79;
200 unsigned int luma_ac_hm_code_val_table_80_83;
201 unsigned int luma_ac_hm_code_val_table_84_87;
202 unsigned int luma_ac_hm_code_val_table_88_91;
203 unsigned int luma_ac_hm_code_val_table_92_95;
204 unsigned int luma_ac_hm_code_val_table_96_99;
205 unsigned int luma_ac_hm_code_val_table_100_103;
206 unsigned int luma_ac_hm_code_val_table_104_107;
207 unsigned int luma_ac_hm_code_val_table_108_111;
208 unsigned int luma_ac_hm_code_val_table_112_115;
209 unsigned int luma_ac_hm_code_val_table_116_119;
210 unsigned int luma_ac_hm_code_val_table_120_123;
211 unsigned int luma_ac_hm_code_val_table_124_127;
212 unsigned int luma_ac_hm_code_val_table_128_131;
213 unsigned int luma_ac_hm_code_val_table_132_135;
214 unsigned int luma_ac_hm_code_val_table_136_139;
215 unsigned int luma_ac_hm_code_val_table_140_143;
216 unsigned int luma_ac_hm_code_val_table_144_147;
217 unsigned int luma_ac_hm_code_val_table_148_151;
218 unsigned int luma_ac_hm_code_val_table_152_155;
219 unsigned int luma_ac_hm_code_val_table_156_159;
220 unsigned int luma_ac_hm_code_val_table_160_161;
221 unsigned int chroma_ac_hm_code_cnt_table_0_3;
222 unsigned int chroma_ac_hm_code_cnt_table_4_7;
223 unsigned int chroma_ac_hm_code_cnt_table_8_11;
224 unsigned int chroma_ac_hm_code_cnt_table_12_15;
225 unsigned int chroma_ac_hm_code_val_table_0_3;
226 unsigned int chroma_ac_hm_code_val_table_4_7;
227 unsigned int chroma_ac_hm_code_val_table_8_11;
228 unsigned int chroma_ac_hm_code_val_table_12_15;
229 unsigned int chroma_ac_hm_code_val_table_16_19;
230 unsigned int chroma_ac_hm_code_val_table_20_23;
231 unsigned int chroma_ac_hm_code_val_table_24_27;
232 unsigned int chroma_ac_hm_code_val_table_28_31;
233 unsigned int chroma_ac_hm_code_val_table_32_35;
234 unsigned int chroma_ac_hm_code_val_table_36_39;
235 unsigned int chroma_ac_hm_code_val_table_40_43;
236 unsigned int chroma_ac_hm_code_val_table_44_47;
237 unsigned int chroma_ac_hm_code_val_table_48_51;
238 unsigned int chroma_ac_hm_code_val_table_52_55;
239 unsigned int chroma_ac_hm_code_val_table_56_59;
240 unsigned int chroma_ac_hm_code_val_table_60_63;
241 unsigned int chroma_ac_hm_code_val_table_64_67;
242 unsigned int chroma_ac_hm_code_val_table_68_71;
243 unsigned int chroma_ac_hm_code_val_table_72_75;
244 unsigned int chroma_ac_hm_code_val_table_76_79;
245 unsigned int chroma_ac_hm_code_val_table_80_83;
246 unsigned int chroma_ac_hm_code_val_table_84_87;
247 unsigned int chroma_ac_hm_code_val_table_88_91;
248 unsigned int chroma_ac_hm_code_val_table_92_95;
249 unsigned int chroma_ac_hm_code_val_table_96_99;
250 unsigned int chroma_ac_hm_code_val_table_100_103;
251 unsigned int chroma_ac_hm_code_val_table_104_107;
252 unsigned int chroma_ac_hm_code_val_table_108_111;
253 unsigned int chroma_ac_hm_code_val_table_112_115;
254 unsigned int chroma_ac_hm_code_val_table_116_119;
255 unsigned int chroma_ac_hm_code_val_table_120_123;
256 unsigned int chroma_ac_hm_code_val_table_124_127;
257 unsigned int chroma_ac_hm_code_val_table_128_131;
258 unsigned int chroma_ac_hm_code_val_table_132_135;
259 unsigned int chroma_ac_hm_code_val_table_136_139;
260 unsigned int chroma_ac_hm_code_val_table_140_143;
261 unsigned int chroma_ac_hm_code_val_table_144_147;
262 unsigned int chroma_ac_hm_code_val_table_148_151;
263 unsigned int chroma_ac_hm_code_val_table_152_155;
264 unsigned int chroma_ac_hm_code_val_table_156_159;
265 unsigned int chroma_ac_hm_code_val_table_160_161;
266} __attribute__((packed)) jpeg_cmd_dec_cfg;
267
268
269/*
270 * ARM to JPEG configuration commands are passed through the
271 * uPJpegActionCmdQueue
272 */
273
274/*
275 * Command to start the encode process
276 */
277
278#define JPEG_CMD_ENC_ENCODE 0x0000
279#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode)
280
281
282typedef struct {
283 unsigned short cmd_id;
284} __attribute__((packed)) jpeg_cmd_enc_encode;
285
286
287/*
288 * Command to transition from current state of encoder to IDLE state
289 */
290
291#define JPEG_CMD_ENC_IDLE 0x0001
292#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle)
293
294
295typedef struct {
296 unsigned short cmd_id;
297} __attribute__((packed)) jpeg_cmd_enc_idle;
298
299
300/*
301 * Command to inform the encoder that another buffer is ready
302 */
303
304#define JPEG_CMD_ENC_OP_CONSUMED 0x0002
305#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed)
306
307
308typedef struct {
309 unsigned int cmd_id;
310 unsigned int op_buf_addr;
311 unsigned int op_buf_size;
312} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
313
314
315/*
316 * Command to start the decoding process
317 */
318
319#define JPEG_CMD_DEC_DECODE 0x0003
320#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode)
321
322
323typedef struct {
324 unsigned short cmd_id;
325} __attribute__((packed)) jpeg_cmd_dec_decode;
326
327
328/*
329 * Command to transition from the current state of decoder to IDLE
330 */
331
332#define JPEG_CMD_DEC_IDLE 0x0004
333#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle)
334
335
336typedef struct {
337 unsigned short cmd_id;
338} __attribute__((packed)) jpeg_cmd_dec_idle;
339
340
341/*
342 * Command to inform that an op buffer is ready for use
343 */
344
345#define JPEG_CMD_DEC_OP_CONSUMED 0x0005
346#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed)
347
348
349typedef struct {
350 unsigned int cmd_id;
351 unsigned int luma_op_buf_addr;
352 unsigned int luma_op_buf_size;
353 unsigned int chroma_op_buf_addr;
354} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
355
356
357/*
358 * Command to pass a new ip buffer to the jpeg decoder
359 */
360
361#define JPEG_CMD_DEC_IP 0x0006
362#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len)
363
364#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000
365#define JPEG_CMD_EOI_INDICATOR_END 0x0001
366
367typedef struct {
368 unsigned int cmd_id;
369 unsigned int ip_buf_addr;
370 unsigned int ip_buf_size;
371 unsigned int eoi_indicator;
372} __attribute__((packed)) jpeg_cmd_dec_ip;
373
374
375
376#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
deleted file mode 100644
index d11aa3fbccb6..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
+++ /dev/null
@@ -1,177 +0,0 @@
1#ifndef QDSP5VIDJPEGMSGI_H
2#define QDSP5VIDJPEGMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 J P E G I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by JPEG Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 sv initial version
43===========================================================================*/
44
45/*
46 * Messages from JPEG task to ARM through jpeguPMsgQueue
47 */
48
49/*
50 * Message is ACK for CMD_JPEGE_ENCODE cmd
51 */
52
53#define JPEG_MSG_ENC_ENCODE_ACK 0x0000
54#define JPEG_MSG_ENC_ENCODE_ACK_LEN \
55 sizeof(jpeg_msg_enc_encode_ack)
56
57typedef struct {
58} __attribute__((packed)) jpeg_msg_enc_encode_ack;
59
60
61/*
62 * Message informs the up when op buffer is ready for consumption and
63 * when encoding is complete or errors
64 */
65
66#define JPEG_MSG_ENC_OP_PRODUCED 0x0001
67#define JPEG_MSG_ENC_OP_PRODUCED_LEN \
68 sizeof(jpeg_msg_enc_op_produced)
69
70#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000
71#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001
72#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000
73
74typedef struct {
75 unsigned int op_buf_addr;
76 unsigned int op_buf_size;
77 unsigned int op_buf_status;
78} __attribute__((packed)) jpeg_msg_enc_op_produced;
79
80
81/*
82 * Message to ack CMD_JPEGE_IDLE
83 */
84
85#define JPEG_MSG_ENC_IDLE_ACK 0x0002
86#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack)
87
88
89typedef struct {
90} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
91
92
93/*
94 * Message to indicate the illegal command
95 */
96
97#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003
98#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \
99 sizeof(jpeg_msg_enc_illegal_command)
100
101typedef struct {
102 unsigned int status;
103} __attribute__((packed)) jpeg_msg_enc_illegal_command;
104
105
106/*
107 * Message to ACK CMD_JPEGD_DECODE
108 */
109
110#define JPEG_MSG_DEC_DECODE_ACK 0x0004
111#define JPEG_MSG_DEC_DECODE_ACK_LEN \
112 sizeof(jpeg_msg_dec_decode_ack)
113
114
115typedef struct {
116} __attribute__((packed)) jpeg_msg_dec_decode_ack;
117
118
119/*
120 * Message to inform up that an op buffer is ready for consumption and when
121 * decoding is complete or an error occurs
122 */
123
124#define JPEG_MSG_DEC_OP_PRODUCED 0x0005
125#define JPEG_MSG_DEC_OP_PRODUCED_LEN \
126 sizeof(jpeg_msg_dec_op_produced)
127
128#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000
129#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001
130
131typedef struct {
132 unsigned int luma_op_buf_addr;
133 unsigned int chroma_op_buf_addr;
134 unsigned int num_mcus;
135 unsigned int op_buf_status;
136} __attribute__((packed)) jpeg_msg_dec_op_produced;
137
138/*
139 * Message to ack CMD_JPEGD_IDLE cmd
140 */
141
142#define JPEG_MSG_DEC_IDLE_ACK 0x0006
143#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack)
144
145
146typedef struct {
147} __attribute__((packed)) jpeg_msg_dec_idle_ack;
148
149
150/*
151 * Message to indicate illegal cmd was received
152 */
153
154#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007
155#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \
156 sizeof(jpeg_msg_dec_illegal_command)
157
158
159typedef struct {
160 unsigned int status;
161} __attribute__((packed)) jpeg_msg_dec_illegal_command;
162
163/*
164 * Message to request up for the next segment of ip bit stream
165 */
166
167#define JPEG_MSG_DEC_IP_REQUEST 0x0008
168#define JPEG_MSG_DEC_IP_REQUEST_LEN \
169 sizeof(jpeg_msg_dec_ip_request)
170
171
172typedef struct {
173} __attribute__((packed)) jpeg_msg_dec_ip_request;
174
175
176
177#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
deleted file mode 100644
index 6c76e2c20cf4..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
+++ /dev/null
@@ -1,82 +0,0 @@
1#ifndef QDSP5LPMCMDI_H
2#define QDSP5LPMCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 L P M I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by LPM Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37
38$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
39Revision History:
40
41when who what, where, why
42-------- --- ----------------------------------------------------------
4306/12/08 sv initial version
44===========================================================================*/
45
46
47/*
48 * Command to start LPM processing based on the config params
49 */
50
51#define LPM_CMD_START 0x0000
52#define LPM_CMD_START_LEN sizeof(lpm_cmd_start)
53
54#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000
55#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000
56typedef struct {
57 unsigned int cmd_id;
58 unsigned int ip_data_cfg_part1;
59 unsigned int ip_data_cfg_part2;
60 unsigned int ip_data_cfg_part3;
61 unsigned int ip_data_cfg_part4;
62 unsigned int op_data_cfg_part1;
63 unsigned int op_data_cfg_part2;
64 unsigned int op_data_cfg_part3;
65 unsigned int spatial_filter_part[32];
66} __attribute__((packed)) lpm_cmd_start;
67
68
69
70/*
71 * Command to stop LPM processing
72 */
73
74#define LPM_CMD_IDLE 0x0001
75#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle)
76
77typedef struct {
78 unsigned int cmd_id;
79} __attribute__((packed)) lpm_cmd_idle;
80
81
82#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
deleted file mode 100644
index 3d1039d6ba42..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
+++ /dev/null
@@ -1,80 +0,0 @@
1#ifndef QDSP5LPMMSGI_H
2#define QDSP5LPMMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 L P M I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by LPM Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45/*
46 * Message to acknowledge CMD_LPM_IDLE command
47 */
48
49#define LPM_MSG_IDLE_ACK 0x0000
50#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack)
51
52typedef struct {
53} __attribute__((packed)) lpm_msg_idle_ack;
54
55
56/*
57 * Message to acknowledge CMD_LPM_START command
58 */
59
60
61#define LPM_MSG_START_ACK 0x0001
62#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack)
63
64
65typedef struct {
66} __attribute__((packed)) lpm_msg_start_ack;
67
68
69/*
70 * Message to notify the ARM that LPM processing is complete
71 */
72
73#define LPM_MSG_DONE 0x0002
74#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done)
75
76typedef struct {
77} __attribute__((packed)) lpm_msg_done;
78
79
80#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
deleted file mode 100644
index 3a32ee99c6e4..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
+++ /dev/null
@@ -1,235 +0,0 @@
1#ifndef QDSP5VIDDECCMDI_H
2#define QDSP5VIDDECCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O D E C O D E R I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VIDDEC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 ac initial version
43===========================================================================*/
44
45
46/*
47 * Command to inform VIDDEC that new subframe packet is ready
48 */
49
50#define VIDDEC_CMD_SUBFRAME_PKT 0x0000
51#define VIDDEC_CMD_SUBFRAME_PKT_LEN \
52 sizeof(viddec_cmd_subframe_pkt)
53
54#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000
55#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001
56
57#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000
58#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001
59#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002
60#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003
61
62#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000
63#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001
64#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002
65#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003
66#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004
67#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005
68#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006
69#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007
70#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008
71
72typedef struct {
73 unsigned short cmd_id;
74 unsigned short packet_seq_number;
75 unsigned short codec_instance_id;
76 unsigned short subframe_packet_size_high;
77 unsigned short subframe_packet_size_low;
78 unsigned short subframe_packet_high;
79 unsigned short subframe_packet_low;
80 unsigned short subframe_packet_partition;
81 unsigned short statistics_packet_size_high;
82 unsigned short statistics_packet_size_low;
83 unsigned short statistics_packet_high;
84 unsigned short statistics_packet_low;
85 unsigned short statistics_partition;
86 unsigned short subframe_info_1;
87 unsigned short subframe_info_0;
88 unsigned short codec_selection_word;
89 unsigned short num_mbs;
90} __attribute__((packed)) viddec_cmd_subframe_pkt;
91
92
93/*
94 * Command to inform VIDDEC task that post processing is required for the frame
95 */
96
97#define VIDDEC_CMD_PP_ENABLE 0x0001
98#define VIDDEC_CMD_PP_ENABLE_LEN \
99 sizeof(viddec_cmd_pp_enable)
100
101#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000
102#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001
103
104typedef struct {
105 unsigned short cmd_id;
106 unsigned short packet_seq_num;
107 unsigned short codec_instance_id;
108 unsigned short postproc_info_0;
109 unsigned short codec_selection_word;
110 unsigned short pp_output_addr_high;
111 unsigned short pp_output_addr_low;
112 unsigned short postproc_info_1;
113 unsigned short load_sharing_packet_size_high;
114 unsigned short load_sharing_packet_size_low;
115 unsigned short load_sharing_packet_high;
116 unsigned short load_sharing_packet_low;
117 unsigned short load_sharing_partition;
118 unsigned short pp_param_0;
119 unsigned short pp_param_1;
120 unsigned short pp_param_2;
121 unsigned short pp_param_3;
122} __attribute__((packed)) viddec_cmd_pp_enable;
123
124
125/*
126 * FRAME Header Packet : It is at the start of new frame
127 */
128
129#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002
130#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \
131 sizeof(viddec_cmd_frame_header_packet)
132
133#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000
134#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800
135
136typedef struct {
137 unsigned short packet_id;
138 unsigned short x_dimension;
139 unsigned short y_dimension;
140 unsigned short line_width;
141 unsigned short frame_info_0;
142 unsigned short frame_buffer_0_high;
143 unsigned short frame_buffer_0_low;
144 unsigned short frame_buffer_1_high;
145 unsigned short frame_buffer_1_low;
146 unsigned short frame_buffer_2_high;
147 unsigned short frame_buffer_2_low;
148 unsigned short frame_buffer_3_high;
149 unsigned short frame_buffer_3_low;
150 unsigned short frame_buffer_4_high;
151 unsigned short frame_buffer_4_low;
152 unsigned short frame_buffer_5_high;
153 unsigned short frame_buffer_5_low;
154 unsigned short frame_buffer_6_high;
155 unsigned short frame_buffer_6_low;
156 unsigned short frame_buffer_7_high;
157 unsigned short frame_buffer_7_low;
158 unsigned short frame_buffer_8_high;
159 unsigned short frame_buffer_8_low;
160 unsigned short frame_buffer_9_high;
161 unsigned short frame_buffer_9_low;
162 unsigned short frame_buffer_10_high;
163 unsigned short frame_buffer_10_low;
164 unsigned short frame_buffer_11_high;
165 unsigned short frame_buffer_11_low;
166 unsigned short frame_buffer_12_high;
167 unsigned short frame_buffer_12_low;
168 unsigned short frame_buffer_13_high;
169 unsigned short frame_buffer_13_low;
170 unsigned short frame_buffer_14_high;
171 unsigned short frame_buffer_14_low;
172 unsigned short frame_buffer_15_high;
173 unsigned short frame_buffer_15_low;
174 unsigned short output_frame_buffer_high;
175 unsigned short output_frame_buffer_low;
176 unsigned short end_of_packet_marker;
177} __attribute__((packed)) viddec_cmd_frame_header_packet;
178
179
180/*
181 * SLICE HEADER PACKET
182 * I-Slice and P-Slice
183 */
184
185#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003
186#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \
187 sizeof(viddec_cmd_slice_header_pkt_islice)
188
189#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000
190#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100
191#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200
192#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300
193#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400
194#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000
195#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800
196
197#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF
198
199typedef struct {
200 unsigned short cmd_id;
201 unsigned short packet_id;
202 unsigned short slice_info_0;
203 unsigned short slice_info_1;
204 unsigned short slice_info_2;
205 unsigned short num_bytes_in_rbsp_high;
206 unsigned short num_bytes_in_rbsp_low;
207 unsigned short num_bytes_in_rbsp_consumed;
208 unsigned short end_of_packet_marker;
209} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
210
211
212#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003
213#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \
214 sizeof(viddec_cmd_slice_header_pkt_pslice)
215
216
217typedef struct {
218 unsigned short cmd_id;
219 unsigned short packet_id;
220 unsigned short slice_info_0;
221 unsigned short slice_info_1;
222 unsigned short slice_info_2;
223 unsigned short slice_info_3;
224 unsigned short refidx_l0_map_tab_info_0;
225 unsigned short refidx_l0_map_tab_info_1;
226 unsigned short refidx_l0_map_tab_info_2;
227 unsigned short refidx_l0_map_tab_info_3;
228 unsigned short num_bytes_in_rbsp_high;
229 unsigned short num_bytes_in_rbsp_low;
230 unsigned short num_bytes_in_rbsp_consumed;
231 unsigned short end_of_packet_marker;
232} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
233
234
235#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
deleted file mode 100644
index c1744c1644dd..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
+++ /dev/null
@@ -1,107 +0,0 @@
1#ifndef QDSP5VIDDECMSGI_H
2#define QDSP5VIDDECMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O D E C O D E R I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by VIDDEC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 ac initial version
43===========================================================================*/
44
45/*
46 * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
47 */
48
49#define VIDDEC_MSG_SUBF_DONE 0x0000
50#define VIDDEC_MSG_SUBF_DONE_LEN \
51 sizeof(viddec_msg_subf_done)
52
53typedef struct {
54 unsigned short packet_seq_number;
55 unsigned short codec_instance_id;
56} __attribute__((packed)) viddec_msg_subf_done;
57
58
59/*
60 * Message to inform ARM one frame has been decoded
61 */
62
63#define VIDDEC_MSG_FRAME_DONE 0x0001
64#define VIDDEC_MSG_FRAME_DONE_LEN \
65 sizeof(viddec_msg_frame_done)
66
67typedef struct {
68 unsigned short packet_seq_number;
69 unsigned short codec_instance_id;
70} __attribute__((packed)) viddec_msg_frame_done;
71
72
73/*
74 * Message to inform ARM that post processing frame has been decoded
75 */
76
77#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002
78#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \
79 sizeof(viddec_msg_pp_enable_cmd_done)
80
81typedef struct {
82 unsigned short packet_seq_number;
83 unsigned short codec_instance_id;
84} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
85
86
87/*
88 * Message to inform ARM that one post processing frame has been decoded
89 */
90
91
92#define VIDDEC_MSG_PP_FRAME_DONE 0x0003
93#define VIDDEC_MSG_PP_FRAME_DONE_LEN \
94 sizeof(viddec_msg_pp_frame_done)
95
96#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000
97#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF
98
99
100typedef struct {
101 unsigned short packet_seq_number;
102 unsigned short codec_instance_id;
103 unsigned short display_worthy;
104} __attribute__((packed)) viddec_msg_pp_frame_done;
105
106
107#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
deleted file mode 100644
index 819544d186da..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
+++ /dev/null
@@ -1,212 +0,0 @@
1#ifndef QDSP5VIDENCCMDI_H
2#define QDSP5VIDENCCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O E N C O D E R I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VIDENC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 2008 by QUALCOMM, Incorporated.
19*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
20/*===========================================================================
21
22 EDIT HISTORY FOR FILE
23
24This section contains comments describing changes made to this file.
25Notice that changes are listed in reverse chronological order.
26
27Revision History:
28
29when who what, where, why
30-------- --- ----------------------------------------------------------
3109/25/08 umeshp initial version
32===========================================================================*/
33
34 #define VIDENC_CMD_CFG 0x0000
35 #define VIDENC_CMD_ACTIVE 0x0001
36 #define VIDENC_CMD_IDLE 0x0002
37 #define VIDENC_CMD_FRAME_START 0x0003
38 #define VIDENC_CMD_STATUS_QUERY 0x0004
39 #define VIDENC_CMD_RC_CFG 0x0005
40 #define VIDENC_CMD_DIS_CFG 0x0006
41 #define VIDENC_CMD_DIS 0x0007
42 #define VIDENC_CMD_INTRA_REFRESH 0x0008
43 #define VIDENC_CMD_DIGITAL_ZOOM 0x0009
44
45
46/*
47 * Command to pass the frame message information to VIDENC
48 */
49
50
51#define VIDENC_CMD_FRAME_START_LEN \
52 sizeof(videnc_cmd_frame_start)
53
54typedef struct {
55 unsigned short cmd_id;
56 unsigned short frame_info;
57 unsigned short frame_rho_budget_word_high;
58 unsigned short frame_rho_budget_word_low;
59 unsigned short input_luma_addr_high;
60 unsigned short input_luma_addr_low;
61 unsigned short input_chroma_addr_high;
62 unsigned short input_chroma_addr_low;
63 unsigned short ref_vop_buf_ptr_high;
64 unsigned short ref_vop_buf_ptr_low;
65 unsigned short enc_pkt_buf_ptr_high;
66 unsigned short enc_pkt_buf_ptr_low;
67 unsigned short enc_pkt_buf_size_high;
68 unsigned short enc_pkt_buf_size_low;
69 unsigned short unfilt_recon_vop_buf_ptr_high;
70 unsigned short unfilt_recon_vop_buf_ptr_low;
71 unsigned short filt_recon_vop_buf_ptr_high;
72 unsigned short filt_recon_vop_buf_ptr_low;
73} __attribute__((packed)) videnc_cmd_frame_start;
74
75/*
76 * Command to pass the frame-level digital stabilization parameters to VIDENC
77 */
78
79
80#define VIDENC_CMD_DIS_LEN \
81 sizeof(videnc_cmd_dis)
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short vfe_out_prev_luma_addr_high;
86 unsigned short vfe_out_prev_luma_addr_low;
87 unsigned short stabilization_info;
88} __attribute__((packed)) videnc_cmd_dis;
89
90/*
91 * Command to pass the codec related parameters to VIDENC
92 */
93
94
95#define VIDENC_CMD_CFG_LEN \
96 sizeof(videnc_cmd_cfg)
97
98typedef struct {
99 unsigned short cmd_id;
100 unsigned short cfg_info_0;
101 unsigned short cfg_info_1;
102 unsigned short four_mv_threshold;
103 unsigned short ise_fse_mv_cost_fac;
104 unsigned short venc_frame_dim;
105 unsigned short venc_DM_partition;
106} __attribute__((packed)) videnc_cmd_cfg;
107
108/*
109 * Command to start the video encoding
110 */
111
112
113#define VIDENC_CMD_ACTIVE_LEN \
114 sizeof(videnc_cmd_active)
115
116typedef struct {
117 unsigned short cmd_id;
118} __attribute__((packed)) videnc_cmd_active;
119
120/*
121 * Command to stop the video encoding
122 */
123
124
125#define VIDENC_CMD_IDLE_LEN \
126 sizeof(videnc_cmd_idle)
127
128typedef struct {
129 unsigned short cmd_id;
130} __attribute__((packed)) videnc_cmd_idle;
131
132/*
133 * Command to query staus of VIDENC
134 */
135
136
137#define VIDENC_CMD_STATUS_QUERY_LEN \
138 sizeof(videnc_cmd_status_query)
139
140typedef struct {
141 unsigned short cmd_id;
142} __attribute__((packed)) videnc_cmd_status_query;
143
144/*
145 * Command to set rate control for a frame
146 */
147
148
149#define VIDENC_CMD_RC_CFG_LEN \
150 sizeof(videnc_cmd_rc_cfg)
151
152typedef struct {
153 unsigned short cmd_id;
154 unsigned short max_frame_qp_delta;
155 unsigned short max_min_frame_qp;
156} __attribute__((packed)) videnc_cmd_rc_cfg;
157
158/*
159 * Command to set intra-refreshing
160 */
161
162
163#define VIDENC_CMD_INTRA_REFRESH_LEN \
164 sizeof(videnc_cmd_intra_refresh)
165
166typedef struct {
167 unsigned short cmd_id;
168 unsigned short num_mb_refresh;
169 unsigned short mb_index[15];
170} __attribute__((packed)) videnc_cmd_intra_refresh;
171
172/*
173 * Command to pass digital zoom information to the VIDENC
174 */
175#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
176 sizeof(videnc_cmd_digital_zoom)
177
178typedef struct {
179 unsigned short cmd_id;
180 unsigned short digital_zoom_en;
181 unsigned short luma_frame_shift_X;
182 unsigned short luma_frame_shift_Y;
183 unsigned short up_ip_luma_rows;
184 unsigned short up_ip_luma_cols;
185 unsigned short up_ip_chroma_rows;
186 unsigned short up_ip_chroma_cols;
187 unsigned short luma_ph_incr_V_low;
188 unsigned short luma_ph_incr_V_high;
189 unsigned short luma_ph_incr_H_low;
190 unsigned short luma_ph_incr_H_high;
191 unsigned short chroma_ph_incr_V_low;
192 unsigned short chroma_ph_incr_V_high;
193 unsigned short chroma_ph_incr_H_low;
194 unsigned short chroma_ph_incr_H_high;
195} __attribute__((packed)) videnc_cmd_digital_zoom;
196
197/*
198 * Command to configure digital stabilization parameters
199 */
200
201#define VIDENC_CMD_DIS_CFG_LEN \
202 sizeof(videnc_cmd_dis_cfg)
203
204typedef struct {
205 unsigned short cmd_id;
206 unsigned short image_stab_subf_start_row_col;
207 unsigned short image_stab_subf_dim;
208 unsigned short image_stab_info_0;
209} __attribute__((packed)) videnc_cmd_dis_cfg;
210
211
212#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
deleted file mode 100644
index 55e8fc2269f7..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
+++ /dev/null
@@ -1,910 +0,0 @@
1#ifndef QDSP5VFECMDI_H
2#define QDSP5VFECMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V F E I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VFE Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45/******************************************************************************
46 * Commands through vfeCommandScaleQueue
47 *****************************************************************************/
48
49/*
50 * Command to program scaler for op1 . max op of scaler is VGA
51 */
52
53
54#define VFE_CMD_SCALE_OP1_CFG 0x0000
55#define VFE_CMD_SCALE_OP1_CFG_LEN \
56 sizeof(vfe_cmd_scale_op1_cfg)
57
58#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000
59#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001
60#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000
61#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002
62#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000
63#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004
64#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000
65#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008
66#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000
67#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010
68#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000
69#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020
70#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000
71#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040
72#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000
73#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080
74
75#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
76#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
77
78typedef struct {
79 unsigned int cmd_id;
80 unsigned int scale_op1_sel;
81 unsigned int y_scaler_cfg_part1;
82 unsigned int y_scaler_cfg_part2;
83 unsigned int cbcr_scaler_cfg_part1;
84 unsigned int cbcr_scaler_cfg_part2;
85 unsigned int cbcr_scaler_cfg_part3;
86 unsigned int pp_y_scaler_cfg_part1;
87 unsigned int pp_y_scaler_cfg_part2;
88 unsigned int y_scaler_v_coeff_bank_part1[16];
89 unsigned int y_scaler_v_coeff_bank_part2[16];
90 unsigned int y_scaler_h_coeff_bank_part1[16];
91 unsigned int y_scaler_h_coeff_bank_part2[16];
92} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
93
94
95/*
96 * Command to program scaler for op2
97 */
98
99#define VFE_CMD_SCALE_OP2_CFG 0x0001
100#define VFE_CMD_SCALE_OP2_CFG_LEN \
101 sizeof(vfe_cmd_scale_op2_cfg)
102
103#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000
104#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001
105#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000
106#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002
107#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000
108#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004
109#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000
110#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008
111#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000
112#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010
113#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000
114#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020
115#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000
116#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040
117#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000
118#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080
119
120#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
121#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
122
123typedef struct {
124 unsigned int cmd_id;
125 unsigned int scale_op2_sel;
126 unsigned int y_scaler_cfg_part1;
127 unsigned int y_scaler_cfg_part2;
128 unsigned int cbcr_scaler_cfg_part1;
129 unsigned int cbcr_scaler_cfg_part2;
130 unsigned int cbcr_scaler_cfg_part3;
131 unsigned int pp_y_scaler_cfg_part1;
132 unsigned int pp_y_scaler_cfg_part2;
133 unsigned int y_scaler_v_coeff_bank_part1[16];
134 unsigned int y_scaler_v_coeff_bank_part2[16];
135 unsigned int y_scaler_h_coeff_bank_part1[16];
136 unsigned int y_scaler_h_coeff_bank_part2[16];
137} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
138
139
140/******************************************************************************
141 * Commands through vfeCommandTableQueue
142 *****************************************************************************/
143
144/*
145 * Command to program the AXI ip paths
146 */
147
148#define VFE_CMD_AXI_IP_CFG 0x0000
149#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg)
150
151#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000
152#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001
153#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002
154
155typedef struct {
156 unsigned int cmd_id;
157 unsigned int ip_sel;
158 unsigned int ip_cfg_part1;
159 unsigned int ip_cfg_part2;
160 unsigned int ip_unpack_cfg_part[6];
161 unsigned int ip_buf_addr[8];
162} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
163
164
165/*
166 * Command to program axi op paths
167 */
168
169#define VFE_CMD_AXI_OP_CFG 0x0001
170#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg)
171
172#define VFE_CMD_OP_SEL_OP1 0x0000
173#define VFE_CMD_OP_SEL_OP2 0x0001
174#define VFE_CMD_OP_SEL_OP1_OP2 0x0002
175#define VFE_CMD_OP_SEL_CTOA 0x0003
176#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004
177#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005
178#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000
179#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008
180#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010
181
182
183typedef struct {
184 unsigned int cmd_id;
185 unsigned int op_sel;
186 unsigned int op1_y_cfg_part1;
187 unsigned int op1_y_cfg_part2;
188 unsigned int op1_cbcr_cfg_part1;
189 unsigned int op1_cbcr_cfg_part2;
190 unsigned int op2_y_cfg_part1;
191 unsigned int op2_y_cfg_part2;
192 unsigned int op2_cbcr_cfg_part1;
193 unsigned int op2_cbcr_cfg_part2;
194 unsigned int op1_buf1_addr[16];
195 unsigned int op2_buf1_addr[16];
196} __attribute__((packed)) vfe_cmd_axi_op_cfg;
197
198
199
200
201/*
202 * Command to program the roll off correction module
203 */
204
205#define VFE_CMD_ROLLOFF_CFG 0x0002
206#define VFE_CMD_ROLLOFF_CFG_LEN \
207 sizeof(vfe_cmd_rolloff_cfg)
208
209
210typedef struct {
211 unsigned int cmd_id;
212 unsigned int correction_opt_center_pos;
213 unsigned int radius_square_entry[32];
214 unsigned int red_table_entry[32];
215 unsigned int green_table_entry[32];
216 unsigned int blue_table_entry[32];
217} __attribute__((packed)) vfe_cmd_rolloff_cfg;
218
219/*
220 * Command to program RGB gamma table
221 */
222
223#define VFE_CMD_RGB_GAMMA_CFG 0x0003
224#define VFE_CMD_RGB_GAMMA_CFG_LEN \
225 sizeof(vfe_cmd_rgb_gamma_cfg)
226
227#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000
228#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001
229typedef struct {
230 unsigned int cmd_id;
231 unsigned int rgb_gamma_sel;
232 unsigned int rgb_gamma_entry[256];
233} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
234
235
236/*
237 * Command to program luma gamma table for the noise reduction path
238 */
239
240#define VFE_CMD_Y_GAMMA_CFG 0x0004
241#define VFE_CMD_Y_GAMMA_CFG_LEN \
242 sizeof(vfe_cmd_y_gamma_cfg)
243
244#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000
245#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001
246
247typedef struct {
248 unsigned int cmd_id;
249 unsigned int y_gamma_sel;
250 unsigned int y_gamma_entry[256];
251} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
252
253
254
255/******************************************************************************
256 * Commands through vfeCommandQueue
257 *****************************************************************************/
258
259/*
260 * Command to reset the VFE to a known good state.All previously programmed
261 * Params will be lost
262 */
263
264
265#define VFE_CMD_RESET 0x0000
266#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset)
267
268
269typedef struct {
270 unsigned short cmd_id;
271} __attribute__((packed)) vfe_cmd_reset;
272
273
274/*
275 * Command to start VFE processing based on the config params
276 */
277
278
279#define VFE_CMD_START 0x0001
280#define VFE_CMD_START_LEN sizeof(vfe_cmd_start)
281
282#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000
283#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001
284#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000
285#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002
286
287#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000
288#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001
289#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000
290#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002
291#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000
292#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004
293#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000
294#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008
295#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000
296#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010
297#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000
298#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020
299#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000
300#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040
301
302
303typedef struct {
304 unsigned int cmd_id;
305 unsigned int startup_params;
306 unsigned int image_pipeline;
307 unsigned int frame_dimension;
308} __attribute__((packed)) vfe_cmd_start;
309
310
311/*
312 * Command to halt all processing
313 */
314
315#define VFE_CMD_STOP 0x0002
316#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop)
317
318typedef struct {
319 unsigned short cmd_id;
320} __attribute__((packed)) vfe_cmd_stop;
321
322
323/*
324 * Command to commit the params that have been programmed to take
325 * effect on the next frame
326 */
327
328#define VFE_CMD_UPDATE 0x0003
329#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update)
330
331
332typedef struct {
333 unsigned short cmd_id;
334} __attribute__((packed)) vfe_cmd_update;
335
336
337/*
338 * Command to program CAMIF module
339 */
340
341#define VFE_CMD_CAMIF_CFG 0x0004
342#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg)
343
344#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000
345#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002
346#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000
347#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004
348#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000
349#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008
350#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010
351#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018
352#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000
353#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020
354#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000
355#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080
356#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000
357#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800
358
359#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000
360#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010
361
362#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000
363#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000
364#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000
365#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000
366
367typedef struct {
368 unsigned int cmd_id;
369 unsigned int cfg;
370 unsigned int efs_cfg;
371 unsigned int frame_cfg;
372 unsigned int window_width_cfg;
373 unsigned int window_height_cfg;
374 unsigned int subsamp1_cfg;
375 unsigned int subsamp2_cfg;
376 unsigned int epoch_irq;
377} __attribute__((packed)) vfe_cmd_camif_cfg;
378
379
380
381/*
382 * Command to program the black level module
383 */
384
385#define VFE_CMD_BLACK_LVL_CFG 0x0005
386#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg)
387
388#define VFE_CMD_BL_SEL_MANUAL 0x0000
389#define VFE_CMD_BL_SEL_AUTO 0x0001
390
391typedef struct {
392 unsigned int cmd_id;
393 unsigned int black_lvl_sel;
394 unsigned int cfg_part[3];
395} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
396
397
398/*
399 * Command to program the active region by cropping the region of interest
400 */
401
402#define VFE_CMD_ACTIVE_REGION_CFG 0x0006
403#define VFE_CMD_ACTIVE_REGION_CFG_LEN \
404 sizeof(vfe_cmd_active_region_cfg)
405
406
407typedef struct {
408 unsigned int cmd_id;
409 unsigned int cfg_part1;
410 unsigned int cfg_part2;
411} __attribute__((packed)) vfe_cmd_active_region_cfg;
412
413
414
415/*
416 * Command to program the defective pixel correction(DPC) ,
417 * adaptive bayer filter (ABF) and demosaic modules
418 */
419
420#define VFE_CMD_DEMOSAIC_CFG 0x0007
421#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg)
422
423#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000
424#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001
425#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000
426#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002
427#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000
428#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004
429#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000
430#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000
431#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000
432#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000
433#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000
434#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000
435#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000
436
437typedef struct {
438 unsigned int cmd_id;
439 unsigned int demosaic_part1;
440 unsigned int demosaic_part2;
441 unsigned int demosaic_part3;
442 unsigned int demosaic_part4;
443 unsigned int demosaic_part5;
444} __attribute__((packed)) vfe_cmd_demosaic_cfg;
445
446
447/*
448 * Command to program the ip format
449 */
450
451#define VFE_CMD_IP_FORMAT_CFG 0x0008
452#define VFE_CMD_IP_FORMAT_CFG_LEN \
453 sizeof(vfe_cmd_ip_format_cfg)
454
455#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000
456#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001
457#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002
458#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003
459#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004
460#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005
461#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006
462#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007
463#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000
464#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008
465
466
467typedef struct {
468 unsigned int cmd_id;
469 unsigned int ip_format_sel;
470 unsigned int balance_gains_part1;
471 unsigned int balance_gains_part2;
472} __attribute__((packed)) vfe_cmd_ip_format_cfg;
473
474
475
476/*
477 * Command to program max and min allowed op values
478 */
479
480#define VFE_CMD_OP_CLAMP_CFG 0x0009
481#define VFE_CMD_OP_CLAMP_CFG_LEN \
482 sizeof(vfe_cmd_op_clamp_cfg)
483
484typedef struct {
485 unsigned int cmd_id;
486 unsigned int op_clamp_max;
487 unsigned int op_clamp_min;
488} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
489
490
491/*
492 * Command to program chroma sub sample module
493 */
494
495#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A
496#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \
497 sizeof(vfe_cmd_chroma_subsample_cfg)
498
499#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000
500#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001
501#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000
502#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002
503#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000
504#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004
505#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000
506#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008
507
508typedef struct {
509 unsigned int cmd_id;
510 unsigned int chroma_subsamp_sel;
511} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
512
513
514/*
515 * Command to program the white balance module
516 */
517
518#define VFE_CMD_WHITE_BALANCE_CFG 0x000B
519#define VFE_CMD_WHITE_BALANCE_CFG_LEN \
520 sizeof(vfe_cmd_white_balance_cfg)
521
522typedef struct {
523 unsigned int cmd_id;
524 unsigned int white_balance_gains;
525} __attribute__((packed)) vfe_cmd_white_balance_cfg;
526
527
528/*
529 * Command to program the color processing module
530 */
531
532#define VFE_CMD_COLOR_PROCESS_CFG 0x000C
533#define VFE_CMD_COLOR_PROCESS_CFG_LEN \
534 sizeof(vfe_cmd_color_process_cfg)
535
536#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000
537#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001
538#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002
539#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003
540
541typedef struct {
542 unsigned int cmd_id;
543 unsigned int color_correction_part1;
544 unsigned int color_correction_part2;
545 unsigned int color_correction_part3;
546 unsigned int color_correction_part4;
547 unsigned int color_correction_part5;
548 unsigned int color_correction_part6;
549 unsigned int color_correction_part7;
550 unsigned int chroma_enhance_part1;
551 unsigned int chroma_enhance_part2;
552 unsigned int chroma_enhance_part3;
553 unsigned int chroma_enhance_part4;
554 unsigned int chroma_enhance_part5;
555 unsigned int luma_calc_part1;
556 unsigned int luma_calc_part2;
557} __attribute__((packed)) vfe_cmd_color_process_cfg;
558
559
560/*
561 * Command to program adaptive filter module
562 */
563
564#define VFE_CMD_ADP_FILTER_CFG 0x000D
565#define VFE_CMD_ADP_FILTER_CFG_LEN \
566 sizeof(vfe_cmd_adp_filter_cfg)
567
568#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000
569#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001
570#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000
571#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002
572#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004
573#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007
574
575typedef struct {
576 unsigned int cmd_id;
577 unsigned int asf_cfg_part[7];
578} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
579
580
581/*
582 * Command to program for frame skip pattern for op1 and op2
583 */
584
585#define VFE_CMD_FRAME_SKIP_CFG 0x000E
586#define VFE_CMD_FRAME_SKIP_CFG_LEN \
587 sizeof(vfe_cmd_frame_skip_cfg)
588
589typedef struct {
590 unsigned int cmd_id;
591 unsigned int frame_skip_pattern_op1;
592 unsigned int frame_skip_pattern_op2;
593} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
594
595
596/*
597 * Command to program field-of-view crop for digital zoom
598 */
599
600#define VFE_CMD_FOV_CROP 0x000F
601#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop)
602
603typedef struct {
604 unsigned int cmd_id;
605 unsigned int fov_crop_part1;
606 unsigned int fov_crop_part2;
607} __attribute__((packed)) vfe_cmd_fov_crop;
608
609
610
611/*
612 * Command to program auto focus(AF) statistics module
613 */
614
615#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010
616#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \
617 sizeof(vfe_cmd_stats_autofocus_cfg)
618
619#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000
620#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001
621#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000
622#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002
623#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000
624#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000
625
626typedef struct {
627 unsigned int cmd_id;
628 unsigned int af_stats_sel;
629 unsigned int af_stats_cfg_part[8];
630 unsigned int af_stats_op_buf_hdr;
631 unsigned int af_stats_op_buf[3];
632} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
633
634
635/*
636 * Command to program White balance(wb) and exposure (exp)
637 * statistics module
638 */
639
640#define VFE_CMD_STATS_WB_EXP_CFG 0x0011
641#define VFE_CMD_STATS_WB_EXP_CFG_LEN \
642 sizeof(vfe_cmd_stats_wb_exp_cfg)
643
644#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000
645#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001
646#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000
647#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002
648
649#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000
650#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001
651#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000
652#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002
653
654typedef struct {
655 unsigned int cmd_id;
656 unsigned int wb_exp_stats_sel;
657 unsigned int wb_exp_stats_cfg_part1;
658 unsigned int wb_exp_stats_cfg_part2;
659 unsigned int wb_exp_stats_cfg_part3;
660 unsigned int wb_exp_stats_cfg_part4;
661 unsigned int wb_exp_stats_op_buf_hdr;
662 unsigned int wb_exp_stats_op_buf[3];
663} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
664
665
666/*
667 * Command to program histogram(hg) stats module
668 */
669
670#define VFE_CMD_STATS_HG_CFG 0x0012
671#define VFE_CMD_STATS_HG_CFG_LEN \
672 sizeof(vfe_cmd_stats_hg_cfg)
673
674#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000
675#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002
676
677typedef struct {
678 unsigned int cmd_id;
679 unsigned int hg_stats_sel;
680 unsigned int hg_stats_cfg_part1;
681 unsigned int hg_stats_cfg_part2;
682 unsigned int hg_stats_op_buf_hdr;
683 unsigned int hg_stats_op_buf;
684} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
685
686
687/*
688 * Command to acknowledge last MSG_VFE_OP1 message
689 */
690
691#define VFE_CMD_OP1_ACK 0x0013
692#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack)
693
694typedef struct {
695 unsigned int cmd_id;
696 unsigned int op1_buf_y_addr;
697 unsigned int op1_buf_cbcr_addr;
698} __attribute__((packed)) vfe_cmd_op1_ack;
699
700
701
702/*
703 * Command to acknowledge last MSG_VFE_OP2 message
704 */
705
706#define VFE_CMD_OP2_ACK 0x0014
707#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack)
708
709typedef struct {
710 unsigned int cmd_id;
711 unsigned int op2_buf_y_addr;
712 unsigned int op2_buf_cbcr_addr;
713} __attribute__((packed)) vfe_cmd_op2_ack;
714
715
716
717/*
718 * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
719 */
720
721#define VFE_CMD_STATS_AF_ACK 0x0015
722#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack)
723
724
725typedef struct {
726 unsigned int cmd_id;
727 unsigned int af_stats_op_buf;
728} __attribute__((packed)) vfe_cmd_stats_af_ack;
729
730
731/*
732 * Command to acknowledge MSG_VFE_STATS_WB_EXP msg
733 */
734
735#define VFE_CMD_STATS_WB_EXP_ACK 0x0016
736#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack)
737
738typedef struct {
739 unsigned int cmd_id;
740 unsigned int wb_exp_stats_op_buf;
741} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
742
743
744/*
745 * Command to acknowledge MSG_VFE_EPOCH1 message
746 */
747
748#define VFE_CMD_EPOCH1_ACK 0x0017
749#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack)
750
751typedef struct {
752 unsigned short cmd_id;
753} __attribute__((packed)) vfe_cmd_epoch1_ack;
754
755
756/*
757 * Command to acknowledge MSG_VFE_EPOCH2 message
758 */
759
760#define VFE_CMD_EPOCH2_ACK 0x0018
761#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack)
762
763typedef struct {
764 unsigned short cmd_id;
765} __attribute__((packed)) vfe_cmd_epoch2_ack;
766
767
768
769/*
770 * Command to configure, enable or disable synchronous timer1
771 */
772
773#define VFE_CMD_SYNC_TIMER1_CFG 0x0019
774#define VFE_CMD_SYNC_TIMER1_CFG_LEN \
775 sizeof(vfe_cmd_sync_timer1_cfg)
776
777#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000
778#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001
779#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000
780#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002
781
782typedef struct {
783 unsigned int cmd_id;
784 unsigned int sync_t1_cfg_part1;
785 unsigned int sync_t1_h_sync_countdown;
786 unsigned int sync_t1_pclk_countdown;
787 unsigned int sync_t1_duration;
788} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
789
790
791/*
792 * Command to configure, enable or disable synchronous timer1
793 */
794
795#define VFE_CMD_SYNC_TIMER2_CFG 0x001A
796#define VFE_CMD_SYNC_TIMER2_CFG_LEN \
797 sizeof(vfe_cmd_sync_timer2_cfg)
798
799#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000
800#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001
801#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000
802#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002
803
804typedef struct {
805 unsigned int cmd_id;
806 unsigned int sync_t2_cfg_part1;
807 unsigned int sync_t2_h_sync_countdown;
808 unsigned int sync_t2_pclk_countdown;
809 unsigned int sync_t2_duration;
810} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
811
812
813/*
814 * Command to configure and start asynchronous timer1
815 */
816
817#define VFE_CMD_ASYNC_TIMER1_START 0x001B
818#define VFE_CMD_ASYNC_TIMER1_START_LEN \
819 sizeof(vfe_cmd_async_timer1_start)
820
821#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000
822#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001
823#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000
824#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002
825
826typedef struct {
827 unsigned int cmd_id;
828 unsigned int async_t1a_cfg;
829 unsigned int async_t1b_cfg;
830 unsigned int async_t1_polarity;
831} __attribute__((packed)) vfe_cmd_async_timer1_start;
832
833
834/*
835 * Command to configure and start asynchronous timer2
836 */
837
838#define VFE_CMD_ASYNC_TIMER2_START 0x001C
839#define VFE_CMD_ASYNC_TIMER2_START_LEN \
840 sizeof(vfe_cmd_async_timer2_start)
841
842#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000
843#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001
844#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000
845#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002
846
847typedef struct {
848 unsigned int cmd_id;
849 unsigned int async_t2a_cfg;
850 unsigned int async_t2b_cfg;
851 unsigned int async_t2_polarity;
852} __attribute__((packed)) vfe_cmd_async_timer2_start;
853
854
855/*
856 * Command to program partial configurations of auto focus(af)
857 */
858
859#define VFE_CMD_STATS_AF_UPDATE 0x001D
860#define VFE_CMD_STATS_AF_UPDATE_LEN \
861 sizeof(vfe_cmd_stats_af_update)
862
863#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000
864#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000
865
866typedef struct {
867 unsigned int cmd_id;
868 unsigned int af_update_part1;
869 unsigned int af_update_part2;
870} __attribute__((packed)) vfe_cmd_stats_af_update;
871
872
873/*
874 * Command to program partial cfg of wb and exp
875 */
876
877#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E
878#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \
879 sizeof(vfe_cmd_stats_wb_exp_update)
880
881#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000
882#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001
883#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000
884#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002
885
886typedef struct {
887 unsigned int cmd_id;
888 unsigned int wb_exp_update_part1;
889 unsigned int wb_exp_update_part2;
890 unsigned int wb_exp_update_part3;
891 unsigned int wb_exp_update_part4;
892} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
893
894
895
896/*
897 * Command to re program the CAMIF FRAME CONFIG settings
898 */
899
900#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F
901#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \
902 sizeof(vfe_cmd_update_camif_frame_cfg)
903
904typedef struct {
905 unsigned int cmd_id;
906 unsigned int camif_frame_cfg;
907} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
908
909
910#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
deleted file mode 100644
index 0053cfb65ba1..000000000000
--- a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
+++ /dev/null
@@ -1,290 +0,0 @@
1#ifndef QDSP5VFEMSGI_H
2#define QDSP5VFEMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V F E I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are sent by VFE Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45
46/*
47 * Message to acknowledge CMD_VFE_REST command
48 */
49
50#define VFE_MSG_RESET_ACK 0x0000
51#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack)
52
53typedef struct {
54} __attribute__((packed)) vfe_msg_reset_ack;
55
56
57/*
58 * Message to acknowledge CMD_VFE_START command
59 */
60
61#define VFE_MSG_START_ACK 0x0001
62#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack)
63
64typedef struct {
65} __attribute__((packed)) vfe_msg_start_ack;
66
67/*
68 * Message to acknowledge CMD_VFE_STOP command
69 */
70
71#define VFE_MSG_STOP_ACK 0x0002
72#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack)
73
74typedef struct {
75} __attribute__((packed)) vfe_msg_stop_ack;
76
77
78/*
79 * Message to acknowledge CMD_VFE_UPDATE command
80 */
81
82#define VFE_MSG_UPDATE_ACK 0x0003
83#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack)
84
85typedef struct {
86} __attribute__((packed)) vfe_msg_update_ack;
87
88
89/*
90 * Message to notify the ARM that snapshot processing is complete
91 * and that the VFE is now STATE_VFE_IDLE
92 */
93
94#define VFE_MSG_SNAPSHOT_DONE 0x0004
95#define VFE_MSG_SNAPSHOT_DONE_LEN \
96 sizeof(vfe_msg_snapshot_done)
97
98typedef struct {
99} __attribute__((packed)) vfe_msg_snapshot_done;
100
101
102
103/*
104 * Message to notify ARM that illegal cmd was received and
105 * system is in the IDLE state
106 */
107
108#define VFE_MSG_ILLEGAL_CMD 0x0005
109#define VFE_MSG_ILLEGAL_CMD_LEN \
110 sizeof(vfe_msg_illegal_cmd)
111
112typedef struct {
113 unsigned int status;
114} __attribute__((packed)) vfe_msg_illegal_cmd;
115
116
117/*
118 * Message to notify ARM that op1 buf is full and ready
119 */
120
121#define VFE_MSG_OP1 0x0006
122#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1)
123
124typedef struct {
125 unsigned int op1_buf_y_addr;
126 unsigned int op1_buf_cbcr_addr;
127 unsigned int black_level_even_col;
128 unsigned int black_level_odd_col;
129 unsigned int defect_pixels_detected;
130 unsigned int asf_max_edge;
131} __attribute__((packed)) vfe_msg_op1;
132
133
134/*
135 * Message to notify ARM that op2 buf is full and ready
136 */
137
138#define VFE_MSG_OP2 0x0007
139#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2)
140
141typedef struct {
142 unsigned int op2_buf_y_addr;
143 unsigned int op2_buf_cbcr_addr;
144 unsigned int black_level_even_col;
145 unsigned int black_level_odd_col;
146 unsigned int defect_pixels_detected;
147 unsigned int asf_max_edge;
148} __attribute__((packed)) vfe_msg_op2;
149
150
151/*
152 * Message to notify ARM that autofocus(af) stats are ready
153 */
154
155#define VFE_MSG_STATS_AF 0x0008
156#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af)
157
158typedef struct {
159 unsigned int af_stats_op_buffer;
160} __attribute__((packed)) vfe_msg_stats_af;
161
162
163/*
164 * Message to notify ARM that white balance(wb) and exposure (exp)
165 * stats are ready
166 */
167
168#define VFE_MSG_STATS_WB_EXP 0x0009
169#define VFE_MSG_STATS_WB_EXP_LEN \
170 sizeof(vfe_msg_stats_wb_exp)
171
172typedef struct {
173 unsigned int wb_exp_stats_op_buf;
174} __attribute__((packed)) vfe_msg_stats_wb_exp;
175
176
177/*
178 * Message to notify the ARM that histogram(hg) stats are ready
179 */
180
181#define VFE_MSG_STATS_HG 0x000A
182#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg)
183
184typedef struct {
185 unsigned int hg_stats_op_buf;
186} __attribute__((packed)) vfe_msg_stats_hg;
187
188
189/*
190 * Message to notify the ARM that epoch1 event occurred in the CAMIF
191 */
192
193#define VFE_MSG_EPOCH1 0x000B
194#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1)
195
196typedef struct {
197} __attribute__((packed)) vfe_msg_epoch1;
198
199
200/*
201 * Message to notify the ARM that epoch2 event occurred in the CAMIF
202 */
203
204#define VFE_MSG_EPOCH2 0x000C
205#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2)
206
207typedef struct {
208} __attribute__((packed)) vfe_msg_epoch2;
209
210
211/*
212 * Message to notify the ARM that sync timer1 op is completed
213 */
214
215#define VFE_MSG_SYNC_T1_DONE 0x000D
216#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done)
217
218typedef struct {
219} __attribute__((packed)) vfe_msg_sync_t1_done;
220
221
222/*
223 * Message to notify the ARM that sync timer2 op is completed
224 */
225
226#define VFE_MSG_SYNC_T2_DONE 0x000E
227#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done)
228
229typedef struct {
230} __attribute__((packed)) vfe_msg_sync_t2_done;
231
232
233/*
234 * Message to notify the ARM that async t1 operation completed
235 */
236
237#define VFE_MSG_ASYNC_T1_DONE 0x000F
238#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done)
239
240typedef struct {
241} __attribute__((packed)) vfe_msg_async_t1_done;
242
243
244
245/*
246 * Message to notify the ARM that async t2 operation completed
247 */
248
249#define VFE_MSG_ASYNC_T2_DONE 0x0010
250#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done)
251
252typedef struct {
253} __attribute__((packed)) vfe_msg_async_t2_done;
254
255
256
257/*
258 * Message to notify the ARM that an error has occurred
259 */
260
261#define VFE_MSG_ERROR 0x0011
262#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error)
263
264#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000
265#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001
266#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000
267#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002
268#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000
269#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004
270#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000
271#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008
272#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000
273#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010
274#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000
275#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020
276#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000
277#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040
278#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000
279#define VFE_MSG_ERR_COND_AXI_ERR 0x0080
280
281#define VFE_MSG_CAMIF_STS_IDLE 0x0000
282#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001
283
284typedef struct {
285 unsigned int err_cond;
286 unsigned int camif_sts;
287} __attribute__((packed)) vfe_msg_error;
288
289
290#endif
diff --git a/drivers/staging/dream/include/media/msm_camera.h b/drivers/staging/dream/include/media/msm_camera.h
deleted file mode 100644
index 09812d62cc1e..000000000000
--- a/drivers/staging/dream/include/media/msm_camera.h
+++ /dev/null
@@ -1,388 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4#ifndef __LINUX_MSM_CAMERA_H
5#define __LINUX_MSM_CAMERA_H
6
7#include <linux/types.h>
8#include <asm/sizes.h>
9#include <linux/ioctl.h>
10
11#define MSM_CAM_IOCTL_MAGIC 'm'
12
13#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
14 _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
15
16#define MSM_CAM_IOCTL_REGISTER_PMEM \
17 _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
18
19#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
20 _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
21
22#define MSM_CAM_IOCTL_CTRL_COMMAND \
23 _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
24
25#define MSM_CAM_IOCTL_CONFIG_VFE \
26 _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
27
28#define MSM_CAM_IOCTL_GET_STATS \
29 _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
30
31#define MSM_CAM_IOCTL_GETFRAME \
32 _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
33
34#define MSM_CAM_IOCTL_ENABLE_VFE \
35 _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
36
37#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
38 _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
39
40#define MSM_CAM_IOCTL_CONFIG_CMD \
41 _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
42
43#define MSM_CAM_IOCTL_DISABLE_VFE \
44 _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
45
46#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
47 _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
48
49#define MSM_CAM_IOCTL_VFE_APPS_RESET \
50 _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
51
52#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
53 _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
54
55#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
56 _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
57
58#define MSM_CAM_IOCTL_AXI_CONFIG \
59 _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
60
61#define MSM_CAM_IOCTL_GET_PICTURE \
62 _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
63
64#define MSM_CAM_IOCTL_SET_CROP \
65 _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
66
67#define MSM_CAM_IOCTL_PICT_PP \
68 _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
69
70#define MSM_CAM_IOCTL_PICT_PP_DONE \
71 _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
72
73#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
74 _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
75
76#define MSM_CAMERA_LED_OFF 0
77#define MSM_CAMERA_LED_LOW 1
78#define MSM_CAMERA_LED_HIGH 2
79
80#define MSM_CAM_IOCTL_FLASH_LED_CFG \
81 _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
82
83#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
84 _IO(MSM_CAM_IOCTL_MAGIC, 23)
85
86#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
87 _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
88
89#define MAX_SENSOR_NUM 3
90#define MAX_SENSOR_NAME 32
91
92#define MSM_CAM_CTRL_CMD_DONE 0
93#define MSM_CAM_SENSOR_VFE_CMD 1
94
95/*****************************************************
96 * structure
97 *****************************************************/
98
99/* define five type of structures for userspace <==> kernel
100 * space communication:
101 * command 1 - 2 are from userspace ==> kernel
102 * command 3 - 4 are from kernel ==> userspace
103 *
104 * 1. control command: control command(from control thread),
105 * control status (from config thread);
106 */
107struct msm_ctrl_cmd {
108 uint16_t type;
109 uint16_t length;
110 void *value;
111 uint16_t status;
112 uint32_t timeout_ms;
113 int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
114};
115
116struct msm_vfe_evt_msg {
117 unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
118 unsigned short msg_id;
119 unsigned int len; /* size in, number of bytes out */
120 void *data;
121};
122
123#define MSM_CAM_RESP_CTRL 0
124#define MSM_CAM_RESP_STAT_EVT_MSG 1
125#define MSM_CAM_RESP_V4L2 2
126#define MSM_CAM_RESP_MAX 3
127
128/* this one is used to send ctrl/status up to config thread */
129struct msm_stats_event_ctrl {
130 /* 0 - ctrl_cmd from control thread,
131 * 1 - stats/event kernel,
132 * 2 - V4L control or read request */
133 int resptype;
134 int timeout_ms;
135 struct msm_ctrl_cmd ctrl_cmd;
136 /* struct vfe_event_t stats_event; */
137 struct msm_vfe_evt_msg stats_event;
138};
139
140/* 2. config command: config command(from config thread); */
141struct msm_camera_cfg_cmd {
142 /* what to config:
143 * 1 - sensor config, 2 - vfe config */
144 uint16_t cfg_type;
145
146 /* sensor config type */
147 uint16_t cmd_type;
148 uint16_t queue;
149 uint16_t length;
150 void *value;
151};
152
153#define CMD_GENERAL 0
154#define CMD_AXI_CFG_OUT1 1
155#define CMD_AXI_CFG_SNAP_O1_AND_O2 2
156#define CMD_AXI_CFG_OUT2 3
157#define CMD_PICT_T_AXI_CFG 4
158#define CMD_PICT_M_AXI_CFG 5
159#define CMD_RAW_PICT_AXI_CFG 6
160#define CMD_STATS_AXI_CFG 7
161#define CMD_STATS_AF_AXI_CFG 8
162#define CMD_FRAME_BUF_RELEASE 9
163#define CMD_PREV_BUF_CFG 10
164#define CMD_SNAP_BUF_RELEASE 11
165#define CMD_SNAP_BUF_CFG 12
166#define CMD_STATS_DISABLE 13
167#define CMD_STATS_ENABLE 14
168#define CMD_STATS_AF_ENABLE 15
169#define CMD_STATS_BUF_RELEASE 16
170#define CMD_STATS_AF_BUF_RELEASE 17
171#define UPDATE_STATS_INVALID 18
172
173/* vfe config command: config command(from config thread)*/
174struct msm_vfe_cfg_cmd {
175 int cmd_type;
176 uint16_t length;
177 void *value;
178};
179
180#define MAX_CAMERA_ENABLE_NAME_LEN 32
181struct camera_enable_cmd {
182 char name[MAX_CAMERA_ENABLE_NAME_LEN];
183};
184
185#define MSM_PMEM_OUTPUT1 0
186#define MSM_PMEM_OUTPUT2 1
187#define MSM_PMEM_OUTPUT1_OUTPUT2 2
188#define MSM_PMEM_THUMBAIL 3
189#define MSM_PMEM_MAINIMG 4
190#define MSM_PMEM_RAW_MAINIMG 5
191#define MSM_PMEM_AEC_AWB 6
192#define MSM_PMEM_AF 7
193#define MSM_PMEM_MAX 8
194
195#define FRAME_PREVIEW_OUTPUT1 0
196#define FRAME_PREVIEW_OUTPUT2 1
197#define FRAME_SNAPSHOT 2
198#define FRAME_THUMBAIL 3
199#define FRAME_RAW_SNAPSHOT 4
200#define FRAME_MAX 5
201
202struct msm_pmem_info {
203 int type;
204 int fd;
205 void *vaddr;
206 uint32_t y_off;
207 uint32_t cbcr_off;
208 uint8_t active;
209};
210
211struct outputCfg {
212 uint32_t height;
213 uint32_t width;
214
215 uint32_t window_height_firstline;
216 uint32_t window_height_lastline;
217};
218
219#define OUTPUT_1 0
220#define OUTPUT_2 1
221#define OUTPUT_1_AND_2 2
222#define CAMIF_TO_AXI_VIA_OUTPUT_2 3
223#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
224#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
225#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
226
227#define MSM_FRAME_PREV_1 0
228#define MSM_FRAME_PREV_2 1
229#define MSM_FRAME_ENC 2
230
231struct msm_frame {
232 int path;
233 unsigned long buffer;
234 uint32_t y_off;
235 uint32_t cbcr_off;
236 int fd;
237
238 void *cropinfo;
239 int croplen;
240};
241
242#define STAT_AEAW 0
243#define STAT_AF 1
244#define STAT_MAX 2
245
246struct msm_stats_buf {
247 int type;
248 unsigned long buffer;
249 int fd;
250};
251
252#define MSM_V4L2_VID_CAP_TYPE 0
253#define MSM_V4L2_STREAM_ON 1
254#define MSM_V4L2_STREAM_OFF 2
255#define MSM_V4L2_SNAPSHOT 3
256#define MSM_V4L2_QUERY_CTRL 4
257#define MSM_V4L2_GET_CTRL 5
258#define MSM_V4L2_SET_CTRL 6
259#define MSM_V4L2_QUERY 7
260#define MSM_V4L2_MAX 8
261
262struct crop_info {
263 void *info;
264 int len;
265};
266
267struct msm_postproc {
268 int ftnum;
269 struct msm_frame fthumnail;
270 int fmnum;
271 struct msm_frame fmain;
272};
273
274struct msm_snapshot_pp_status {
275 void *status;
276};
277
278#define CFG_SET_MODE 0
279#define CFG_SET_EFFECT 1
280#define CFG_START 2
281#define CFG_PWR_UP 3
282#define CFG_PWR_DOWN 4
283#define CFG_WRITE_EXPOSURE_GAIN 5
284#define CFG_SET_DEFAULT_FOCUS 6
285#define CFG_MOVE_FOCUS 7
286#define CFG_REGISTER_TO_REAL_GAIN 8
287#define CFG_REAL_TO_REGISTER_GAIN 9
288#define CFG_SET_FPS 10
289#define CFG_SET_PICT_FPS 11
290#define CFG_SET_BRIGHTNESS 12
291#define CFG_SET_CONTRAST 13
292#define CFG_SET_ZOOM 14
293#define CFG_SET_EXPOSURE_MODE 15
294#define CFG_SET_WB 16
295#define CFG_SET_ANTIBANDING 17
296#define CFG_SET_EXP_GAIN 18
297#define CFG_SET_PICT_EXP_GAIN 19
298#define CFG_SET_LENS_SHADING 20
299#define CFG_GET_PICT_FPS 21
300#define CFG_GET_PREV_L_PF 22
301#define CFG_GET_PREV_P_PL 23
302#define CFG_GET_PICT_L_PF 24
303#define CFG_GET_PICT_P_PL 25
304#define CFG_GET_AF_MAX_STEPS 26
305#define CFG_GET_PICT_MAX_EXP_LC 27
306#define CFG_MAX 28
307
308#define MOVE_NEAR 0
309#define MOVE_FAR 1
310
311#define SENSOR_PREVIEW_MODE 0
312#define SENSOR_SNAPSHOT_MODE 1
313#define SENSOR_RAW_SNAPSHOT_MODE 2
314
315#define SENSOR_QTR_SIZE 0
316#define SENSOR_FULL_SIZE 1
317#define SENSOR_INVALID_SIZE 2
318
319#define CAMERA_EFFECT_OFF 0
320#define CAMERA_EFFECT_MONO 1
321#define CAMERA_EFFECT_NEGATIVE 2
322#define CAMERA_EFFECT_SOLARIZE 3
323#define CAMERA_EFFECT_PASTEL 4
324#define CAMERA_EFFECT_MOSAIC 5
325#define CAMERA_EFFECT_RESIZE 6
326#define CAMERA_EFFECT_SEPIA 7
327#define CAMERA_EFFECT_POSTERIZE 8
328#define CAMERA_EFFECT_WHITEBOARD 9
329#define CAMERA_EFFECT_BLACKBOARD 10
330#define CAMERA_EFFECT_AQUA 11
331#define CAMERA_EFFECT_MAX 12
332
333struct sensor_pict_fps {
334 uint16_t prevfps;
335 uint16_t pictfps;
336};
337
338struct exp_gain_cfg {
339 uint16_t gain;
340 uint32_t line;
341};
342
343struct focus_cfg {
344 int32_t steps;
345 int dir;
346};
347
348struct fps_cfg {
349 uint16_t f_mult;
350 uint16_t fps_div;
351 uint32_t pict_fps_div;
352};
353
354struct sensor_cfg_data {
355 int cfgtype;
356 int mode;
357 int rs;
358 uint8_t max_steps;
359
360 union {
361 int8_t effect;
362 uint8_t lens_shading;
363 uint16_t prevl_pf;
364 uint16_t prevp_pl;
365 uint16_t pictl_pf;
366 uint16_t pictp_pl;
367 uint32_t pict_max_exp_lc;
368 uint16_t p_fps;
369 struct sensor_pict_fps gfps;
370 struct exp_gain_cfg exp_gain;
371 struct focus_cfg focus;
372 struct fps_cfg fps;
373 } cfg;
374};
375
376#define GET_NAME 0
377#define GET_PREVIEW_LINE_PER_FRAME 1
378#define GET_PREVIEW_PIXELS_PER_LINE 2
379#define GET_SNAPSHOT_LINE_PER_FRAME 3
380#define GET_SNAPSHOT_PIXELS_PER_LINE 4
381#define GET_SNAPSHOT_FPS 5
382#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6
383
384struct msm_camsensor_info {
385 char name[MAX_SENSOR_NAME];
386 uint8_t flash_enabled;
387};
388#endif /* __LINUX_MSM_CAMERA_H */
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
deleted file mode 100644
index 4d3d300bb736..000000000000
--- a/drivers/staging/dream/pmem.c
+++ /dev/null
@@ -1,1333 +0,0 @@
1/* drivers/android/pmem.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/miscdevice.h>
17#include <linux/platform_device.h>
18#include <linux/fs.h>
19#include <linux/file.h>
20#include <linux/mm.h>
21#include <linux/list.h>
22#include <linux/debugfs.h>
23#include <linux/android_pmem.h>
24#include <linux/mempolicy.h>
25#include <linux/sched.h>
26#include <linux/slab.h>
27#include <linux/io.h>
28#include <linux/uaccess.h>
29#include <asm/cacheflush.h>
30
31#define PMEM_MAX_DEVICES 10
32#define PMEM_MAX_ORDER 128
33#define PMEM_MIN_ALLOC PAGE_SIZE
34
35#define PMEM_DEBUG 1
36
37/* indicates that a refernce to this file has been taken via get_pmem_file,
38 * the file should not be released until put_pmem_file is called */
39#define PMEM_FLAGS_BUSY 0x1
40/* indicates that this is a suballocation of a larger master range */
41#define PMEM_FLAGS_CONNECTED (0x1 << 1)
42/* indicates this is a master and not a sub allocation and that it is mmaped */
43#define PMEM_FLAGS_MASTERMAP (0x1 << 2)
44/* submap and unsubmap flags indicate:
45 * 00: subregion has never been mmaped
46 * 10: subregion has been mmaped, reference to the mm was taken
47 * 11: subretion has ben released, refernece to the mm still held
48 * 01: subretion has been released, reference to the mm has been released
49 */
50#define PMEM_FLAGS_SUBMAP (0x1 << 3)
51#define PMEM_FLAGS_UNSUBMAP (0x1 << 4)
52
53
54struct pmem_data {
55 /* in alloc mode: an index into the bitmap
56 * in no_alloc mode: the size of the allocation */
57 int index;
58 /* see flags above for descriptions */
59 unsigned int flags;
60 /* protects this data field, if the mm_mmap sem will be held at the
61 * same time as this sem, the mm sem must be taken first (as this is
62 * the order for vma_open and vma_close ops */
63 struct rw_semaphore sem;
64 /* info about the mmaping process */
65 struct vm_area_struct *vma;
66 /* task struct of the mapping process */
67 struct task_struct *task;
68 /* process id of teh mapping process */
69 pid_t pid;
70 /* file descriptor of the master */
71 int master_fd;
72 /* file struct of the master */
73 struct file *master_file;
74 /* a list of currently available regions if this is a suballocation */
75 struct list_head region_list;
76 /* a linked list of data so we can access them for debugging */
77 struct list_head list;
78#if PMEM_DEBUG
79 int ref;
80#endif
81};
82
83struct pmem_bits {
84 unsigned allocated:1; /* 1 if allocated, 0 if free */
85 unsigned order:7; /* size of the region in pmem space */
86};
87
88struct pmem_region_node {
89 struct pmem_region region;
90 struct list_head list;
91};
92
93#define PMEM_DEBUG_MSGS 0
94#if PMEM_DEBUG_MSGS
95#define DLOG(fmt, args...) \
96 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
97 ##args); } \
98 while (0)
99#else
100#define DLOG(x...) do {} while (0)
101#endif
102
103struct pmem_info {
104 struct miscdevice dev;
105 /* physical start address of the remaped pmem space */
106 unsigned long base;
107 /* vitual start address of the remaped pmem space */
108 unsigned char __iomem *vbase;
109 /* total size of the pmem space */
110 unsigned long size;
111 /* number of entries in the pmem space */
112 unsigned long num_entries;
113 /* pfn of the garbage page in memory */
114 unsigned long garbage_pfn;
115 /* index of the garbage page in the pmem space */
116 int garbage_index;
117 /* the bitmap for the region indicating which entries are allocated
118 * and which are free */
119 struct pmem_bits *bitmap;
120 /* indicates the region should not be managed with an allocator */
121 unsigned no_allocator;
122 /* indicates maps of this region should be cached, if a mix of
123 * cached and uncached is desired, set this and open the device with
124 * O_SYNC to get an uncached region */
125 unsigned cached;
126 unsigned buffered;
127 /* in no_allocator mode the first mapper gets the whole space and sets
128 * this flag */
129 unsigned allocated;
130 /* for debugging, creates a list of pmem file structs, the
131 * data_list_sem should be taken before pmem_data->sem if both are
132 * needed */
133 struct semaphore data_list_sem;
134 struct list_head data_list;
135 /* pmem_sem protects the bitmap array
136 * a write lock should be held when modifying entries in bitmap
137 * a read lock should be held when reading data from bits or
138 * dereferencing a pointer into bitmap
139 *
140 * pmem_data->sem protects the pmem data of a particular file
141 * Many of the function that require the pmem_data->sem have a non-
142 * locking version for when the caller is already holding that sem.
143 *
144 * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
145 * down(pmem_data->sem) => down(bitmap_sem)
146 */
147 struct rw_semaphore bitmap_sem;
148
149 long (*ioctl)(struct file *, unsigned int, unsigned long);
150 int (*release)(struct inode *, struct file *);
151};
152
153static struct pmem_info pmem[PMEM_MAX_DEVICES];
154static int id_count;
155
156#define PMEM_IS_FREE(id, index) (!(pmem[id].bitmap[index].allocated))
157#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
158#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
159#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
160#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
161#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
162#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
163#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
164 PMEM_LEN(id, index))
165#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
166#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
167 PMEM_LEN(id, index))
168#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
169#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
170#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
171 (!(data->flags & PMEM_FLAGS_UNSUBMAP)))
172
173static int pmem_release(struct inode *, struct file *);
174static int pmem_mmap(struct file *, struct vm_area_struct *);
175static int pmem_open(struct inode *, struct file *);
176static long pmem_ioctl(struct file *, unsigned int, unsigned long);
177
178const struct file_operations pmem_fops = {
179 .release = pmem_release,
180 .mmap = pmem_mmap,
181 .open = pmem_open,
182 .unlocked_ioctl = pmem_ioctl,
183 .llseek = noop_llseek,
184};
185
186static int get_id(struct file *file)
187{
188 return MINOR(file->f_dentry->d_inode->i_rdev);
189}
190
191static int is_pmem_file(struct file *file)
192{
193 int id;
194
195 if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
196 return 0;
197 id = get_id(file);
198 if (unlikely(id >= PMEM_MAX_DEVICES))
199 return 0;
200 if (unlikely(file->f_dentry->d_inode->i_rdev !=
201 MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
202 return 0;
203 return 1;
204}
205
206static int has_allocation(struct file *file)
207{
208 struct pmem_data *data;
209 /* check is_pmem_file first if not accessed via pmem_file_ops */
210
211 if (unlikely(!file->private_data))
212 return 0;
213 data = file->private_data;
214 if (unlikely(data->index < 0))
215 return 0;
216 return 1;
217}
218
219static int is_master_owner(struct file *file)
220{
221 struct file *master_file;
222 struct pmem_data *data;
223 int put_needed, ret = 0;
224
225 if (!is_pmem_file(file) || !has_allocation(file))
226 return 0;
227 data = file->private_data;
228 if (PMEM_FLAGS_MASTERMAP & data->flags)
229 return 1;
230 master_file = fget_light(data->master_fd, &put_needed);
231 if (master_file && data->master_file == master_file)
232 ret = 1;
233 fput_light(master_file, put_needed);
234 return ret;
235}
236
237static int pmem_free(int id, int index)
238{
239 /* caller should hold the write lock on pmem_sem! */
240 int buddy, curr = index;
241 DLOG("index %d\n", index);
242
243 if (pmem[id].no_allocator) {
244 pmem[id].allocated = 0;
245 return 0;
246 }
247 /* clean up the bitmap, merging any buddies */
248 pmem[id].bitmap[curr].allocated = 0;
249 /* find a slots buddy Buddy# = Slot# ^ (1 << order)
250 * if the buddy is also free merge them
251 * repeat until the buddy is not free or end of the bitmap is reached
252 */
253 do {
254 buddy = PMEM_BUDDY_INDEX(id, curr);
255 if (PMEM_IS_FREE(id, buddy) &&
256 PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
257 PMEM_ORDER(id, buddy)++;
258 PMEM_ORDER(id, curr)++;
259 curr = min(buddy, curr);
260 } else {
261 break;
262 }
263 } while (curr < pmem[id].num_entries);
264
265 return 0;
266}
267
268static void pmem_revoke(struct file *file, struct pmem_data *data);
269
270static int pmem_release(struct inode *inode, struct file *file)
271{
272 struct pmem_data *data = file->private_data;
273 struct pmem_region_node *region_node;
274 struct list_head *elt, *elt2;
275 int id = get_id(file), ret = 0;
276
277
278 down(&pmem[id].data_list_sem);
279 /* if this file is a master, revoke all the memory in the connected
280 * files */
281 if (PMEM_FLAGS_MASTERMAP & data->flags) {
282 struct pmem_data *sub_data;
283 list_for_each(elt, &pmem[id].data_list) {
284 sub_data = list_entry(elt, struct pmem_data, list);
285 down_read(&sub_data->sem);
286 if (PMEM_IS_SUBMAP(sub_data) &&
287 file == sub_data->master_file) {
288 up_read(&sub_data->sem);
289 pmem_revoke(file, sub_data);
290 } else
291 up_read(&sub_data->sem);
292 }
293 }
294 list_del(&data->list);
295 up(&pmem[id].data_list_sem);
296
297
298 down_write(&data->sem);
299
300 /* if its not a conencted file and it has an allocation, free it */
301 if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
302 down_write(&pmem[id].bitmap_sem);
303 ret = pmem_free(id, data->index);
304 up_write(&pmem[id].bitmap_sem);
305 }
306
307 /* if this file is a submap (mapped, connected file), downref the
308 * task struct */
309 if (PMEM_FLAGS_SUBMAP & data->flags)
310 if (data->task) {
311 put_task_struct(data->task);
312 data->task = NULL;
313 }
314
315 file->private_data = NULL;
316
317 list_for_each_safe(elt, elt2, &data->region_list) {
318 region_node = list_entry(elt, struct pmem_region_node, list);
319 list_del(elt);
320 kfree(region_node);
321 }
322 BUG_ON(!list_empty(&data->region_list));
323
324 up_write(&data->sem);
325 kfree(data);
326 if (pmem[id].release)
327 ret = pmem[id].release(inode, file);
328
329 return ret;
330}
331
332static int pmem_open(struct inode *inode, struct file *file)
333{
334 struct pmem_data *data;
335 int id = get_id(file);
336 int ret = 0;
337
338 DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
339 /* setup file->private_data to indicate its unmapped */
340 /* you can only open a pmem device one time */
341 if (file->private_data != NULL)
342 return -1;
343 data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
344 if (!data) {
345 printk("pmem: unable to allocate memory for pmem metadata.");
346 return -1;
347 }
348 data->flags = 0;
349 data->index = -1;
350 data->task = NULL;
351 data->vma = NULL;
352 data->pid = 0;
353 data->master_file = NULL;
354#if PMEM_DEBUG
355 data->ref = 0;
356#endif
357 INIT_LIST_HEAD(&data->region_list);
358 init_rwsem(&data->sem);
359
360 file->private_data = data;
361 INIT_LIST_HEAD(&data->list);
362
363 down(&pmem[id].data_list_sem);
364 list_add(&data->list, &pmem[id].data_list);
365 up(&pmem[id].data_list_sem);
366 return ret;
367}
368
369static unsigned long pmem_order(unsigned long len)
370{
371 int i;
372
373 len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
374 len--;
375 for (i = 0; i < sizeof(len)*8; i++)
376 if (len >> i == 0)
377 break;
378 return i;
379}
380
381static int pmem_allocate(int id, unsigned long len)
382{
383 /* caller should hold the write lock on pmem_sem! */
384 /* return the corresponding pdata[] entry */
385 int curr = 0;
386 int end = pmem[id].num_entries;
387 int best_fit = -1;
388 unsigned long order = pmem_order(len);
389
390 if (pmem[id].no_allocator) {
391 DLOG("no allocator");
392 if ((len > pmem[id].size) || pmem[id].allocated)
393 return -1;
394 pmem[id].allocated = 1;
395 return len;
396 }
397
398 if (order > PMEM_MAX_ORDER)
399 return -1;
400 DLOG("order %lx\n", order);
401
402 /* look through the bitmap:
403 * if you find a free slot of the correct order use it
404 * otherwise, use the best fit (smallest with size > order) slot
405 */
406 while (curr < end) {
407 if (PMEM_IS_FREE(id, curr)) {
408 if (PMEM_ORDER(id, curr) == (unsigned char)order) {
409 /* set the not free bit and clear others */
410 best_fit = curr;
411 break;
412 }
413 if (PMEM_ORDER(id, curr) > (unsigned char)order &&
414 (best_fit < 0 ||
415 PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
416 best_fit = curr;
417 }
418 curr = PMEM_NEXT_INDEX(id, curr);
419 }
420
421 /* if best_fit < 0, there are no suitable slots,
422 * return an error
423 */
424 if (best_fit < 0) {
425 printk("pmem: no space left to allocate!\n");
426 return -1;
427 }
428
429 /* now partition the best fit:
430 * split the slot into 2 buddies of order - 1
431 * repeat until the slot is of the correct order
432 */
433 while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
434 int buddy;
435 PMEM_ORDER(id, best_fit) -= 1;
436 buddy = PMEM_BUDDY_INDEX(id, best_fit);
437 PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
438 }
439 pmem[id].bitmap[best_fit].allocated = 1;
440 return best_fit;
441}
442
443static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot)
444{
445 int id = get_id(file);
446#ifdef pgprot_noncached
447 if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
448 return pgprot_noncached(vma_prot);
449#endif
450#ifdef pgprot_ext_buffered
451 else if (pmem[id].buffered)
452 return pgprot_ext_buffered(vma_prot);
453#endif
454 return vma_prot;
455}
456
457static unsigned long pmem_start_addr(int id, struct pmem_data *data)
458{
459 if (pmem[id].no_allocator)
460 return PMEM_START_ADDR(id, 0);
461 else
462 return PMEM_START_ADDR(id, data->index);
463
464}
465
466static void *pmem_start_vaddr(int id, struct pmem_data *data)
467{
468 return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
469}
470
471static unsigned long pmem_len(int id, struct pmem_data *data)
472{
473 if (pmem[id].no_allocator)
474 return data->index;
475 else
476 return PMEM_LEN(id, data->index);
477}
478
479static int pmem_map_garbage(int id, struct vm_area_struct *vma,
480 struct pmem_data *data, unsigned long offset,
481 unsigned long len)
482{
483 int i, garbage_pages = len >> PAGE_SHIFT;
484
485 vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
486 for (i = 0; i < garbage_pages; i++) {
487 if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
488 pmem[id].garbage_pfn))
489 return -EAGAIN;
490 }
491 return 0;
492}
493
494static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
495 struct pmem_data *data, unsigned long offset,
496 unsigned long len)
497{
498 int garbage_pages;
499 DLOG("unmap offset %lx len %lx\n", offset, len);
500
501 BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
502
503 garbage_pages = len >> PAGE_SHIFT;
504 zap_page_range(vma, vma->vm_start + offset, len, NULL);
505 pmem_map_garbage(id, vma, data, offset, len);
506 return 0;
507}
508
509static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
510 struct pmem_data *data, unsigned long offset,
511 unsigned long len)
512{
513 DLOG("map offset %lx len %lx\n", offset, len);
514 BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
515 BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
516 BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
517 BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
518
519 if (io_remap_pfn_range(vma, vma->vm_start + offset,
520 (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
521 len, vma->vm_page_prot)) {
522 return -EAGAIN;
523 }
524 return 0;
525}
526
527static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
528 struct pmem_data *data, unsigned long offset,
529 unsigned long len)
530{
531 /* hold the mm semp for the vma you are modifying when you call this */
532 BUG_ON(!vma);
533 zap_page_range(vma, vma->vm_start + offset, len, NULL);
534 return pmem_map_pfn_range(id, vma, data, offset, len);
535}
536
537static void pmem_vma_open(struct vm_area_struct *vma)
538{
539 struct file *file = vma->vm_file;
540 struct pmem_data *data = file->private_data;
541 int id = get_id(file);
542 /* this should never be called as we don't support copying pmem
543 * ranges via fork */
544 BUG_ON(!has_allocation(file));
545 down_write(&data->sem);
546 /* remap the garbage pages, forkers don't get access to the data */
547 pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
548 up_write(&data->sem);
549}
550
551static void pmem_vma_close(struct vm_area_struct *vma)
552{
553 struct file *file = vma->vm_file;
554 struct pmem_data *data = file->private_data;
555
556 DLOG("current %u ppid %u file %p count %d\n", current->pid,
557 current->parent->pid, file, file_count(file));
558 if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
559 printk(KERN_WARNING "pmem: something is very wrong, you are "
560 "closing a vm backing an allocation that doesn't "
561 "exist!\n");
562 return;
563 }
564 down_write(&data->sem);
565 if (data->vma == vma) {
566 data->vma = NULL;
567 if ((data->flags & PMEM_FLAGS_CONNECTED) &&
568 (data->flags & PMEM_FLAGS_SUBMAP))
569 data->flags |= PMEM_FLAGS_UNSUBMAP;
570 }
571 /* the kernel is going to free this vma now anyway */
572 up_write(&data->sem);
573}
574
575static struct vm_operations_struct vm_ops = {
576 .open = pmem_vma_open,
577 .close = pmem_vma_close,
578};
579
580static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
581{
582 struct pmem_data *data;
583 int index;
584 unsigned long vma_size = vma->vm_end - vma->vm_start;
585 int ret = 0, id = get_id(file);
586
587 if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
588#if PMEM_DEBUG
589 printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
590 " and a multiple of pages_size.\n");
591#endif
592 return -EINVAL;
593 }
594
595 data = file->private_data;
596 down_write(&data->sem);
597 /* check this file isn't already mmaped, for submaps check this file
598 * has never been mmaped */
599 if ((data->flags & PMEM_FLAGS_MASTERMAP) ||
600 (data->flags & PMEM_FLAGS_SUBMAP) ||
601 (data->flags & PMEM_FLAGS_UNSUBMAP)) {
602#if PMEM_DEBUG
603 printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
604 "this file is already mmaped. %x\n", data->flags);
605#endif
606 ret = -EINVAL;
607 goto error;
608 }
609 /* if file->private_data == unalloced, alloc*/
610 if (data && data->index == -1) {
611 down_write(&pmem[id].bitmap_sem);
612 index = pmem_allocate(id, vma->vm_end - vma->vm_start);
613 up_write(&pmem[id].bitmap_sem);
614 data->index = index;
615 }
616 /* either no space was available or an error occured */
617 if (!has_allocation(file)) {
618 ret = -EINVAL;
619 printk("pmem: could not find allocation for map.\n");
620 goto error;
621 }
622
623 if (pmem_len(id, data) < vma_size) {
624#if PMEM_DEBUG
625 printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
626 "size of backing region [%lu].\n", vma_size,
627 pmem_len(id, data));
628#endif
629 ret = -EINVAL;
630 goto error;
631 }
632
633 vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
634 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot);
635
636 if (data->flags & PMEM_FLAGS_CONNECTED) {
637 struct pmem_region_node *region_node;
638 struct list_head *elt;
639 if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
640 printk("pmem: mmap failed in kernel!\n");
641 ret = -EAGAIN;
642 goto error;
643 }
644 list_for_each(elt, &data->region_list) {
645 region_node = list_entry(elt, struct pmem_region_node,
646 list);
647 DLOG("remapping file: %p %lx %lx\n", file,
648 region_node->region.offset,
649 region_node->region.len);
650 if (pmem_remap_pfn_range(id, vma, data,
651 region_node->region.offset,
652 region_node->region.len)) {
653 ret = -EAGAIN;
654 goto error;
655 }
656 }
657 data->flags |= PMEM_FLAGS_SUBMAP;
658 get_task_struct(current->group_leader);
659 data->task = current->group_leader;
660 data->vma = vma;
661#if PMEM_DEBUG
662 data->pid = current->pid;
663#endif
664 DLOG("submmapped file %p vma %p pid %u\n", file, vma,
665 current->pid);
666 } else {
667 if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
668 printk(KERN_INFO "pmem: mmap failed in kernel!\n");
669 ret = -EAGAIN;
670 goto error;
671 }
672 data->flags |= PMEM_FLAGS_MASTERMAP;
673 data->pid = current->pid;
674 }
675 vma->vm_ops = &vm_ops;
676error:
677 up_write(&data->sem);
678 return ret;
679}
680
681/* the following are the api for accessing pmem regions by other drivers
682 * from inside the kernel */
683int get_pmem_user_addr(struct file *file, unsigned long *start,
684 unsigned long *len)
685{
686 struct pmem_data *data;
687 if (!is_pmem_file(file) || !has_allocation(file)) {
688#if PMEM_DEBUG
689 printk(KERN_INFO "pmem: requested pmem data from invalid"
690 "file.\n");
691#endif
692 return -1;
693 }
694 data = file->private_data;
695 down_read(&data->sem);
696 if (data->vma) {
697 *start = data->vma->vm_start;
698 *len = data->vma->vm_end - data->vma->vm_start;
699 } else {
700 *start = 0;
701 *len = 0;
702 }
703 up_read(&data->sem);
704 return 0;
705}
706
707int get_pmem_addr(struct file *file, unsigned long *start,
708 unsigned long *vstart, unsigned long *len)
709{
710 struct pmem_data *data;
711 int id;
712
713 if (!is_pmem_file(file) || !has_allocation(file))
714 return -1;
715
716 data = file->private_data;
717 if (data->index == -1) {
718#if PMEM_DEBUG
719 printk(KERN_INFO "pmem: requested pmem data from file with no "
720 "allocation.\n");
721 return -1;
722#endif
723 }
724 id = get_id(file);
725
726 down_read(&data->sem);
727 *start = pmem_start_addr(id, data);
728 *len = pmem_len(id, data);
729 *vstart = (unsigned long)pmem_start_vaddr(id, data);
730 up_read(&data->sem);
731#if PMEM_DEBUG
732 down_write(&data->sem);
733 data->ref++;
734 up_write(&data->sem);
735#endif
736 return 0;
737}
738
739int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
740 unsigned long *len, struct file **filp)
741{
742 struct file *file;
743
744 file = fget(fd);
745 if (unlikely(file == NULL)) {
746 printk(KERN_INFO "pmem: requested data from file descriptor "
747 "that doesn't exist.");
748 return -1;
749 }
750
751 if (get_pmem_addr(file, start, vstart, len))
752 goto end;
753
754 if (filp)
755 *filp = file;
756 return 0;
757end:
758 fput(file);
759 return -1;
760}
761
762void put_pmem_file(struct file *file)
763{
764 struct pmem_data *data;
765 int id;
766
767 if (!is_pmem_file(file))
768 return;
769 id = get_id(file);
770 data = file->private_data;
771#if PMEM_DEBUG
772 down_write(&data->sem);
773 if (data->ref == 0) {
774 printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
775 pmem[id].dev.name, data->pid);
776 BUG();
777 }
778 data->ref--;
779 up_write(&data->sem);
780#endif
781 fput(file);
782}
783
784void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
785{
786 struct pmem_data *data;
787 int id;
788 void *vaddr;
789 struct pmem_region_node *region_node;
790 struct list_head *elt;
791 void *flush_start, *flush_end;
792
793 if (!is_pmem_file(file) || !has_allocation(file))
794 return;
795
796 id = get_id(file);
797 data = file->private_data;
798 if (!pmem[id].cached)
799 return;
800
801 down_read(&data->sem);
802 vaddr = pmem_start_vaddr(id, data);
803 /* if this isn't a submmapped file, flush the whole thing */
804 if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
805 dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
806 goto end;
807 }
808 /* otherwise, flush the region of the file we are drawing */
809 list_for_each(elt, &data->region_list) {
810 region_node = list_entry(elt, struct pmem_region_node, list);
811 if ((offset >= region_node->region.offset) &&
812 ((offset + len) <= (region_node->region.offset +
813 region_node->region.len))) {
814 flush_start = vaddr + region_node->region.offset;
815 flush_end = flush_start + region_node->region.len;
816 dmac_flush_range(flush_start, flush_end);
817 break;
818 }
819 }
820end:
821 up_read(&data->sem);
822}
823
824static int pmem_connect(unsigned long connect, struct file *file)
825{
826 struct pmem_data *data = file->private_data;
827 struct pmem_data *src_data;
828 struct file *src_file;
829 int ret = 0, put_needed;
830
831 down_write(&data->sem);
832 /* retrieve the src file and check it is a pmem file with an alloc */
833 src_file = fget_light(connect, &put_needed);
834 DLOG("connect %p to %p\n", file, src_file);
835 if (!src_file) {
836 printk(KERN_INFO "pmem: src file not found!\n");
837 ret = -EINVAL;
838 goto err_no_file;
839 }
840 if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
841 printk(KERN_INFO "pmem: src file is not a pmem file or has no "
842 "alloc!\n");
843 ret = -EINVAL;
844 goto err_bad_file;
845 }
846 src_data = src_file->private_data;
847
848 if (has_allocation(file) && (data->index != src_data->index)) {
849 printk(KERN_INFO "pmem: file is already mapped but doesn't "
850 "match this src_file!\n");
851 ret = -EINVAL;
852 goto err_bad_file;
853 }
854 data->index = src_data->index;
855 data->flags |= PMEM_FLAGS_CONNECTED;
856 data->master_fd = connect;
857 data->master_file = src_file;
858
859err_bad_file:
860 fput_light(src_file, put_needed);
861err_no_file:
862 up_write(&data->sem);
863 return ret;
864}
865
866static void pmem_unlock_data_and_mm(struct pmem_data *data,
867 struct mm_struct *mm)
868{
869 up_write(&data->sem);
870 if (mm != NULL) {
871 up_write(&mm->mmap_sem);
872 mmput(mm);
873 }
874}
875
876static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
877 struct mm_struct **locked_mm)
878{
879 int ret = 0;
880 struct mm_struct *mm = NULL;
881 *locked_mm = NULL;
882lock_mm:
883 down_read(&data->sem);
884 if (PMEM_IS_SUBMAP(data)) {
885 mm = get_task_mm(data->task);
886 if (!mm) {
887#if PMEM_DEBUG
888 printk(KERN_DEBUG "pmem: can't remap task is gone!\n");
889#endif
890 up_read(&data->sem);
891 return -1;
892 }
893 }
894 up_read(&data->sem);
895
896 if (mm)
897 down_write(&mm->mmap_sem);
898
899 down_write(&data->sem);
900 /* check that the file didn't get mmaped before we could take the
901 * data sem, this should be safe b/c you can only submap each file
902 * once */
903 if (PMEM_IS_SUBMAP(data) && !mm) {
904 pmem_unlock_data_and_mm(data, mm);
905 up_write(&data->sem);
906 goto lock_mm;
907 }
908 /* now check that vma.mm is still there, it could have been
909 * deleted by vma_close before we could get the data->sem */
910 if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
911 /* might as well release this */
912 if (data->flags & PMEM_FLAGS_SUBMAP) {
913 put_task_struct(data->task);
914 data->task = NULL;
915 /* lower the submap flag to show the mm is gone */
916 data->flags &= ~(PMEM_FLAGS_SUBMAP);
917 }
918 pmem_unlock_data_and_mm(data, mm);
919 return -1;
920 }
921 *locked_mm = mm;
922 return ret;
923}
924
925int pmem_remap(struct pmem_region *region, struct file *file,
926 unsigned operation)
927{
928 int ret;
929 struct pmem_region_node *region_node;
930 struct mm_struct *mm = NULL;
931 struct list_head *elt, *elt2;
932 int id = get_id(file);
933 struct pmem_data *data = file->private_data;
934
935 /* pmem region must be aligned on a page boundry */
936 if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
937 !PMEM_IS_PAGE_ALIGNED(region->len))) {
938#if PMEM_DEBUG
939 printk(KERN_DEBUG "pmem: request for unaligned pmem "
940 "suballocation %lx %lx\n", region->offset, region->len);
941#endif
942 return -EINVAL;
943 }
944
945 /* if userspace requests a region of len 0, there's nothing to do */
946 if (region->len == 0)
947 return 0;
948
949 /* lock the mm and data */
950 ret = pmem_lock_data_and_mm(file, data, &mm);
951 if (ret)
952 return 0;
953
954 /* only the owner of the master file can remap the client fds
955 * that back in it */
956 if (!is_master_owner(file)) {
957#if PMEM_DEBUG
958 printk("pmem: remap requested from non-master process\n");
959#endif
960 ret = -EINVAL;
961 goto err;
962 }
963
964 /* check that the requested range is within the src allocation */
965 if (unlikely((region->offset > pmem_len(id, data)) ||
966 (region->len > pmem_len(id, data)) ||
967 (region->offset + region->len > pmem_len(id, data)))) {
968#if PMEM_DEBUG
969 printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
970#endif
971 ret = -EINVAL;
972 goto err;
973 }
974
975 if (operation == PMEM_MAP) {
976 region_node = kmalloc(sizeof(struct pmem_region_node),
977 GFP_KERNEL);
978 if (!region_node) {
979 ret = -ENOMEM;
980#if PMEM_DEBUG
981 printk(KERN_INFO "No space to allocate metadata!");
982#endif
983 goto err;
984 }
985 region_node->region = *region;
986 list_add(&region_node->list, &data->region_list);
987 } else if (operation == PMEM_UNMAP) {
988 int found = 0;
989 list_for_each_safe(elt, elt2, &data->region_list) {
990 region_node = list_entry(elt, struct pmem_region_node,
991 list);
992 if (region->len == 0 ||
993 (region_node->region.offset == region->offset &&
994 region_node->region.len == region->len)) {
995 list_del(elt);
996 kfree(region_node);
997 found = 1;
998 }
999 }
1000 if (!found) {
1001#if PMEM_DEBUG
1002 printk("pmem: Unmap region does not map any mapped "
1003 "region!");
1004#endif
1005 ret = -EINVAL;
1006 goto err;
1007 }
1008 }
1009
1010 if (data->vma && PMEM_IS_SUBMAP(data)) {
1011 if (operation == PMEM_MAP)
1012 ret = pmem_remap_pfn_range(id, data->vma, data,
1013 region->offset, region->len);
1014 else if (operation == PMEM_UNMAP)
1015 ret = pmem_unmap_pfn_range(id, data->vma, data,
1016 region->offset, region->len);
1017 }
1018
1019err:
1020 pmem_unlock_data_and_mm(data, mm);
1021 return ret;
1022}
1023
1024static void pmem_revoke(struct file *file, struct pmem_data *data)
1025{
1026 struct pmem_region_node *region_node;
1027 struct list_head *elt, *elt2;
1028 struct mm_struct *mm = NULL;
1029 int id = get_id(file);
1030 int ret = 0;
1031
1032 data->master_file = NULL;
1033 ret = pmem_lock_data_and_mm(file, data, &mm);
1034 /* if lock_data_and_mm fails either the task that mapped the fd, or
1035 * the vma that mapped it have already gone away, nothing more
1036 * needs to be done */
1037 if (ret)
1038 return;
1039 /* unmap everything */
1040 /* delete the regions and region list nothing is mapped any more */
1041 if (data->vma)
1042 list_for_each_safe(elt, elt2, &data->region_list) {
1043 region_node = list_entry(elt, struct pmem_region_node,
1044 list);
1045 pmem_unmap_pfn_range(id, data->vma, data,
1046 region_node->region.offset,
1047 region_node->region.len);
1048 list_del(elt);
1049 kfree(region_node);
1050 }
1051 /* delete the master file */
1052 pmem_unlock_data_and_mm(data, mm);
1053}
1054
1055static void pmem_get_size(struct pmem_region *region, struct file *file)
1056{
1057 struct pmem_data *data = file->private_data;
1058 int id = get_id(file);
1059
1060 if (!has_allocation(file)) {
1061 region->offset = 0;
1062 region->len = 0;
1063 return;
1064 } else {
1065 region->offset = pmem_start_addr(id, data);
1066 region->len = pmem_len(id, data);
1067 }
1068 DLOG("offset %lx len %lx\n", region->offset, region->len);
1069}
1070
1071
1072static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1073{
1074 struct pmem_data *data;
1075 int id = get_id(file);
1076
1077 switch (cmd) {
1078 case PMEM_GET_PHYS:
1079 {
1080 struct pmem_region region;
1081 DLOG("get_phys\n");
1082 if (!has_allocation(file)) {
1083 region.offset = 0;
1084 region.len = 0;
1085 } else {
1086 data = file->private_data;
1087 region.offset = pmem_start_addr(id, data);
1088 region.len = pmem_len(id, data);
1089 }
1090 printk(KERN_INFO "pmem: request for physical address "
1091 "of pmem region from process %d.\n", current->pid);
1092 if (copy_to_user((void __user *)arg, &region,
1093 sizeof(struct pmem_region)))
1094 return -EFAULT;
1095 break;
1096 }
1097 case PMEM_MAP:
1098 {
1099 struct pmem_region region;
1100 if (copy_from_user(&region, (void __user *)arg,
1101 sizeof(struct pmem_region)))
1102 return -EFAULT;
1103 data = file->private_data;
1104 return pmem_remap(&region, file, PMEM_MAP);
1105 }
1106 break;
1107 case PMEM_UNMAP:
1108 {
1109 struct pmem_region region;
1110 if (copy_from_user(&region, (void __user *)arg,
1111 sizeof(struct pmem_region)))
1112 return -EFAULT;
1113 data = file->private_data;
1114 return pmem_remap(&region, file, PMEM_UNMAP);
1115 break;
1116 }
1117 case PMEM_GET_SIZE:
1118 {
1119 struct pmem_region region;
1120 DLOG("get_size\n");
1121 pmem_get_size(&region, file);
1122 if (copy_to_user((void __user *)arg, &region,
1123 sizeof(struct pmem_region)))
1124 return -EFAULT;
1125 break;
1126 }
1127 case PMEM_GET_TOTAL_SIZE:
1128 {
1129 struct pmem_region region;
1130 DLOG("get total size\n");
1131 region.offset = 0;
1132 get_id(file);
1133 region.len = pmem[id].size;
1134 if (copy_to_user((void __user *)arg, &region,
1135 sizeof(struct pmem_region)))
1136 return -EFAULT;
1137 break;
1138 }
1139 case PMEM_ALLOCATE:
1140 {
1141 if (has_allocation(file))
1142 return -EINVAL;
1143 data = file->private_data;
1144 data->index = pmem_allocate(id, arg);
1145 break;
1146 }
1147 case PMEM_CONNECT:
1148 DLOG("connect\n");
1149 return pmem_connect(arg, file);
1150 break;
1151 default:
1152 if (pmem[id].ioctl)
1153 return pmem[id].ioctl(file, cmd, arg);
1154 return -EINVAL;
1155 }
1156 return 0;
1157}
1158
1159#if PMEM_DEBUG
1160static ssize_t debug_open(struct inode *inode, struct file *file)
1161{
1162 file->private_data = inode->i_private;
1163 return 0;
1164}
1165
1166static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
1167 loff_t *ppos)
1168{
1169 struct list_head *elt, *elt2;
1170 struct pmem_data *data;
1171 struct pmem_region_node *region_node;
1172 int id = (int)file->private_data;
1173 const int debug_bufmax = 4096;
1174 static char buffer[4096];
1175 int n = 0;
1176
1177 DLOG("debug open\n");
1178 n = scnprintf(buffer, debug_bufmax,
1179 "pid #: mapped regions (offset, len) (offset,len)...\n");
1180
1181 down(&pmem[id].data_list_sem);
1182 list_for_each(elt, &pmem[id].data_list) {
1183 data = list_entry(elt, struct pmem_data, list);
1184 down_read(&data->sem);
1185 n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
1186 data->pid);
1187 list_for_each(elt2, &data->region_list) {
1188 region_node = list_entry(elt2, struct pmem_region_node,
1189 list);
1190 n += scnprintf(buffer + n, debug_bufmax - n,
1191 "(%lx,%lx) ",
1192 region_node->region.offset,
1193 region_node->region.len);
1194 }
1195 n += scnprintf(buffer + n, debug_bufmax - n, "\n");
1196 up_read(&data->sem);
1197 }
1198 up(&pmem[id].data_list_sem);
1199
1200 n++;
1201 buffer[n] = 0;
1202 return simple_read_from_buffer(buf, count, ppos, buffer, n);
1203}
1204
1205static struct file_operations debug_fops = {
1206 .read = debug_read,
1207 .open = debug_open,
1208 .llseek = default_llseek,
1209};
1210#endif
1211
1212#if 0
1213static struct miscdevice pmem_dev = {
1214 .name = "pmem",
1215 .fops = &pmem_fops,
1216};
1217#endif
1218
1219int pmem_setup(struct android_pmem_platform_data *pdata,
1220 long (*ioctl)(struct file *, unsigned int, unsigned long),
1221 int (*release)(struct inode *, struct file *))
1222{
1223 int err = 0;
1224 int i, index = 0;
1225 int id = id_count;
1226 id_count++;
1227
1228 pmem[id].no_allocator = pdata->no_allocator;
1229 pmem[id].cached = pdata->cached;
1230 pmem[id].buffered = pdata->buffered;
1231 pmem[id].base = pdata->start;
1232 pmem[id].size = pdata->size;
1233 pmem[id].ioctl = ioctl;
1234 pmem[id].release = release;
1235 init_rwsem(&pmem[id].bitmap_sem);
1236 sema_init(&pmem[id].data_list_sem, 1);
1237 INIT_LIST_HEAD(&pmem[id].data_list);
1238 pmem[id].dev.name = pdata->name;
1239 pmem[id].dev.minor = id;
1240 pmem[id].dev.fops = &pmem_fops;
1241 printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
1242
1243 err = misc_register(&pmem[id].dev);
1244 if (err) {
1245 printk(KERN_ALERT "Unable to register pmem driver!\n");
1246 goto err_cant_register_device;
1247 }
1248 pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
1249
1250 pmem[id].bitmap = kcalloc(pmem[id].num_entries,
1251 sizeof(struct pmem_bits), GFP_KERNEL);
1252 if (!pmem[id].bitmap)
1253 goto err_no_mem_for_metadata;
1254
1255 for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
1256 if ((pmem[id].num_entries) & 1<<i) {
1257 PMEM_ORDER(id, index) = i;
1258 index = PMEM_NEXT_INDEX(id, index);
1259 }
1260 }
1261
1262 if (pmem[id].cached)
1263 pmem[id].vbase = ioremap_cached(pmem[id].base,
1264 pmem[id].size);
1265#ifdef ioremap_ext_buffered
1266 else if (pmem[id].buffered)
1267 pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
1268 pmem[id].size);
1269#endif
1270 else
1271 pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
1272
1273 if (pmem[id].vbase == 0)
1274 goto error_cant_remap;
1275
1276 pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
1277 if (pmem[id].no_allocator)
1278 pmem[id].allocated = 0;
1279
1280#if PMEM_DEBUG
1281 debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
1282 &debug_fops);
1283#endif
1284 return 0;
1285error_cant_remap:
1286 kfree(pmem[id].bitmap);
1287err_no_mem_for_metadata:
1288 misc_deregister(&pmem[id].dev);
1289err_cant_register_device:
1290 return -1;
1291}
1292
1293static int pmem_probe(struct platform_device *pdev)
1294{
1295 struct android_pmem_platform_data *pdata;
1296
1297 if (!pdev || !pdev->dev.platform_data) {
1298 printk(KERN_ALERT "Unable to probe pmem!\n");
1299 return -1;
1300 }
1301 pdata = pdev->dev.platform_data;
1302 return pmem_setup(pdata, NULL, NULL);
1303}
1304
1305
1306static int pmem_remove(struct platform_device *pdev)
1307{
1308 int id = pdev->id;
1309 __free_page(pfn_to_page(pmem[id].garbage_pfn));
1310 misc_deregister(&pmem[id].dev);
1311 return 0;
1312}
1313
1314static struct platform_driver pmem_driver = {
1315 .probe = pmem_probe,
1316 .remove = pmem_remove,
1317 .driver = { .name = "android_pmem" }
1318};
1319
1320
1321static int __init pmem_init(void)
1322{
1323 return platform_driver_register(&pmem_driver);
1324}
1325
1326static void __exit pmem_exit(void)
1327{
1328 platform_driver_unregister(&pmem_driver);
1329}
1330
1331module_init(pmem_init);
1332module_exit(pmem_exit);
1333
diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile
deleted file mode 100644
index 44ae6b4b47ec..000000000000
--- a/drivers/staging/dream/qdsp5/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
1ccflags-y:=-Idrivers/staging/dream/include
2obj-y += adsp.o
3ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
4obj-y += adsp_info.o
5obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o
6else
7obj-y += adsp_6225.o
8endif
9
10obj-y += adsp_driver.o
11obj-y += adsp_video_verify_cmd.o
12obj-y += adsp_videoenc_verify_cmd.o
13obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o
14obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o
15obj-y += adsp_lpm_verify_cmd.o
16obj-y += audio_out.o audio_in.o audio_mp3.o audmgr.o audpp.o
17obj-y += snd.o
18
diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c
deleted file mode 100644
index f1e9d81674e8..000000000000
--- a/drivers/staging/dream/qdsp5/adsp.c
+++ /dev/null
@@ -1,1159 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp.c
2 *
3 * Register/Interrupt access for userspace aDSP library.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 * Author: Iliyan Malchev <ibm@android.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20/* TODO:
21 * - move shareable rpc code outside of adsp.c
22 * - general solution for virt->phys patchup
23 * - queue IDs should be relative to modules
24 * - disallow access to non-associated queues
25 */
26
27#include <linux/clk.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/kernel.h>
31#include <linux/kthread.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <linux/uaccess.h>
35#include <linux/wait.h>
36
37static inline void prevent_suspend(void)
38{
39}
40static inline void allow_suspend(void)
41{
42}
43
44#include <linux/io.h>
45#include <mach/msm_iomap.h>
46#include "adsp.h"
47
48#define INT_ADSP INT_ADSP_A9_A11
49
50static struct adsp_info adsp_info;
51static struct msm_rpc_endpoint *rpc_cb_server_client;
52static struct msm_adsp_module *adsp_modules;
53static int adsp_open_count;
54static DEFINE_MUTEX(adsp_open_lock);
55
56/* protect interactions with the ADSP command/message queue */
57static spinlock_t adsp_cmd_lock;
58
59static uint32_t current_image = -1;
60
61void adsp_set_image(struct adsp_info *info, uint32_t image)
62{
63 current_image = image;
64}
65
66/*
67 * Checks whether the module_id is available in the
68 * module_entries table.If module_id is available returns `0`.
69 * If module_id is not available returns `-ENXIO`.
70 */
71#if CONFIG_MSM_AMSS_VERSION >= 6350
72static int32_t adsp_validate_module(uint32_t module_id)
73{
74 uint32_t *ptr;
75 uint32_t module_index;
76 uint32_t num_mod_entries;
77
78 ptr = adsp_info.init_info_ptr->module_entries;
79 num_mod_entries = adsp_info.init_info_ptr->module_table_size;
80
81 for (module_index = 0; module_index < num_mod_entries; module_index++)
82 if (module_id == ptr[module_index])
83 return 0;
84
85 return -ENXIO;
86}
87#else
88static inline int32_t adsp_validate_module(uint32_t module_id) { return 0; }
89#endif
90
91uint32_t adsp_get_module(struct adsp_info *info, uint32_t task)
92{
93 BUG_ON(current_image == -1UL);
94 return info->task_to_module[current_image][task];
95}
96
97uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id)
98{
99 BUG_ON(current_image == -1UL);
100 return info->queue_offset[current_image][queue_id];
101}
102
103static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module,
104 struct msm_adsp_module *adsp_module)
105{
106 int rc;
107 struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
108 struct rpc_reply_hdr *rpc_rsp;
109
110 msm_rpc_setup_req(&rpc_req.hdr,
111 RPC_ADSP_RTOS_ATOM_PROG,
112 msm_rpc_get_vers(adsp_module->rpc_client),
113 RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
114
115 rpc_req.gotit = cpu_to_be32(1);
116 rpc_req.cmd = cpu_to_be32(cmd);
117 rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
118 rpc_req.module = cpu_to_be32(module);
119 rc = msm_rpc_write(adsp_module->rpc_client, &rpc_req, sizeof(rpc_req));
120 if (rc < 0) {
121 pr_err("adsp: could not send RPC request: %d\n", rc);
122 return rc;
123 }
124
125 rc = msm_rpc_read(adsp_module->rpc_client,
126 (void **)&rpc_rsp, -1, (5*HZ));
127 if (rc < 0) {
128 pr_err("adsp: error receiving RPC reply: %d (%d)\n",
129 rc, -ERESTARTSYS);
130 return rc;
131 }
132
133 if (be32_to_cpu(rpc_rsp->reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) {
134 pr_err("adsp: RPC call was denied!\n");
135 kfree(rpc_rsp);
136 return -EPERM;
137 }
138
139 if (be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat) !=
140 RPC_ACCEPTSTAT_SUCCESS) {
141 pr_err("adsp error: RPC call was not successful (%d)\n",
142 be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat));
143 kfree(rpc_rsp);
144 return -EINVAL;
145 }
146
147 kfree(rpc_rsp);
148 return 0;
149}
150
151#if CONFIG_MSM_AMSS_VERSION >= 6350
152static int get_module_index(uint32_t id)
153{
154 int mod_idx;
155 for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++)
156 if (adsp_info.module[mod_idx].id == id)
157 return mod_idx;
158
159 return -ENXIO;
160}
161#endif
162
163static struct msm_adsp_module *find_adsp_module_by_id(
164 struct adsp_info *info, uint32_t id)
165{
166 if (id > info->max_module_id) {
167 return NULL;
168 } else {
169#if CONFIG_MSM_AMSS_VERSION >= 6350
170 id = get_module_index(id);
171 if (id < 0)
172 return NULL;
173#endif
174 return info->id_to_module[id];
175 }
176}
177
178static struct msm_adsp_module *find_adsp_module_by_name(
179 struct adsp_info *info, const char *name)
180{
181 unsigned n;
182 for (n = 0; n < info->module_count; n++)
183 if (!strcmp(name, adsp_modules[n].name))
184 return adsp_modules + n;
185 return NULL;
186}
187
188static int adsp_rpc_init(struct msm_adsp_module *adsp_module)
189{
190 /* remove the original connect once compatible support is complete */
191 adsp_module->rpc_client = msm_rpc_connect(
192 RPC_ADSP_RTOS_ATOM_PROG,
193 RPC_ADSP_RTOS_ATOM_VERS,
194 MSM_RPC_UNINTERRUPTIBLE);
195
196 if (IS_ERR(adsp_module->rpc_client)) {
197 int rc = PTR_ERR(adsp_module->rpc_client);
198 adsp_module->rpc_client = 0;
199 pr_err("adsp: could not open rpc client: %d\n", rc);
200 return rc;
201 }
202
203 return 0;
204}
205
206#if CONFIG_MSM_AMSS_VERSION >= 6350
207/*
208 * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get
209 * queue offsets and module entries (init info) as part of the event.
210 */
211static void msm_get_init_info(void)
212{
213 int rc;
214 struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
215
216 adsp_info.init_info_rpc_client = msm_rpc_connect(
217 RPC_ADSP_RTOS_ATOM_PROG,
218 RPC_ADSP_RTOS_ATOM_VERS,
219 MSM_RPC_UNINTERRUPTIBLE);
220 if (IS_ERR(adsp_info.init_info_rpc_client)) {
221 rc = PTR_ERR(adsp_info.init_info_rpc_client);
222 adsp_info.init_info_rpc_client = 0;
223 pr_err("adsp: could not open rpc client: %d\n", rc);
224 return;
225 }
226
227 msm_rpc_setup_req(&rpc_req.hdr,
228 RPC_ADSP_RTOS_ATOM_PROG,
229 msm_rpc_get_vers(adsp_info.init_info_rpc_client),
230 RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
231
232 rpc_req.gotit = cpu_to_be32(1);
233 rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO);
234 rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
235 rpc_req.module = 0;
236
237 rc = msm_rpc_write(adsp_info.init_info_rpc_client,
238 &rpc_req, sizeof(rpc_req));
239 if (rc < 0)
240 pr_err("adsp: could not send RPC request: %d\n", rc);
241}
242#endif
243
244int msm_adsp_get(const char *name, struct msm_adsp_module **out,
245 struct msm_adsp_ops *ops, void *driver_data)
246{
247 struct msm_adsp_module *module;
248 int rc = 0;
249
250#if CONFIG_MSM_AMSS_VERSION >= 6350
251 static uint32_t init_info_cmd_sent;
252 if (!init_info_cmd_sent) {
253 msm_get_init_info();
254 init_waitqueue_head(&adsp_info.init_info_wait);
255 rc = wait_event_timeout(adsp_info.init_info_wait,
256 adsp_info.init_info_state == ADSP_STATE_INIT_INFO,
257 5 * HZ);
258 if (!rc) {
259 pr_info("adsp: INIT_INFO failed\n");
260 return -ETIMEDOUT;
261 }
262 init_info_cmd_sent++;
263 }
264#endif
265
266 module = find_adsp_module_by_name(&adsp_info, name);
267 if (!module)
268 return -ENODEV;
269
270 mutex_lock(&module->lock);
271 pr_info("adsp: opening module %s\n", module->name);
272 if (module->open_count++ == 0 && module->clk)
273 clk_enable(module->clk);
274
275 mutex_lock(&adsp_open_lock);
276 if (adsp_open_count++ == 0) {
277 enable_irq(INT_ADSP);
278 prevent_suspend();
279 }
280 mutex_unlock(&adsp_open_lock);
281
282 if (module->ops) {
283 rc = -EBUSY;
284 goto done;
285 }
286
287 rc = adsp_rpc_init(module);
288 if (rc)
289 goto done;
290
291 module->ops = ops;
292 module->driver_data = driver_data;
293 *out = module;
294 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP,
295 module->id, module);
296 if (rc) {
297 module->ops = NULL;
298 module->driver_data = NULL;
299 *out = NULL;
300 pr_err("adsp: REGISTER_APP failed\n");
301 goto done;
302 }
303
304 pr_info("adsp: module %s has been registered\n", module->name);
305
306done:
307 mutex_lock(&adsp_open_lock);
308 if (rc && --adsp_open_count == 0) {
309 disable_irq(INT_ADSP);
310 allow_suspend();
311 }
312 if (rc && --module->open_count == 0 && module->clk)
313 clk_disable(module->clk);
314 mutex_unlock(&adsp_open_lock);
315 mutex_unlock(&module->lock);
316 return rc;
317}
318EXPORT_SYMBOL(msm_adsp_get);
319
320static int msm_adsp_disable_locked(struct msm_adsp_module *module);
321
322void msm_adsp_put(struct msm_adsp_module *module)
323{
324 unsigned long flags;
325
326 mutex_lock(&module->lock);
327 if (--module->open_count == 0 && module->clk)
328 clk_disable(module->clk);
329 if (module->ops) {
330 pr_info("adsp: closing module %s\n", module->name);
331
332 /* lock to ensure a dsp event cannot be delivered
333 * during or after removal of the ops and driver_data
334 */
335 spin_lock_irqsave(&adsp_cmd_lock, flags);
336 module->ops = NULL;
337 module->driver_data = NULL;
338 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
339
340 if (module->state != ADSP_STATE_DISABLED) {
341 pr_info("adsp: disabling module %s\n", module->name);
342 msm_adsp_disable_locked(module);
343 }
344
345 msm_rpc_close(module->rpc_client);
346 module->rpc_client = 0;
347 if (--adsp_open_count == 0) {
348 disable_irq(INT_ADSP);
349 allow_suspend();
350 pr_info("adsp: disable interrupt\n");
351 }
352 } else {
353 pr_info("adsp: module %s is already closed\n", module->name);
354 }
355 mutex_unlock(&module->lock);
356}
357EXPORT_SYMBOL(msm_adsp_put);
358
359/* this should be common code with rpc_servers.c */
360static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client,
361 uint32_t xid, uint32_t accept_status)
362{
363 int rc = 0;
364 uint8_t reply_buf[sizeof(struct rpc_reply_hdr)];
365 struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf;
366
367 reply->xid = cpu_to_be32(xid);
368 reply->type = cpu_to_be32(1); /* reply */
369 reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
370
371 reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status);
372 reply->data.acc_hdr.verf_flavor = 0;
373 reply->data.acc_hdr.verf_length = 0;
374
375 rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf));
376 if (rc < 0)
377 pr_err("adsp: could not write RPC response: %d\n", rc);
378 return rc;
379}
380
381int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
382 void *cmd_buf, size_t cmd_size)
383{
384 uint32_t ctrl_word;
385 uint32_t dsp_q_addr;
386 uint32_t dsp_addr;
387 uint32_t cmd_id = 0;
388 int cnt = 0;
389 int ret_status = 0;
390 unsigned long flags;
391 struct adsp_info *info = module->info;
392
393 spin_lock_irqsave(&adsp_cmd_lock, flags);
394
395 if (module->state != ADSP_STATE_ENABLED) {
396 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
397 pr_err("adsp: module %s not enabled before write\n",
398 module->name);
399 return -ENODEV;
400 }
401 if (adsp_validate_module(module->id)) {
402 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
403 pr_info("adsp: module id validation failed %s %d\n",
404 module->name, module->id);
405 return -ENXIO;
406 }
407 dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr);
408 dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M;
409
410 /* Poll until the ADSP is ready to accept a command.
411 * Wait for 100us, return error if it's not responding.
412 * If this returns an error, we need to disable ALL modules and
413 * then retry.
414 */
415 while (((ctrl_word = readl(info->write_ctrl)) &
416 ADSP_RTOS_WRITE_CTRL_WORD_READY_M) !=
417 ADSP_RTOS_WRITE_CTRL_WORD_READY_V) {
418 if (cnt > 100) {
419 pr_err("adsp: timeout waiting for DSP write ready\n");
420 ret_status = -EIO;
421 goto fail;
422 }
423 pr_warning("adsp: waiting for DSP write ready\n");
424 udelay(1);
425 cnt++;
426 }
427
428 /* Set the mutex bits */
429 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
430 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
431
432 /* Clear the command bits */
433 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
434
435 /* Set the queue address bits */
436 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
437 ctrl_word |= dsp_q_addr;
438
439 writel(ctrl_word, info->write_ctrl);
440
441 /* Generate an interrupt to the DSP. This notifies the DSP that
442 * we are about to send a command on this particular queue. The
443 * DSP will in response change its state.
444 */
445 writel(1, info->send_irq);
446
447 /* Poll until the adsp responds to the interrupt; this does not
448 * generate an interrupt from the adsp. This should happen within
449 * 5ms.
450 */
451 cnt = 0;
452 while ((readl(info->write_ctrl) &
453 ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) ==
454 ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) {
455 if (cnt > 5000) {
456 pr_err("adsp: timeout waiting for adsp ack\n");
457 ret_status = -EIO;
458 goto fail;
459 }
460 udelay(1);
461 cnt++;
462 }
463
464 /* Read the ctrl word */
465 ctrl_word = readl(info->write_ctrl);
466
467 if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) !=
468 ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) {
469 ret_status = -EAGAIN;
470 goto fail;
471 }
472
473 /* Ctrl word status bits were 00, no error in the ctrl word */
474
475 /* Get the DSP buffer address */
476 dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) +
477 (uint32_t)MSM_AD5_BASE;
478
479 if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
480 uint16_t *buf_ptr = (uint16_t *) cmd_buf;
481 uint16_t *dsp_addr16 = (uint16_t *)dsp_addr;
482 cmd_size /= sizeof(uint16_t);
483
484 /* Save the command ID */
485 cmd_id = (uint32_t) buf_ptr[0];
486
487 /* Copy the command to DSP memory */
488 cmd_size++;
489 while (--cmd_size)
490 *dsp_addr16++ = *buf_ptr++;
491 } else {
492 uint32_t *buf_ptr = (uint32_t *) cmd_buf;
493 uint32_t *dsp_addr32 = (uint32_t *)dsp_addr;
494 cmd_size /= sizeof(uint32_t);
495
496 /* Save the command ID */
497 cmd_id = buf_ptr[0];
498
499 cmd_size++;
500 while (--cmd_size)
501 *dsp_addr32++ = *buf_ptr++;
502 }
503
504 /* Set the mutex bits */
505 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
506 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
507
508 /* Set the command bits to write done */
509 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
510 ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V;
511
512 /* Set the queue address bits */
513 ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
514 ctrl_word |= dsp_q_addr;
515
516 writel(ctrl_word, info->write_ctrl);
517
518 /* Generate an interrupt to the DSP. It does not respond with
519 * an interrupt, and we do not need to wait for it to
520 * acknowledge, because it will hold the mutex lock until it's
521 * ready to receive more commands again.
522 */
523 writel(1, info->send_irq);
524
525 module->num_commands++;
526
527fail:
528 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
529 return ret_status;
530}
531EXPORT_SYMBOL(msm_adsp_write);
532
533int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
534 void *cmd_buf, size_t cmd_size)
535{
536 int rc, retries = 0;
537 do {
538 rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, cmd_size);
539 if (rc == -EAGAIN)
540 udelay(10);
541 } while(rc == -EAGAIN && retries++ < 100);
542 if (retries > 50)
543 pr_warning("adsp: %s command took %d attempts: rc %d\n",
544 module->name, retries, rc);
545 return rc;
546}
547
548#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
549static void *modem_event_addr;
550#if CONFIG_MSM_AMSS_VERSION >= 6350
551static void read_modem_event(void *buf, size_t len)
552{
553 uint32_t *dptr = buf;
554 struct rpc_adsp_rtos_modem_to_app_args_t *sptr;
555 struct adsp_rtos_mp_mtoa_type *pkt_ptr;
556
557 sptr = modem_event_addr;
558 pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
559
560 dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event);
561 dptr[1] = be32_to_cpu(pkt_ptr->module);
562 dptr[2] = be32_to_cpu(pkt_ptr->image);
563}
564#else
565static void read_modem_event(void *buf, size_t len)
566{
567 uint32_t *dptr = buf;
568 struct rpc_adsp_rtos_modem_to_app_args_t *sptr =
569 modem_event_addr;
570 dptr[0] = be32_to_cpu(sptr->event);
571 dptr[1] = be32_to_cpu(sptr->module);
572 dptr[2] = be32_to_cpu(sptr->image);
573}
574#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
575#endif /* CONFIG_MSM_ADSP_REPORT_EVENTS */
576
577static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req)
578{
579 struct rpc_adsp_rtos_modem_to_app_args_t *args =
580 (struct rpc_adsp_rtos_modem_to_app_args_t *)req;
581 uint32_t event;
582 uint32_t proc_id;
583 uint32_t module_id;
584 uint32_t image;
585 struct msm_adsp_module *module;
586#if CONFIG_MSM_AMSS_VERSION >= 6350
587 struct adsp_rtos_mp_mtoa_type *pkt_ptr =
588 &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
589
590 event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event);
591 proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id);
592 module_id = be32_to_cpu(pkt_ptr->module);
593 image = be32_to_cpu(pkt_ptr->image);
594
595 if (be32_to_cpu(args->mtoa_pkt.desc_field) == RPC_ADSP_RTOS_INIT_INFO) {
596 struct queue_to_offset_type *qptr;
597 struct queue_to_offset_type *qtbl;
598 uint32_t *mptr;
599 uint32_t *mtbl;
600 uint32_t q_idx;
601 uint32_t num_entries;
602 uint32_t entries_per_image;
603 struct adsp_rtos_mp_mtoa_init_info_type *iptr;
604 struct adsp_rtos_mp_mtoa_init_info_type *sptr;
605 int32_t i_no, e_idx;
606
607 pr_info("adsp:INIT_INFO Event\n");
608 sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.
609 mp_mtoa_init_packet;
610
611 iptr = adsp_info.init_info_ptr;
612 iptr->image_count = be32_to_cpu(sptr->image_count);
613 iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets);
614 num_entries = iptr->num_queue_offsets;
615 qptr = &sptr->queue_offsets_tbl[0][0];
616 for (i_no = 0; i_no < iptr->image_count; i_no++) {
617 qtbl = &iptr->queue_offsets_tbl[i_no][0];
618 for (e_idx = 0; e_idx < num_entries; e_idx++) {
619 qtbl[e_idx].offset = be32_to_cpu(qptr->offset);
620 qtbl[e_idx].queue = be32_to_cpu(qptr->queue);
621 q_idx = be32_to_cpu(qptr->queue);
622 iptr->queue_offsets[i_no][q_idx] =
623 qtbl[e_idx].offset;
624 qptr++;
625 }
626 }
627
628 num_entries = be32_to_cpu(sptr->num_task_module_entries);
629 iptr->num_task_module_entries = num_entries;
630 entries_per_image = num_entries / iptr->image_count;
631 mptr = &sptr->task_to_module_tbl[0][0];
632 for (i_no = 0; i_no < iptr->image_count; i_no++) {
633 mtbl = &iptr->task_to_module_tbl[i_no][0];
634 for (e_idx = 0; e_idx < entries_per_image; e_idx++) {
635 mtbl[e_idx] = be32_to_cpu(*mptr);
636 mptr++;
637 }
638 }
639
640 iptr->module_table_size = be32_to_cpu(sptr->module_table_size);
641 mptr = &sptr->module_entries[0];
642 for (i_no = 0; i_no < iptr->module_table_size; i_no++)
643 iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]);
644 adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
645 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
646 RPC_ACCEPTSTAT_SUCCESS);
647 wake_up(&adsp_info.init_info_wait);
648
649 return;
650 }
651#else
652 event = be32_to_cpu(args->event);
653 proc_id = be32_to_cpu(args->proc_id);
654 module_id = be32_to_cpu(args->module);
655 image = be32_to_cpu(args->image);
656#endif
657
658 pr_info("adsp: rpc event=%d, proc_id=%d, module=%d, image=%d\n",
659 event, proc_id, module_id, image);
660
661 module = find_adsp_module_by_id(&adsp_info, module_id);
662 if (!module) {
663 pr_err("adsp: module %d is not supported!\n", module_id);
664 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
665 RPC_ACCEPTSTAT_GARBAGE_ARGS);
666 return;
667 }
668
669 mutex_lock(&module->lock);
670 switch (event) {
671 case RPC_ADSP_RTOS_MOD_READY:
672 pr_info("adsp: module %s: READY\n", module->name);
673 module->state = ADSP_STATE_ENABLED;
674 wake_up(&module->state_wait);
675 adsp_set_image(module->info, image);
676 break;
677 case RPC_ADSP_RTOS_MOD_DISABLE:
678 pr_info("adsp: module %s: DISABLED\n", module->name);
679 module->state = ADSP_STATE_DISABLED;
680 wake_up(&module->state_wait);
681 break;
682 case RPC_ADSP_RTOS_SERVICE_RESET:
683 pr_info("adsp: module %s: SERVICE_RESET\n", module->name);
684 module->state = ADSP_STATE_DISABLED;
685 wake_up(&module->state_wait);
686 break;
687 case RPC_ADSP_RTOS_CMD_SUCCESS:
688 pr_info("adsp: module %s: CMD_SUCCESS\n", module->name);
689 break;
690 case RPC_ADSP_RTOS_CMD_FAIL:
691 pr_info("adsp: module %s: CMD_FAIL\n", module->name);
692 break;
693#if CONFIG_MSM_AMSS_VERSION >= 6350
694 case RPC_ADSP_RTOS_DISABLE_FAIL:
695 pr_info("adsp: module %s: DISABLE_FAIL\n", module->name);
696 break;
697#endif
698 default:
699 pr_info("adsp: unknown event %d\n", event);
700 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
701 RPC_ACCEPTSTAT_GARBAGE_ARGS);
702 mutex_unlock(&module->lock);
703 return;
704 }
705 rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
706 RPC_ACCEPTSTAT_SUCCESS);
707 mutex_unlock(&module->lock);
708#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
709 modem_event_addr = (uint32_t *)req;
710 module->ops->event(module->driver_data, EVENT_MSG_ID,
711 EVENT_LEN, read_modem_event);
712#endif
713}
714
715static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req)
716{
717 switch (req->procedure) {
718 case RPC_ADSP_RTOS_MTOA_NULL_PROC:
719 rpc_send_accepted_void_reply(rpc_cb_server_client,
720 req->xid,
721 RPC_ACCEPTSTAT_SUCCESS);
722 break;
723 case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
724 handle_adsp_rtos_mtoa_app(req);
725 break;
726 default:
727 pr_err("adsp: unknowned proc %d\n", req->procedure);
728 rpc_send_accepted_void_reply(
729 rpc_cb_server_client, req->xid,
730 RPC_ACCEPTSTAT_PROC_UNAVAIL);
731 break;
732 }
733 return 0;
734}
735
736/* this should be common code with rpc_servers.c */
737static int adsp_rpc_thread(void *data)
738{
739 void *buffer;
740 struct rpc_request_hdr *req;
741 int rc;
742
743 do {
744 rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1);
745 if (rc < 0) {
746 pr_err("adsp: could not read rpc: %d\n", rc);
747 break;
748 }
749 req = (struct rpc_request_hdr *)buffer;
750
751 req->type = be32_to_cpu(req->type);
752 req->xid = be32_to_cpu(req->xid);
753 req->rpc_vers = be32_to_cpu(req->rpc_vers);
754 req->prog = be32_to_cpu(req->prog);
755 req->vers = be32_to_cpu(req->vers);
756 req->procedure = be32_to_cpu(req->procedure);
757
758 if (req->type != 0)
759 goto bad_rpc;
760 if (req->rpc_vers != 2)
761 goto bad_rpc;
762 if (req->prog != RPC_ADSP_RTOS_MTOA_PROG)
763 goto bad_rpc;
764 if (req->vers != RPC_ADSP_RTOS_MTOA_VERS)
765 goto bad_rpc;
766
767 handle_adsp_rtos_mtoa(req);
768 kfree(buffer);
769 continue;
770
771bad_rpc:
772 pr_err("adsp: bogus rpc from modem\n");
773 kfree(buffer);
774 } while (1);
775
776 do_exit(0);
777}
778
779static size_t read_event_size;
780static void *read_event_addr;
781
782static void read_event_16(void *buf, size_t len)
783{
784 uint16_t *dst = buf;
785 uint16_t *src = read_event_addr;
786 len /= 2;
787 if (len > read_event_size)
788 len = read_event_size;
789 while (len--)
790 *dst++ = *src++;
791}
792
793static void read_event_32(void *buf, size_t len)
794{
795 uint32_t *dst = buf;
796 uint32_t *src = read_event_addr;
797 len /= 2;
798 if (len > read_event_size)
799 len = read_event_size;
800 while (len--)
801 *dst++ = *src++;
802}
803
804static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(
805 struct adsp_info *info, void *dsp_addr)
806{
807 struct msm_adsp_module *module;
808 unsigned rtos_task_id;
809 unsigned msg_id;
810 unsigned msg_length;
811 void (*func)(void *, size_t);
812
813 if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
814 uint32_t *dsp_addr32 = dsp_addr;
815 uint32_t tmp = *dsp_addr32++;
816 rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
817 msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M);
818 read_event_size = tmp >> 16;
819 read_event_addr = dsp_addr32;
820 msg_length = read_event_size * sizeof(uint32_t);
821 func = read_event_32;
822 } else {
823 uint16_t *dsp_addr16 = dsp_addr;
824 uint16_t tmp = *dsp_addr16++;
825 rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
826 msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M;
827 read_event_size = *dsp_addr16++;
828 read_event_addr = dsp_addr16;
829 msg_length = read_event_size * sizeof(uint16_t);
830 func = read_event_16;
831 }
832
833 if (rtos_task_id > info->max_task_id) {
834 pr_err("adsp: bogus task id %d\n", rtos_task_id);
835 return 0;
836 }
837 module = find_adsp_module_by_id(info,
838 adsp_get_module(info, rtos_task_id));
839
840 if (!module) {
841 pr_err("adsp: no module for task id %d\n", rtos_task_id);
842 return 0;
843 }
844
845 module->num_events++;
846
847 if (!module->ops) {
848 pr_err("adsp: module %s is not open\n", module->name);
849 return 0;
850 }
851
852 module->ops->event(module->driver_data, msg_id, msg_length, func);
853 return 0;
854}
855
856static int adsp_get_event(struct adsp_info *info)
857{
858 uint32_t ctrl_word;
859 uint32_t ready;
860 void *dsp_addr;
861 uint32_t cmd_type;
862 int cnt;
863 unsigned long flags;
864 int rc = 0;
865
866 spin_lock_irqsave(&adsp_cmd_lock, flags);
867
868 /* Whenever the DSP has a message, it updates this control word
869 * and generates an interrupt. When we receive the interrupt, we
870 * read this register to find out what ADSP task the command is
871 * comming from.
872 *
873 * The ADSP should *always* be ready on the first call, but the
874 * irq handler calls us in a loop (to handle back-to-back command
875 * processing), so we give the DSP some time to return to the
876 * ready state. The DSP will not issue another IRQ for events
877 * pending between the first IRQ and the event queue being drained,
878 * unfortunately.
879 */
880
881 for (cnt = 0; cnt < 10; cnt++) {
882 ctrl_word = readl(info->read_ctrl);
883
884 if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) ==
885 ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V)
886 goto ready;
887
888 udelay(10);
889 }
890 pr_warning("adsp: not ready after 100uS\n");
891 rc = -EBUSY;
892 goto done;
893
894ready:
895 /* Here we check to see if there are pending messages. If there are
896 * none, we siply return -EAGAIN to indicate that there are no more
897 * messages pending.
898 */
899 ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M;
900 if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) &&
901 (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) {
902 rc = -EAGAIN;
903 goto done;
904 }
905
906 /* DSP says that there are messages waiting for the host to read */
907
908 /* Get the Command Type */
909 cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M;
910
911 /* Get the DSP buffer address */
912 dsp_addr = (void *)((ctrl_word &
913 ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) +
914 (uint32_t)MSM_AD5_BASE);
915
916 /* We can only handle Task-to-Host messages */
917 if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) {
918 pr_err("adsp: unknown dsp cmd_type %d\n", cmd_type);
919 rc = -EIO;
920 goto done;
921 }
922
923 adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr);
924
925 ctrl_word = readl(info->read_ctrl);
926 ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M;
927
928 /* Write ctrl word to the DSP */
929 writel(ctrl_word, info->read_ctrl);
930
931 /* Generate an interrupt to the DSP */
932 writel(1, info->send_irq);
933
934done:
935 spin_unlock_irqrestore(&adsp_cmd_lock, flags);
936 return rc;
937}
938
939static irqreturn_t adsp_irq_handler(int irq, void *data)
940{
941 struct adsp_info *info = &adsp_info;
942 int cnt = 0;
943 for (cnt = 0; cnt < 10; cnt++)
944 if (adsp_get_event(info) < 0)
945 break;
946 if (cnt > info->event_backlog_max)
947 info->event_backlog_max = cnt;
948 info->events_received += cnt;
949 if (cnt == 10)
950 pr_err("adsp: too many (%d) events for single irq!\n", cnt);
951 return IRQ_HANDLED;
952}
953
954int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate)
955{
956 if (module->clk && clk_rate)
957 return clk_set_rate(module->clk, clk_rate);
958
959 return -EINVAL;
960}
961
962int msm_adsp_enable(struct msm_adsp_module *module)
963{
964 int rc = 0;
965
966 pr_info("msm_adsp_enable() '%s'state[%d] id[%d]\n",
967 module->name, module->state, module->id);
968
969 mutex_lock(&module->lock);
970 switch (module->state) {
971 case ADSP_STATE_DISABLED:
972 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE,
973 module->id, module);
974 if (rc)
975 break;
976 module->state = ADSP_STATE_ENABLING;
977 mutex_unlock(&module->lock);
978 rc = wait_event_timeout(module->state_wait,
979 module->state != ADSP_STATE_ENABLING,
980 1 * HZ);
981 mutex_lock(&module->lock);
982 if (module->state == ADSP_STATE_ENABLED) {
983 rc = 0;
984 } else {
985 pr_err("adsp: module '%s' enable timed out\n",
986 module->name);
987 rc = -ETIMEDOUT;
988 }
989 break;
990 case ADSP_STATE_ENABLING:
991 pr_warning("adsp: module '%s' enable in progress\n",
992 module->name);
993 break;
994 case ADSP_STATE_ENABLED:
995 pr_warning("adsp: module '%s' already enabled\n",
996 module->name);
997 break;
998 case ADSP_STATE_DISABLING:
999 pr_err("adsp: module '%s' disable in progress\n",
1000 module->name);
1001 rc = -EBUSY;
1002 break;
1003 }
1004 mutex_unlock(&module->lock);
1005 return rc;
1006}
1007EXPORT_SYMBOL(msm_adsp_enable);
1008
1009static int msm_adsp_disable_locked(struct msm_adsp_module *module)
1010{
1011 int rc = 0;
1012
1013 switch (module->state) {
1014 case ADSP_STATE_DISABLED:
1015 pr_warning("adsp: module '%s' already disabled\n",
1016 module->name);
1017 break;
1018 case ADSP_STATE_ENABLING:
1019 case ADSP_STATE_ENABLED:
1020 rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE,
1021 module->id, module);
1022 module->state = ADSP_STATE_DISABLED;
1023 }
1024 return rc;
1025}
1026
1027int msm_adsp_disable(struct msm_adsp_module *module)
1028{
1029 int rc;
1030 pr_info("msm_adsp_disable() '%s'\n", module->name);
1031 mutex_lock(&module->lock);
1032 rc = msm_adsp_disable_locked(module);
1033 mutex_unlock(&module->lock);
1034 return rc;
1035}
1036EXPORT_SYMBOL(msm_adsp_disable);
1037
1038static int msm_adsp_probe(struct platform_device *pdev)
1039{
1040 unsigned count;
1041 int rc, i;
1042 int max_module_id;
1043
1044 pr_info("adsp: probe\n");
1045
1046#if CONFIG_MSM_AMSS_VERSION >= 6350
1047 adsp_info.init_info_ptr = kzalloc(
1048 (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
1049 if (!adsp_info.init_info_ptr)
1050 return -ENOMEM;
1051#endif
1052
1053 rc = adsp_init_info(&adsp_info);
1054 if (rc)
1055 return rc;
1056 adsp_info.send_irq += (uint32_t) MSM_AD5_BASE;
1057 adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE;
1058 adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE;
1059 count = adsp_info.module_count;
1060
1061#if CONFIG_MSM_AMSS_VERSION >= 6350
1062 max_module_id = count;
1063#else
1064 max_module_id = adsp_info.max_module_id + 1;
1065#endif
1066
1067 adsp_modules = kzalloc(
1068 sizeof(struct msm_adsp_module) * count +
1069 sizeof(void *) * max_module_id, GFP_KERNEL);
1070 if (!adsp_modules)
1071 return -ENOMEM;
1072
1073 adsp_info.id_to_module = (void *) (adsp_modules + count);
1074
1075 spin_lock_init(&adsp_cmd_lock);
1076
1077 rc = request_irq(INT_ADSP, adsp_irq_handler, IRQF_TRIGGER_RISING,
1078 "adsp", 0);
1079 if (rc < 0)
1080 goto fail_request_irq;
1081 disable_irq(INT_ADSP);
1082
1083 rpc_cb_server_client = msm_rpc_open();
1084 if (IS_ERR(rpc_cb_server_client)) {
1085 rpc_cb_server_client = NULL;
1086 rc = PTR_ERR(rpc_cb_server_client);
1087 pr_err("adsp: could not create rpc server (%d)\n", rc);
1088 goto fail_rpc_open;
1089 }
1090
1091 rc = msm_rpc_register_server(rpc_cb_server_client,
1092 RPC_ADSP_RTOS_MTOA_PROG,
1093 RPC_ADSP_RTOS_MTOA_VERS);
1094 if (rc) {
1095 pr_err("adsp: could not register callback server (%d)\n", rc);
1096 goto fail_rpc_register;
1097 }
1098
1099 /* start the kernel thread to process the callbacks */
1100 kthread_run(adsp_rpc_thread, NULL, "kadspd");
1101
1102 for (i = 0; i < count; i++) {
1103 struct msm_adsp_module *mod = adsp_modules + i;
1104 mutex_init(&mod->lock);
1105 init_waitqueue_head(&mod->state_wait);
1106 mod->info = &adsp_info;
1107 mod->name = adsp_info.module[i].name;
1108 mod->id = adsp_info.module[i].id;
1109 if (adsp_info.module[i].clk_name)
1110 mod->clk = clk_get(NULL, adsp_info.module[i].clk_name);
1111 else
1112 mod->clk = NULL;
1113 if (mod->clk && adsp_info.module[i].clk_rate)
1114 clk_set_rate(mod->clk, adsp_info.module[i].clk_rate);
1115 mod->verify_cmd = adsp_info.module[i].verify_cmd;
1116 mod->patch_event = adsp_info.module[i].patch_event;
1117 INIT_HLIST_HEAD(&mod->pmem_regions);
1118 mod->pdev.name = adsp_info.module[i].pdev_name;
1119 mod->pdev.id = -1;
1120#if CONFIG_MSM_AMSS_VERSION >= 6350
1121 adsp_info.id_to_module[i] = mod;
1122#else
1123 adsp_info.id_to_module[mod->id] = mod;
1124#endif
1125 platform_device_register(&mod->pdev);
1126 }
1127
1128 msm_adsp_publish_cdevs(adsp_modules, count);
1129
1130 return 0;
1131
1132fail_rpc_register:
1133 msm_rpc_close(rpc_cb_server_client);
1134 rpc_cb_server_client = NULL;
1135fail_rpc_open:
1136 enable_irq(INT_ADSP);
1137 free_irq(INT_ADSP, 0);
1138fail_request_irq:
1139 kfree(adsp_modules);
1140#if CONFIG_MSM_AMSS_VERSION >= 6350
1141 kfree(adsp_info.init_info_ptr);
1142#endif
1143 return rc;
1144}
1145
1146static struct platform_driver msm_adsp_driver = {
1147 .probe = msm_adsp_probe,
1148 .driver = {
1149 .name = MSM_ADSP_DRIVER_NAME,
1150 .owner = THIS_MODULE,
1151 },
1152};
1153
1154static int __init adsp_init(void)
1155{
1156 return platform_driver_register(&msm_adsp_driver);
1157}
1158
1159device_initcall(adsp_init);
diff --git a/drivers/staging/dream/qdsp5/adsp.h b/drivers/staging/dream/qdsp5/adsp.h
deleted file mode 100644
index 0e5c9abd3da5..000000000000
--- a/drivers/staging/dream/qdsp5/adsp.h
+++ /dev/null
@@ -1,369 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp.h
2 *
3 * Copyright (c) 2008 QUALCOMM Incorporated
4 * Copyright (C) 2008 Google, Inc.
5 * Author: Iliyan Malchev <ibm@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#ifndef _ARCH_ARM_MACH_MSM_ADSP_H
19#define _ARCH_ARM_MACH_MSM_ADSP_H
20
21#include <linux/types.h>
22#include <linux/msm_adsp.h>
23#include <mach/msm_rpcrouter.h>
24#include <mach/msm_adsp.h>
25
26int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
27 unsigned long len);
28int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
29 unsigned long *kvaddr, unsigned long len);
30int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr);
31
32int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
33 unsigned int queue_id, void *cmd_data,
34 size_t cmd_size);
35int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
36 unsigned int queue_id, void *cmd_data,
37 size_t cmd_size);
38int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
39 unsigned int queue_id, void *cmd_data,
40 size_t cmd_size);
41int adsp_video_verify_cmd(struct msm_adsp_module *module,
42 unsigned int queue_id, void *cmd_data,
43 size_t cmd_size);
44int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
45 unsigned int queue_id, void *cmd_data,
46 size_t cmd_size);
47
48
49struct adsp_event;
50
51int adsp_vfe_patch_event(struct msm_adsp_module *module,
52 struct adsp_event *event);
53
54int adsp_jpeg_patch_event(struct msm_adsp_module *module,
55 struct adsp_event *event);
56
57
58struct adsp_module_info {
59 const char *name;
60 const char *pdev_name;
61 uint32_t id;
62 const char *clk_name;
63 unsigned long clk_rate;
64 int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
65 size_t);
66 int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
67};
68
69#define ADSP_EVENT_MAX_SIZE 496
70#define EVENT_LEN 12
71#define EVENT_MSG_ID ((uint16_t)~0)
72
73struct adsp_event {
74 struct list_head list;
75 uint32_t size; /* always in bytes */
76 uint16_t msg_id;
77 uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */
78 int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */
79 union {
80 uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2];
81 uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4];
82 } data;
83};
84
85struct adsp_info {
86 uint32_t send_irq;
87 uint32_t read_ctrl;
88 uint32_t write_ctrl;
89
90 uint32_t max_msg16_size;
91 uint32_t max_msg32_size;
92
93 uint32_t max_task_id;
94 uint32_t max_module_id;
95 uint32_t max_queue_id;
96 uint32_t max_image_id;
97
98 /* for each image id, a map of queue id to offset */
99 uint32_t **queue_offset;
100
101 /* for each image id, a map of task id to module id */
102 uint32_t **task_to_module;
103
104 /* for each module id, map of module id to module */
105 struct msm_adsp_module **id_to_module;
106
107 uint32_t module_count;
108 struct adsp_module_info *module;
109
110 /* stats */
111 uint32_t events_received;
112 uint32_t event_backlog_max;
113
114#if CONFIG_MSM_AMSS_VERSION >= 6350
115 /* rpc_client for init_info */
116 struct msm_rpc_endpoint *init_info_rpc_client;
117 struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr;
118 wait_queue_head_t init_info_wait;
119 unsigned init_info_state;
120#endif
121};
122
123#define RPC_ADSP_RTOS_ATOM_PROG 0x3000000a
124#define RPC_ADSP_RTOS_MTOA_PROG 0x3000000b
125#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0
126#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0
127#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2
128#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2
129
130#if CONFIG_MSM_AMSS_VERSION >= 6350
131#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(1,0)
132#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(2,1) /* must be actual vers */
133#define MSM_ADSP_DRIVER_NAME "rs3000000a:00010000"
134#elif (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225)
135#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x71d1094b, 0)
136#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0xee3a9966, 0)
137#define MSM_ADSP_DRIVER_NAME "rs3000000a:71d1094b"
138#elif CONFIG_MSM_AMSS_VERSION == 6210
139#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x20f17fd3, 0)
140#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0x75babbd6, 0)
141#define MSM_ADSP_DRIVER_NAME "rs3000000a:20f17fd3"
142#else
143#error "Unknown AMSS version"
144#endif
145
146enum rpc_adsp_rtos_proc_type {
147 RPC_ADSP_RTOS_PROC_NONE = 0,
148 RPC_ADSP_RTOS_PROC_MODEM = 1,
149 RPC_ADSP_RTOS_PROC_APPS = 2,
150};
151
152enum {
153 RPC_ADSP_RTOS_CMD_REGISTER_APP,
154 RPC_ADSP_RTOS_CMD_ENABLE,
155 RPC_ADSP_RTOS_CMD_DISABLE,
156 RPC_ADSP_RTOS_CMD_KERNEL_COMMAND,
157 RPC_ADSP_RTOS_CMD_16_COMMAND,
158 RPC_ADSP_RTOS_CMD_32_COMMAND,
159 RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP,
160 RPC_ADSP_RTOS_CMD_REMOTE_EVENT,
161 RPC_ADSP_RTOS_CMD_SET_STATE,
162#if CONFIG_MSM_AMSS_VERSION >= 6350
163 RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
164 RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
165#endif
166};
167
168enum rpc_adsp_rtos_mod_status_type {
169 RPC_ADSP_RTOS_MOD_READY,
170 RPC_ADSP_RTOS_MOD_DISABLE,
171 RPC_ADSP_RTOS_SERVICE_RESET,
172 RPC_ADSP_RTOS_CMD_FAIL,
173 RPC_ADSP_RTOS_CMD_SUCCESS,
174#if CONFIG_MSM_AMSS_VERSION >= 6350
175 RPC_ADSP_RTOS_INIT_INFO,
176 RPC_ADSP_RTOS_DISABLE_FAIL,
177#endif
178};
179
180struct rpc_adsp_rtos_app_to_modem_args_t {
181 struct rpc_request_hdr hdr;
182 uint32_t gotit; /* if 1, the next elements are present */
183 uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
184 uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
185 uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
186};
187
188#if CONFIG_MSM_AMSS_VERSION >= 6350
189enum qdsp_image_type {
190 QDSP_IMAGE_COMBO,
191 QDSP_IMAGE_GAUDIO,
192 QDSP_IMAGE_QTV_LP,
193 QDSP_IMAGE_MAX,
194 /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
195 QDSP_IMAGE_32BIT_DUMMY = 0x10000
196};
197
198struct adsp_rtos_mp_mtoa_header_type {
199 enum rpc_adsp_rtos_mod_status_type event;
200 enum rpc_adsp_rtos_proc_type proc_id;
201};
202
203/* ADSP RTOS MP Communications - Modem to APP's Event Info*/
204struct adsp_rtos_mp_mtoa_type {
205 uint32_t module;
206 uint32_t image;
207 uint32_t apps_okts;
208};
209
210/* ADSP RTOS MP Communications - Modem to APP's Init Info */
211#define IMG_MAX 8
212#define ENTRIES_MAX 64
213
214struct queue_to_offset_type {
215 uint32_t queue;
216 uint32_t offset;
217};
218
219struct adsp_rtos_mp_mtoa_init_info_type {
220 uint32_t image_count;
221 uint32_t num_queue_offsets;
222 struct queue_to_offset_type queue_offsets_tbl[IMG_MAX][ENTRIES_MAX];
223 uint32_t num_task_module_entries;
224 uint32_t task_to_module_tbl[IMG_MAX][ENTRIES_MAX];
225
226 uint32_t module_table_size;
227 uint32_t module_entries[ENTRIES_MAX];
228 /*
229 * queue_offsets[] is to store only queue_offsets
230 */
231 uint32_t queue_offsets[IMG_MAX][ENTRIES_MAX];
232};
233
234struct adsp_rtos_mp_mtoa_s_type {
235 struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header;
236
237 uint32_t desc_field;
238 union {
239 struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet;
240 struct adsp_rtos_mp_mtoa_type mp_mtoa_packet;
241 } adsp_rtos_mp_mtoa_data;
242};
243
244struct rpc_adsp_rtos_modem_to_app_args_t {
245 struct rpc_request_hdr hdr;
246 uint32_t gotit; /* if 1, the next elements are present */
247 struct adsp_rtos_mp_mtoa_s_type mtoa_pkt;
248};
249#else
250struct rpc_adsp_rtos_modem_to_app_args_t {
251 struct rpc_request_hdr hdr;
252 uint32_t gotit; /* if 1, the next elements are present */
253 uint32_t event; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
254 uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
255 uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
256 uint32_t image; /* RPC_QDSP_IMAGE_GAUDIO */
257};
258#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
259
260#define ADSP_STATE_DISABLED 0
261#define ADSP_STATE_ENABLING 1
262#define ADSP_STATE_ENABLED 2
263#define ADSP_STATE_DISABLING 3
264#if CONFIG_MSM_AMSS_VERSION >= 6350
265#define ADSP_STATE_INIT_INFO 4
266#endif
267
268struct msm_adsp_module {
269 struct mutex lock;
270 const char *name;
271 unsigned id;
272 struct adsp_info *info;
273
274 struct msm_rpc_endpoint *rpc_client;
275 struct msm_adsp_ops *ops;
276 void *driver_data;
277
278 /* statistics */
279 unsigned num_commands;
280 unsigned num_events;
281
282 wait_queue_head_t state_wait;
283 unsigned state;
284
285 struct platform_device pdev;
286 struct clk *clk;
287 int open_count;
288
289 struct mutex pmem_regions_lock;
290 struct hlist_head pmem_regions;
291 int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
292 size_t);
293 int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
294};
295
296extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned);
297extern int adsp_init_info(struct adsp_info *info);
298
299/* Value to indicate that a queue is not defined for a particular image */
300#if CONFIG_MSM_AMSS_VERSION >= 6350
301#define QDSP_RTOS_NO_QUEUE 0xfffffffe
302#else
303#define QDSP_RTOS_NO_QUEUE 0xffffffff
304#endif
305
306/*
307 * Constants used to communicate with the ADSP RTOS
308 */
309#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M 0x80000000U
310#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V 0x80000000U
311#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V 0x00000000U
312
313#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M 0x70000000U
314#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V 0x00000000U
315#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V 0x10000000U
316#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V 0x70000000U
317
318#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M 0x0E000000U
319#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V 0x00000000U
320#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V 0x02000000U
321
322#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M 0x01000000U
323#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V 0x00000000U
324#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V 0x01000000U
325
326#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU
327#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M 0x00FFFFFFU
328
329/* Combination of MUTEX and CMD bits to check if the DSP is busy */
330#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M 0xF0000000U
331#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V 0x70000000U
332
333/* RTOS to Host processor command mask values */
334#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M 0x80000000U
335#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V 0x00000000U
336#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V 0x80000000U
337
338#define ADSP_RTOS_READ_CTRL_WORD_CMD_M 0x60000000U
339#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V 0x00000000U
340#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V 0x20000000U
341#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V 0x60000000U
342
343/* Combination of FLAG and COMMAND bits to check if MSG ready */
344#define ADSP_RTOS_READ_CTRL_WORD_READY_M 0xE0000000U
345#define ADSP_RTOS_READ_CTRL_WORD_READY_V 0xA0000000U
346#define ADSP_RTOS_READ_CTRL_WORD_CONT_V 0xC0000000U
347#define ADSP_RTOS_READ_CTRL_WORD_DONE_V 0xE0000000U
348
349#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M 0x18000000U
350#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V 0x00000000U
351
352#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M 0x04000000U
353#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V 0x00000000U
354#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V 0x04000000U
355
356#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M 0x03000000U
357#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V 0x00000000U
358#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V 0x01000000U
359#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U
360
361#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M 0x00FFFFFFU
362
363#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M 0x000000FFU
364#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M 0x0000FF00U
365
366/* Base address of DSP and DSP hardware registers */
367#define QDSP_RAMC_OFFSET 0x400000
368
369#endif /* _ARCH_ARM_MACH_MSM_ADSP_H */
diff --git a/drivers/staging/dream/qdsp5/adsp_6210.c b/drivers/staging/dream/qdsp5/adsp_6210.c
deleted file mode 100644
index 3cf4e99ed862..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_6210.c
+++ /dev/null
@@ -1,283 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_6210.h
2 *
3 * Copyright (c) 2008 QUALCOMM Incorporated.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include "adsp.h"
17
18/* Firmware modules */
19typedef enum {
20 QDSP_MODULE_KERNEL,
21 QDSP_MODULE_AFETASK,
22 QDSP_MODULE_AUDPLAY0TASK,
23 QDSP_MODULE_AUDPLAY1TASK,
24 QDSP_MODULE_AUDPPTASK,
25 QDSP_MODULE_VIDEOTASK,
26 QDSP_MODULE_VIDEO_AAC_VOC,
27 QDSP_MODULE_PCM_DEC,
28 QDSP_MODULE_AUDIO_DEC_MP3,
29 QDSP_MODULE_AUDIO_DEC_AAC,
30 QDSP_MODULE_AUDIO_DEC_WMA,
31 QDSP_MODULE_HOSTPCM,
32 QDSP_MODULE_DTMF,
33 QDSP_MODULE_AUDRECTASK,
34 QDSP_MODULE_AUDPREPROCTASK,
35 QDSP_MODULE_SBC_ENC,
36 QDSP_MODULE_VOC,
37 QDSP_MODULE_VOC_PCM,
38 QDSP_MODULE_VOCENCTASK,
39 QDSP_MODULE_VOCDECTASK,
40 QDSP_MODULE_VOICEPROCTASK,
41 QDSP_MODULE_VIDEOENCTASK,
42 QDSP_MODULE_VFETASK,
43 QDSP_MODULE_WAV_ENC,
44 QDSP_MODULE_AACLC_ENC,
45 QDSP_MODULE_VIDEO_AMR,
46 QDSP_MODULE_VOC_AMR,
47 QDSP_MODULE_VOC_EVRC,
48 QDSP_MODULE_VOC_13K,
49 QDSP_MODULE_VOC_FGV,
50 QDSP_MODULE_DIAGTASK,
51 QDSP_MODULE_JPEGTASK,
52 QDSP_MODULE_LPMTASK,
53 QDSP_MODULE_QCAMTASK,
54 QDSP_MODULE_MODMATHTASK,
55 QDSP_MODULE_AUDPLAY2TASK,
56 QDSP_MODULE_AUDPLAY3TASK,
57 QDSP_MODULE_AUDPLAY4TASK,
58 QDSP_MODULE_GRAPHICSTASK,
59 QDSP_MODULE_MIDI,
60 QDSP_MODULE_GAUDIO,
61 QDSP_MODULE_VDEC_LP_MODE,
62 QDSP_MODULE_MAX,
63} qdsp_module_type;
64
65#define QDSP_RTOS_MAX_TASK_ID 19U
66
67/* Table of modules indexed by task ID for the GAUDIO image */
68static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
69 QDSP_MODULE_KERNEL,
70 QDSP_MODULE_AFETASK,
71 QDSP_MODULE_MAX,
72 QDSP_MODULE_MAX,
73 QDSP_MODULE_MAX,
74 QDSP_MODULE_MAX,
75 QDSP_MODULE_MAX,
76 QDSP_MODULE_MAX,
77 QDSP_MODULE_MAX,
78 QDSP_MODULE_AUDPPTASK,
79 QDSP_MODULE_AUDPLAY0TASK,
80 QDSP_MODULE_AUDPLAY1TASK,
81 QDSP_MODULE_AUDPLAY2TASK,
82 QDSP_MODULE_AUDPLAY3TASK,
83 QDSP_MODULE_AUDPLAY4TASK,
84 QDSP_MODULE_MAX,
85 QDSP_MODULE_AUDRECTASK,
86 QDSP_MODULE_AUDPREPROCTASK,
87 QDSP_MODULE_MAX,
88 QDSP_MODULE_GRAPHICSTASK,
89 QDSP_MODULE_MAX
90};
91
92/* Queue offset table indexed by queue ID for the GAUDIO image */
93static uint32_t qdsp_gaudio_queue_offset_table[] = {
94 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
95 0x3be, /* QDSP_mpuAfeQueue */
96 0x3ee, /* QDSP_mpuGraphicsCmdQueue */
97 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
98 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
99 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
100 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
101 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
102 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
103 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
104 0x3c2, /* QDSP_uPAudPPCmd1Queue */
105 0x3c6, /* QDSP_uPAudPPCmd2Queue */
106 0x3ca, /* QDSP_uPAudPPCmd3Queue */
107 0x3da, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
108 0x3de, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
109 0x3e2, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
110 0x3e6, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
111 0x3ea, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
112 0x3ce, /* QDSP_uPAudPreProcCmdQueue */
113 0x3d6, /* QDSP_uPAudRecBitStreamQueue */
114 0x3d2, /* QDSP_uPAudRecCmdQueue */
115 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
116 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
117 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
118 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
119 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
120 QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
121};
122
123/* Table of modules indexed by task ID for the COMBO image */
124static qdsp_module_type qdsp_combo_task_to_module_table[] = {
125 QDSP_MODULE_KERNEL,
126 QDSP_MODULE_AFETASK,
127 QDSP_MODULE_VOCDECTASK,
128 QDSP_MODULE_VOCENCTASK,
129 QDSP_MODULE_VIDEOTASK,
130 QDSP_MODULE_VIDEOENCTASK,
131 QDSP_MODULE_VOICEPROCTASK,
132 QDSP_MODULE_VFETASK,
133 QDSP_MODULE_JPEGTASK,
134 QDSP_MODULE_AUDPPTASK,
135 QDSP_MODULE_AUDPLAY0TASK,
136 QDSP_MODULE_AUDPLAY1TASK,
137 QDSP_MODULE_MAX,
138 QDSP_MODULE_MAX,
139 QDSP_MODULE_MAX,
140 QDSP_MODULE_LPMTASK,
141 QDSP_MODULE_AUDRECTASK,
142 QDSP_MODULE_AUDPREPROCTASK,
143 QDSP_MODULE_MODMATHTASK,
144 QDSP_MODULE_MAX,
145 QDSP_MODULE_MAX
146};
147
148/* Queue offset table indexed by queue ID for the COMBO image */
149static uint32_t qdsp_combo_queue_offset_table[] = {
150 0x585, /* QDSP_lpmCommandQueue */
151 0x52d, /* QDSP_mpuAfeQueue */
152 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
153 0x541, /* QDSP_mpuModmathCmdQueue */
154 0x555, /* QDSP_mpuVDecCmdQueue */
155 0x559, /* QDSP_mpuVDecPktQueue */
156 0x551, /* QDSP_mpuVEncCmdQueue */
157 0x535, /* QDSP_rxMpuDecCmdQueue */
158 0x539, /* QDSP_rxMpuDecPktQueue */
159 0x53d, /* QDSP_txMpuEncQueue */
160 0x55d, /* QDSP_uPAudPPCmd1Queue */
161 0x561, /* QDSP_uPAudPPCmd2Queue */
162 0x565, /* QDSP_uPAudPPCmd3Queue */
163 0x575, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
164 0x579, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
165 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
166 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
167 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
168 0x569, /* QDSP_uPAudPreProcCmdQueue */
169 0x571, /* QDSP_uPAudRecBitStreamQueue */
170 0x56d, /* QDSP_uPAudRecCmdQueue */
171 0x581, /* QDSP_uPJpegActionCmdQueue */
172 0x57d, /* QDSP_uPJpegCfgCmdQueue */
173 0x531, /* QDSP_uPVocProcQueue */
174 0x545, /* QDSP_vfeCommandQueue */
175 0x54d, /* QDSP_vfeCommandScaleQueue */
176 0x549 /* QDSP_vfeCommandTableQueue */
177};
178
179/* Table of modules indexed by task ID for the QTV_LP image */
180static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
181 QDSP_MODULE_KERNEL,
182 QDSP_MODULE_AFETASK,
183 QDSP_MODULE_MAX,
184 QDSP_MODULE_MAX,
185 QDSP_MODULE_VIDEOTASK,
186 QDSP_MODULE_MAX,
187 QDSP_MODULE_MAX,
188 QDSP_MODULE_MAX,
189 QDSP_MODULE_MAX,
190 QDSP_MODULE_AUDPPTASK,
191 QDSP_MODULE_AUDPLAY0TASK,
192 QDSP_MODULE_MAX,
193 QDSP_MODULE_MAX,
194 QDSP_MODULE_MAX,
195 QDSP_MODULE_MAX,
196 QDSP_MODULE_MAX,
197 QDSP_MODULE_AUDRECTASK,
198 QDSP_MODULE_AUDPREPROCTASK,
199 QDSP_MODULE_MAX,
200 QDSP_MODULE_MAX,
201 QDSP_MODULE_MAX
202};
203
204/* Queue offset table indexed by queue ID for the QTV_LP image */
205static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
206 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
207 0x40c, /* QDSP_mpuAfeQueue */
208 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
209 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
210 0x410, /* QDSP_mpuVDecCmdQueue */
211 0x414, /* QDSP_mpuVDecPktQueue */
212 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
213 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
214 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
215 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
216 0x41c, /* QDSP_uPAudPPCmd1Queue */
217 0x420, /* QDSP_uPAudPPCmd2Queue */
218 0x424, /* QDSP_uPAudPPCmd3Queue */
219 0x430, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
220 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
221 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
222 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
223 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
224 0x418, /* QDSP_uPAudPreProcCmdQueue */
225 0x42c, /* QDSP_uPAudRecBitStreamQueue */
226 0x428, /* QDSP_uPAudRecCmdQueue */
227 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
228 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
229 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
230 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
231 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
232 QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
233};
234
235/* Tables to convert tasks to modules */
236static uint32_t *qdsp_task_to_module[] = {
237 qdsp_combo_task_to_module_table,
238 qdsp_gaudio_task_to_module_table,
239 qdsp_qtv_lp_task_to_module_table,
240};
241
242/* Tables to retrieve queue offsets */
243static uint32_t *qdsp_queue_offset_table[] = {
244 qdsp_combo_queue_offset_table,
245 qdsp_gaudio_queue_offset_table,
246 qdsp_qtv_lp_queue_offset_table,
247};
248
249#define QDSP_MODULE(n) \
250 { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
251
252static struct adsp_module_info module_info[] = {
253 QDSP_MODULE(AUDPPTASK),
254 QDSP_MODULE(AUDRECTASK),
255 QDSP_MODULE(AUDPREPROCTASK),
256 QDSP_MODULE(VFETASK),
257 QDSP_MODULE(QCAMTASK),
258 QDSP_MODULE(LPMTASK),
259 QDSP_MODULE(JPEGTASK),
260 QDSP_MODULE(VIDEOTASK),
261 QDSP_MODULE(VDEC_LP_MODE),
262};
263
264int adsp_init_info(struct adsp_info *info)
265{
266 info->send_irq = 0x00c00200;
267 info->read_ctrl = 0x00400038;
268 info->write_ctrl = 0x00400034;
269
270 info->max_msg16_size = 193;
271 info->max_msg32_size = 8;
272
273 info->max_task_id = 16;
274 info->max_module_id = QDSP_MODULE_MAX - 1;
275 info->max_queue_id = QDSP_QUEUE_MAX;
276 info->max_image_id = 2;
277 info->queue_offset = qdsp_queue_offset_table;
278 info->task_to_module = qdsp_task_to_module;
279
280 info->module_count = ARRAY_SIZE(module_info);
281 info->module = module_info;
282 return 0;
283}
diff --git a/drivers/staging/dream/qdsp5/adsp_6220.c b/drivers/staging/dream/qdsp5/adsp_6220.c
deleted file mode 100644
index 02225cd7ec8f..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_6220.c
+++ /dev/null
@@ -1,284 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_6220.h
2 *
3 * Copyright (c) 2008 QUALCOMM Incorporated.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include "adsp.h"
17
18/* Firmware modules */
19typedef enum {
20 QDSP_MODULE_KERNEL,
21 QDSP_MODULE_AFETASK,
22 QDSP_MODULE_AUDPLAY0TASK,
23 QDSP_MODULE_AUDPLAY1TASK,
24 QDSP_MODULE_AUDPPTASK,
25 QDSP_MODULE_VIDEOTASK,
26 QDSP_MODULE_VIDEO_AAC_VOC,
27 QDSP_MODULE_PCM_DEC,
28 QDSP_MODULE_AUDIO_DEC_MP3,
29 QDSP_MODULE_AUDIO_DEC_AAC,
30 QDSP_MODULE_AUDIO_DEC_WMA,
31 QDSP_MODULE_HOSTPCM,
32 QDSP_MODULE_DTMF,
33 QDSP_MODULE_AUDRECTASK,
34 QDSP_MODULE_AUDPREPROCTASK,
35 QDSP_MODULE_SBC_ENC,
36 QDSP_MODULE_VOC,
37 QDSP_MODULE_VOC_PCM,
38 QDSP_MODULE_VOCENCTASK,
39 QDSP_MODULE_VOCDECTASK,
40 QDSP_MODULE_VOICEPROCTASK,
41 QDSP_MODULE_VIDEOENCTASK,
42 QDSP_MODULE_VFETASK,
43 QDSP_MODULE_WAV_ENC,
44 QDSP_MODULE_AACLC_ENC,
45 QDSP_MODULE_VIDEO_AMR,
46 QDSP_MODULE_VOC_AMR,
47 QDSP_MODULE_VOC_EVRC,
48 QDSP_MODULE_VOC_13K,
49 QDSP_MODULE_VOC_FGV,
50 QDSP_MODULE_DIAGTASK,
51 QDSP_MODULE_JPEGTASK,
52 QDSP_MODULE_LPMTASK,
53 QDSP_MODULE_QCAMTASK,
54 QDSP_MODULE_MODMATHTASK,
55 QDSP_MODULE_AUDPLAY2TASK,
56 QDSP_MODULE_AUDPLAY3TASK,
57 QDSP_MODULE_AUDPLAY4TASK,
58 QDSP_MODULE_GRAPHICSTASK,
59 QDSP_MODULE_MIDI,
60 QDSP_MODULE_GAUDIO,
61 QDSP_MODULE_VDEC_LP_MODE,
62 QDSP_MODULE_MAX,
63} qdsp_module_type;
64
65#define QDSP_RTOS_MAX_TASK_ID 19U
66
67/* Table of modules indexed by task ID for the GAUDIO image */
68static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
69 QDSP_MODULE_KERNEL,
70 QDSP_MODULE_AFETASK,
71 QDSP_MODULE_MAX,
72 QDSP_MODULE_MAX,
73 QDSP_MODULE_MAX,
74 QDSP_MODULE_MAX,
75 QDSP_MODULE_MAX,
76 QDSP_MODULE_MAX,
77 QDSP_MODULE_MAX,
78 QDSP_MODULE_AUDPPTASK,
79 QDSP_MODULE_AUDPLAY0TASK,
80 QDSP_MODULE_AUDPLAY1TASK,
81 QDSP_MODULE_AUDPLAY2TASK,
82 QDSP_MODULE_AUDPLAY3TASK,
83 QDSP_MODULE_AUDPLAY4TASK,
84 QDSP_MODULE_MAX,
85 QDSP_MODULE_AUDRECTASK,
86 QDSP_MODULE_AUDPREPROCTASK,
87 QDSP_MODULE_MAX,
88 QDSP_MODULE_GRAPHICSTASK,
89 QDSP_MODULE_MAX
90};
91
92/* Queue offset table indexed by queue ID for the GAUDIO image */
93static uint32_t qdsp_gaudio_queue_offset_table[] = {
94 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
95 0x3f0, /* QDSP_mpuAfeQueue */
96 0x420, /* QDSP_mpuGraphicsCmdQueue */
97 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
98 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
99 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
100 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
101 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
102 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
103 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
104 0x3f4, /* QDSP_uPAudPPCmd1Queue */
105 0x3f8, /* QDSP_uPAudPPCmd2Queue */
106 0x3fc, /* QDSP_uPAudPPCmd3Queue */
107 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
108 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
109 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
110 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
111 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
112 0x400, /* QDSP_uPAudPreProcCmdQueue */
113 0x408, /* QDSP_uPAudRecBitStreamQueue */
114 0x404, /* QDSP_uPAudRecCmdQueue */
115 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
116 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
117 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
118 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
119 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
120 QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
121};
122
123/* Table of modules indexed by task ID for the COMBO image */
124static qdsp_module_type qdsp_combo_task_to_module_table[] = {
125 QDSP_MODULE_KERNEL,
126 QDSP_MODULE_AFETASK,
127 QDSP_MODULE_VOCDECTASK,
128 QDSP_MODULE_VOCENCTASK,
129 QDSP_MODULE_VIDEOTASK,
130 QDSP_MODULE_VIDEOENCTASK,
131 QDSP_MODULE_VOICEPROCTASK,
132 QDSP_MODULE_VFETASK,
133 QDSP_MODULE_JPEGTASK,
134 QDSP_MODULE_AUDPPTASK,
135 QDSP_MODULE_AUDPLAY0TASK,
136 QDSP_MODULE_AUDPLAY1TASK,
137 QDSP_MODULE_MAX,
138 QDSP_MODULE_MAX,
139 QDSP_MODULE_MAX,
140 QDSP_MODULE_LPMTASK,
141 QDSP_MODULE_AUDRECTASK,
142 QDSP_MODULE_AUDPREPROCTASK,
143 QDSP_MODULE_MODMATHTASK,
144 QDSP_MODULE_MAX,
145 QDSP_MODULE_MAX
146};
147
148/* Queue offset table indexed by queue ID for the COMBO image */
149static uint32_t qdsp_combo_queue_offset_table[] = {
150 0x6f2, /* QDSP_lpmCommandQueue */
151 0x69e, /* QDSP_mpuAfeQueue */
152 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
153 0x6b2, /* QDSP_mpuModmathCmdQueue */
154 0x6c6, /* QDSP_mpuVDecCmdQueue */
155 0x6ca, /* QDSP_mpuVDecPktQueue */
156 0x6c2, /* QDSP_mpuVEncCmdQueue */
157 0x6a6, /* QDSP_rxMpuDecCmdQueue */
158 0x6aa, /* QDSP_rxMpuDecPktQueue */
159 0x6ae, /* QDSP_txMpuEncQueue */
160 0x6ce, /* QDSP_uPAudPPCmd1Queue */
161 0x6d2, /* QDSP_uPAudPPCmd2Queue */
162 0x6d6, /* QDSP_uPAudPPCmd3Queue */
163 0x6e6, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
164 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
165 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
166 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
167 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
168 0x6da, /* QDSP_uPAudPreProcCmdQueue */
169 0x6e2, /* QDSP_uPAudRecBitStreamQueue */
170 0x6de, /* QDSP_uPAudRecCmdQueue */
171 0x6ee, /* QDSP_uPJpegActionCmdQueue */
172 0x6ea, /* QDSP_uPJpegCfgCmdQueue */
173 0x6a2, /* QDSP_uPVocProcQueue */
174 0x6b6, /* QDSP_vfeCommandQueue */
175 0x6be, /* QDSP_vfeCommandScaleQueue */
176 0x6ba /* QDSP_vfeCommandTableQueue */
177};
178
179/* Table of modules indexed by task ID for the QTV_LP image */
180static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
181 QDSP_MODULE_KERNEL,
182 QDSP_MODULE_AFETASK,
183 QDSP_MODULE_MAX,
184 QDSP_MODULE_MAX,
185 QDSP_MODULE_VIDEOTASK,
186 QDSP_MODULE_MAX,
187 QDSP_MODULE_MAX,
188 QDSP_MODULE_MAX,
189 QDSP_MODULE_MAX,
190 QDSP_MODULE_AUDPPTASK,
191 QDSP_MODULE_AUDPLAY0TASK,
192 QDSP_MODULE_MAX,
193 QDSP_MODULE_MAX,
194 QDSP_MODULE_MAX,
195 QDSP_MODULE_MAX,
196 QDSP_MODULE_MAX,
197 QDSP_MODULE_AUDRECTASK,
198 QDSP_MODULE_AUDPREPROCTASK,
199 QDSP_MODULE_MAX,
200 QDSP_MODULE_MAX,
201 QDSP_MODULE_MAX
202};
203
204/* Queue offset table indexed by queue ID for the QTV_LP image */
205static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
206 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
207 0x430, /* QDSP_mpuAfeQueue */
208 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
209 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
210 0x434, /* QDSP_mpuVDecCmdQueue */
211 0x438, /* QDSP_mpuVDecPktQueue */
212 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
213 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
214 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
215 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
216 0x440, /* QDSP_uPAudPPCmd1Queue */
217 0x444, /* QDSP_uPAudPPCmd2Queue */
218 0x448, /* QDSP_uPAudPPCmd3Queue */
219 0x454, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
220 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
221 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
222 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
223 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
224 0x43c, /* QDSP_uPAudPreProcCmdQueue */
225 0x450, /* QDSP_uPAudRecBitStreamQueue */
226 0x44c, /* QDSP_uPAudRecCmdQueue */
227 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
228 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
229 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
230 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
231 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
232 QDSP_RTOS_NO_QUEUE /* QDSP_vfeCommandTableQueue */
233};
234
235/* Tables to convert tasks to modules */
236static qdsp_module_type *qdsp_task_to_module[] = {
237 qdsp_combo_task_to_module_table,
238 qdsp_gaudio_task_to_module_table,
239 qdsp_qtv_lp_task_to_module_table,
240};
241
242/* Tables to retrieve queue offsets */
243static uint32_t *qdsp_queue_offset_table[] = {
244 qdsp_combo_queue_offset_table,
245 qdsp_gaudio_queue_offset_table,
246 qdsp_qtv_lp_queue_offset_table,
247};
248
249#define QDSP_MODULE(n) \
250 { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
251
252static struct adsp_module_info module_info[] = {
253 QDSP_MODULE(AUDPLAY0TASK),
254 QDSP_MODULE(AUDPPTASK),
255 QDSP_MODULE(AUDPREPROCTASK),
256 QDSP_MODULE(AUDRECTASK),
257 QDSP_MODULE(VFETASK),
258 QDSP_MODULE(QCAMTASK),
259 QDSP_MODULE(LPMTASK),
260 QDSP_MODULE(JPEGTASK),
261 QDSP_MODULE(VIDEOTASK),
262 QDSP_MODULE(VDEC_LP_MODE),
263};
264
265int adsp_init_info(struct adsp_info *info)
266{
267 info->send_irq = 0x00c00200;
268 info->read_ctrl = 0x00400038;
269 info->write_ctrl = 0x00400034;
270
271 info->max_msg16_size = 193;
272 info->max_msg32_size = 8;
273
274 info->max_task_id = 16;
275 info->max_module_id = QDSP_MODULE_MAX - 1;
276 info->max_queue_id = QDSP_QUEUE_MAX;
277 info->max_image_id = 2;
278 info->queue_offset = qdsp_queue_offset_table;
279 info->task_to_module = qdsp_task_to_module;
280
281 info->module_count = ARRAY_SIZE(module_info);
282 info->module = module_info;
283 return 0;
284}
diff --git a/drivers/staging/dream/qdsp5/adsp_6225.c b/drivers/staging/dream/qdsp5/adsp_6225.c
deleted file mode 100644
index 5078afbb1a8c..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_6225.c
+++ /dev/null
@@ -1,328 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_6225.h
2 *
3 * Copyright (c) 2008 QUALCOMM Incorporated.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include "adsp.h"
17
18/* Firmware modules */
19typedef enum {
20 QDSP_MODULE_KERNEL,
21 QDSP_MODULE_AFETASK,
22 QDSP_MODULE_AUDPLAY0TASK,
23 QDSP_MODULE_AUDPLAY1TASK,
24 QDSP_MODULE_AUDPPTASK,
25 QDSP_MODULE_VIDEOTASK,
26 QDSP_MODULE_VIDEO_AAC_VOC,
27 QDSP_MODULE_PCM_DEC,
28 QDSP_MODULE_AUDIO_DEC_MP3,
29 QDSP_MODULE_AUDIO_DEC_AAC,
30 QDSP_MODULE_AUDIO_DEC_WMA,
31 QDSP_MODULE_HOSTPCM,
32 QDSP_MODULE_DTMF,
33 QDSP_MODULE_AUDRECTASK,
34 QDSP_MODULE_AUDPREPROCTASK,
35 QDSP_MODULE_SBC_ENC,
36 QDSP_MODULE_VOC_UMTS,
37 QDSP_MODULE_VOC_CDMA,
38 QDSP_MODULE_VOC_PCM,
39 QDSP_MODULE_VOCENCTASK,
40 QDSP_MODULE_VOCDECTASK,
41 QDSP_MODULE_VOICEPROCTASK,
42 QDSP_MODULE_VIDEOENCTASK,
43 QDSP_MODULE_VFETASK,
44 QDSP_MODULE_WAV_ENC,
45 QDSP_MODULE_AACLC_ENC,
46 QDSP_MODULE_VIDEO_AMR,
47 QDSP_MODULE_VOC_AMR,
48 QDSP_MODULE_VOC_EVRC,
49 QDSP_MODULE_VOC_13K,
50 QDSP_MODULE_VOC_FGV,
51 QDSP_MODULE_DIAGTASK,
52 QDSP_MODULE_JPEGTASK,
53 QDSP_MODULE_LPMTASK,
54 QDSP_MODULE_QCAMTASK,
55 QDSP_MODULE_MODMATHTASK,
56 QDSP_MODULE_AUDPLAY2TASK,
57 QDSP_MODULE_AUDPLAY3TASK,
58 QDSP_MODULE_AUDPLAY4TASK,
59 QDSP_MODULE_GRAPHICSTASK,
60 QDSP_MODULE_MIDI,
61 QDSP_MODULE_GAUDIO,
62 QDSP_MODULE_VDEC_LP_MODE,
63 QDSP_MODULE_MAX,
64} qdsp_module_type;
65
66#define QDSP_RTOS_MAX_TASK_ID 30U
67
68/* Table of modules indexed by task ID for the GAUDIO image */
69static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
70 QDSP_MODULE_KERNEL,
71 QDSP_MODULE_AFETASK,
72 QDSP_MODULE_MAX,
73 QDSP_MODULE_MAX,
74 QDSP_MODULE_MAX,
75 QDSP_MODULE_MAX,
76 QDSP_MODULE_MAX,
77 QDSP_MODULE_MAX,
78 QDSP_MODULE_MAX,
79 QDSP_MODULE_AUDPPTASK,
80 QDSP_MODULE_AUDPLAY0TASK,
81 QDSP_MODULE_AUDPLAY1TASK,
82 QDSP_MODULE_AUDPLAY2TASK,
83 QDSP_MODULE_AUDPLAY3TASK,
84 QDSP_MODULE_AUDPLAY4TASK,
85 QDSP_MODULE_MAX,
86 QDSP_MODULE_AUDRECTASK,
87 QDSP_MODULE_AUDPREPROCTASK,
88 QDSP_MODULE_MAX,
89 QDSP_MODULE_GRAPHICSTASK,
90 QDSP_MODULE_MAX,
91 QDSP_MODULE_MAX,
92 QDSP_MODULE_MAX,
93 QDSP_MODULE_MAX,
94 QDSP_MODULE_MAX,
95 QDSP_MODULE_MAX,
96 QDSP_MODULE_MAX,
97 QDSP_MODULE_MAX,
98 QDSP_MODULE_MAX,
99 QDSP_MODULE_MAX,
100 QDSP_MODULE_MAX,
101 QDSP_MODULE_MAX,
102};
103
104/* Queue offset table indexed by queue ID for the GAUDIO image */
105static uint32_t qdsp_gaudio_queue_offset_table[] = {
106 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
107 0x3f0, /* QDSP_mpuAfeQueue */
108 0x420, /* QDSP_mpuGraphicsCmdQueue */
109 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
110 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecCmdQueue */
111 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVDecPktQueue */
112 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
113 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
114 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
115 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
116 0x3f4, /* QDSP_uPAudPPCmd1Queue */
117 0x3f8, /* QDSP_uPAudPPCmd2Queue */
118 0x3fc, /* QDSP_uPAudPPCmd3Queue */
119 0x40c, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
120 0x410, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
121 0x414, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
122 0x418, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
123 0x41c, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
124 0x400, /* QDSP_uPAudPreProcCmdQueue */
125 0x408, /* QDSP_uPAudRecBitStreamQueue */
126 0x404, /* QDSP_uPAudRecCmdQueue */
127 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
128 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
129 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
130 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
131 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
132 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */
133 QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */
134};
135
136/* Table of modules indexed by task ID for the COMBO image */
137static qdsp_module_type qdsp_combo_task_to_module_table[] = {
138 QDSP_MODULE_KERNEL,
139 QDSP_MODULE_AFETASK,
140 QDSP_MODULE_VOCDECTASK,
141 QDSP_MODULE_VOCENCTASK,
142 QDSP_MODULE_VIDEOTASK,
143 QDSP_MODULE_VIDEOENCTASK,
144 QDSP_MODULE_VOICEPROCTASK,
145 QDSP_MODULE_VFETASK,
146 QDSP_MODULE_JPEGTASK,
147 QDSP_MODULE_AUDPPTASK,
148 QDSP_MODULE_AUDPLAY0TASK,
149 QDSP_MODULE_AUDPLAY1TASK,
150 QDSP_MODULE_MAX,
151 QDSP_MODULE_MAX,
152 QDSP_MODULE_MAX,
153 QDSP_MODULE_LPMTASK,
154 QDSP_MODULE_AUDRECTASK,
155 QDSP_MODULE_AUDPREPROCTASK,
156 QDSP_MODULE_MODMATHTASK,
157 QDSP_MODULE_MAX,
158 QDSP_MODULE_MAX,
159 QDSP_MODULE_MAX,
160 QDSP_MODULE_MAX,
161 QDSP_MODULE_MAX,
162 QDSP_MODULE_MAX,
163 QDSP_MODULE_MAX,
164 QDSP_MODULE_MAX,
165 QDSP_MODULE_MAX,
166 QDSP_MODULE_MAX,
167 QDSP_MODULE_MAX,
168 QDSP_MODULE_DIAGTASK,
169 QDSP_MODULE_MAX,
170};
171
172/* Queue offset table indexed by queue ID for the COMBO image */
173static uint32_t qdsp_combo_queue_offset_table[] = {
174 0x714, /* QDSP_lpmCommandQueue */
175 0x6bc, /* QDSP_mpuAfeQueue */
176 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
177 0x6d0, /* QDSP_mpuModmathCmdQueue */
178 0x6e8, /* QDSP_mpuVDecCmdQueue */
179 0x6ec, /* QDSP_mpuVDecPktQueue */
180 0x6e4, /* QDSP_mpuVEncCmdQueue */
181 0x6c4, /* QDSP_rxMpuDecCmdQueue */
182 0x6c8, /* QDSP_rxMpuDecPktQueue */
183 0x6cc, /* QDSP_txMpuEncQueue */
184 0x6f0, /* QDSP_uPAudPPCmd1Queue */
185 0x6f4, /* QDSP_uPAudPPCmd2Queue */
186 0x6f8, /* QDSP_uPAudPPCmd3Queue */
187 0x708, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
188 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
189 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
190 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
191 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
192 0x6fc, /* QDSP_uPAudPreProcCmdQueue */
193 0x704, /* QDSP_uPAudRecBitStreamQueue */
194 0x700, /* QDSP_uPAudRecCmdQueue */
195 0x710, /* QDSP_uPJpegActionCmdQueue */
196 0x70c, /* QDSP_uPJpegCfgCmdQueue */
197 0x6c0, /* QDSP_uPVocProcQueue */
198 0x6d8, /* QDSP_vfeCommandQueue */
199 0x6e0, /* QDSP_vfeCommandScaleQueue */
200 0x6dc, /* QDSP_vfeCommandTableQueue */
201 0x6d4, /* QDSP_uPDiagQueue */
202};
203
204/* Table of modules indexed by task ID for the QTV_LP image */
205static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
206 QDSP_MODULE_KERNEL,
207 QDSP_MODULE_AFETASK,
208 QDSP_MODULE_MAX,
209 QDSP_MODULE_MAX,
210 QDSP_MODULE_VIDEOTASK,
211 QDSP_MODULE_MAX,
212 QDSP_MODULE_MAX,
213 QDSP_MODULE_MAX,
214 QDSP_MODULE_MAX,
215 QDSP_MODULE_AUDPPTASK,
216 QDSP_MODULE_AUDPLAY0TASK,
217 QDSP_MODULE_MAX,
218 QDSP_MODULE_MAX,
219 QDSP_MODULE_MAX,
220 QDSP_MODULE_MAX,
221 QDSP_MODULE_MAX,
222 QDSP_MODULE_AUDRECTASK,
223 QDSP_MODULE_AUDPREPROCTASK,
224 QDSP_MODULE_MAX,
225 QDSP_MODULE_MAX,
226 QDSP_MODULE_MAX,
227 QDSP_MODULE_MAX,
228 QDSP_MODULE_MAX,
229 QDSP_MODULE_MAX,
230 QDSP_MODULE_MAX,
231 QDSP_MODULE_MAX,
232 QDSP_MODULE_MAX,
233 QDSP_MODULE_MAX,
234 QDSP_MODULE_MAX,
235 QDSP_MODULE_MAX,
236 QDSP_MODULE_MAX,
237 QDSP_MODULE_MAX,
238};
239
240/* Queue offset table indexed by queue ID for the QTV_LP image */
241static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
242 QDSP_RTOS_NO_QUEUE, /* QDSP_lpmCommandQueue */
243 0x3fe, /* QDSP_mpuAfeQueue */
244 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuGraphicsCmdQueue */
245 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuModmathCmdQueue */
246 0x402, /* QDSP_mpuVDecCmdQueue */
247 0x406, /* QDSP_mpuVDecPktQueue */
248 QDSP_RTOS_NO_QUEUE, /* QDSP_mpuVEncCmdQueue */
249 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecCmdQueue */
250 QDSP_RTOS_NO_QUEUE, /* QDSP_rxMpuDecPktQueue */
251 QDSP_RTOS_NO_QUEUE, /* QDSP_txMpuEncQueue */
252 0x40e, /* QDSP_uPAudPPCmd1Queue */
253 0x412, /* QDSP_uPAudPPCmd2Queue */
254 0x416, /* QDSP_uPAudPPCmd3Queue */
255 0x422, /* QDSP_uPAudPlay0BitStreamCtrlQueue */
256 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay1BitStreamCtrlQueue */
257 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay2BitStreamCtrlQueue */
258 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay3BitStreamCtrlQueue */
259 QDSP_RTOS_NO_QUEUE, /* QDSP_uPAudPlay4BitStreamCtrlQueue */
260 0x40a, /* QDSP_uPAudPreProcCmdQueue */
261 0x41e, /* QDSP_uPAudRecBitStreamQueue */
262 0x41a, /* QDSP_uPAudRecCmdQueue */
263 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegActionCmdQueue */
264 QDSP_RTOS_NO_QUEUE, /* QDSP_uPJpegCfgCmdQueue */
265 QDSP_RTOS_NO_QUEUE, /* QDSP_uPVocProcQueue */
266 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandQueue */
267 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandScaleQueue */
268 QDSP_RTOS_NO_QUEUE, /* QDSP_vfeCommandTableQueue */
269 QDSP_RTOS_NO_QUEUE, /* QDSP_uPDiagQueue */
270};
271
272/* Tables to convert tasks to modules */
273static qdsp_module_type *qdsp_task_to_module[] = {
274 qdsp_combo_task_to_module_table,
275 qdsp_gaudio_task_to_module_table,
276 qdsp_qtv_lp_task_to_module_table,
277};
278
279/* Tables to retrieve queue offsets */
280static uint32_t *qdsp_queue_offset_table[] = {
281 qdsp_combo_queue_offset_table,
282 qdsp_gaudio_queue_offset_table,
283 qdsp_qtv_lp_queue_offset_table,
284};
285
286#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
287 { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
288 .clk_name = clkname, .clk_rate = clkrate, \
289 .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
290
291static struct adsp_module_info module_info[] = {
292 QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
293 QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
294 QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
295 QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
296 QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
297 adsp_vfe_patch_event),
298 QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
299 QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
300 QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd,
301 adsp_jpeg_patch_event),
302 QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
303 adsp_video_verify_cmd, NULL),
304 QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
305 QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
306 adsp_videoenc_verify_cmd, NULL),
307};
308
309int adsp_init_info(struct adsp_info *info)
310{
311 info->send_irq = 0x00c00200;
312 info->read_ctrl = 0x00400038;
313 info->write_ctrl = 0x00400034;
314
315 info->max_msg16_size = 193;
316 info->max_msg32_size = 8;
317
318 info->max_task_id = 16;
319 info->max_module_id = QDSP_MODULE_MAX - 1;
320 info->max_queue_id = QDSP_QUEUE_MAX;
321 info->max_image_id = 2;
322 info->queue_offset = qdsp_queue_offset_table;
323 info->task_to_module = qdsp_task_to_module;
324
325 info->module_count = ARRAY_SIZE(module_info);
326 info->module = module_info;
327 return 0;
328}
diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c
deleted file mode 100644
index 28a6f8da9477..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_driver.c
+++ /dev/null
@@ -1,643 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_driver.c
2 *
3 * Copyright (C) 2008 Google, Inc.
4 * Author: Iliyan Malchev <ibm@android.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/cdev.h>
18#include <linux/fs.h>
19#include <linux/list.h>
20#include <linux/platform_device.h>
21#include <linux/sched.h>
22#include <linux/slab.h>
23#include <linux/uaccess.h>
24
25#include "adsp.h"
26
27#include <linux/msm_adsp.h>
28#include <linux/android_pmem.h>
29
30struct adsp_pmem_region {
31 struct hlist_node list;
32 void *vaddr;
33 unsigned long paddr;
34 unsigned long kvaddr;
35 unsigned long len;
36 struct file *file;
37};
38
39struct adsp_device {
40 struct msm_adsp_module *module;
41
42 spinlock_t event_queue_lock;
43 wait_queue_head_t event_wait;
44 struct list_head event_queue;
45 int abort;
46
47 const char *name;
48 struct device *device;
49 struct cdev cdev;
50};
51
52static struct adsp_device *inode_to_device(struct inode *inode);
53
54#define __CONTAINS(r, v, l) ({ \
55 typeof(r) __r = r; \
56 typeof(v) __v = v; \
57 typeof(v) __e = __v + l; \
58 int res = __v >= __r->vaddr && \
59 __e <= __r->vaddr + __r->len; \
60 res; \
61})
62
63#define CONTAINS(r1, r2) ({ \
64 typeof(r2) __r2 = r2; \
65 __CONTAINS(r1, __r2->vaddr, __r2->len); \
66})
67
68#define IN_RANGE(r, v) ({ \
69 typeof(r) __r = r; \
70 typeof(v) __vv = v; \
71 int res = ((__vv >= __r->vaddr) && \
72 (__vv < (__r->vaddr + __r->len))); \
73 res; \
74})
75
76#define OVERLAPS(r1, r2) ({ \
77 typeof(r1) __r1 = r1; \
78 typeof(r2) __r2 = r2; \
79 typeof(__r2->vaddr) __v = __r2->vaddr; \
80 typeof(__v) __e = __v + __r2->len - 1; \
81 int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \
82 res; \
83})
84
85static int adsp_pmem_check(struct msm_adsp_module *module,
86 void *vaddr, unsigned long len)
87{
88 struct adsp_pmem_region *region_elt;
89 struct hlist_node *node;
90 struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };
91
92 hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
93 if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
94 OVERLAPS(region_elt, &t)) {
95 printk(KERN_ERR "adsp: module %s:"
96 " region (vaddr %p len %ld)"
97 " clashes with registered region"
98 " (vaddr %p paddr %p len %ld)\n",
99 module->name,
100 vaddr, len,
101 region_elt->vaddr,
102 (void *)region_elt->paddr,
103 region_elt->len);
104 return -EINVAL;
105 }
106 }
107
108 return 0;
109}
110
111static int adsp_pmem_add(struct msm_adsp_module *module,
112 struct adsp_pmem_info *info)
113{
114 unsigned long paddr, kvaddr, len;
115 struct file *file;
116 struct adsp_pmem_region *region;
117 int rc = -EINVAL;
118
119 mutex_lock(&module->pmem_regions_lock);
120 region = kmalloc(sizeof(*region), GFP_KERNEL);
121 if (!region) {
122 rc = -ENOMEM;
123 goto end;
124 }
125 INIT_HLIST_NODE(&region->list);
126 if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
127 kfree(region);
128 goto end;
129 }
130
131 rc = adsp_pmem_check(module, info->vaddr, len);
132 if (rc < 0) {
133 put_pmem_file(file);
134 kfree(region);
135 goto end;
136 }
137
138 region->vaddr = info->vaddr;
139 region->paddr = paddr;
140 region->kvaddr = kvaddr;
141 region->len = len;
142 region->file = file;
143
144 hlist_add_head(&region->list, &module->pmem_regions);
145end:
146 mutex_unlock(&module->pmem_regions_lock);
147 return rc;
148}
149
150static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
151 unsigned long len, struct adsp_pmem_region **region)
152{
153 struct hlist_node *node;
154 void *vaddr = *addr;
155 struct adsp_pmem_region *region_elt;
156
157 int match_count = 0;
158
159 *region = NULL;
160
161 /* returns physical address or zero */
162 hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
163 if (vaddr >= region_elt->vaddr &&
164 vaddr < region_elt->vaddr + region_elt->len &&
165 vaddr + len <= region_elt->vaddr + region_elt->len) {
166 /* offset since we could pass vaddr inside a registerd
167 * pmem buffer
168 */
169
170 match_count++;
171 if (!*region)
172 *region = region_elt;
173 }
174 }
175
176 if (match_count > 1) {
177 printk(KERN_ERR "adsp: module %s: "
178 "multiple hits for vaddr %p, len %ld\n",
179 module->name, vaddr, len);
180 hlist_for_each_entry(region_elt, node,
181 &module->pmem_regions, list) {
182 if (vaddr >= region_elt->vaddr &&
183 vaddr < region_elt->vaddr + region_elt->len &&
184 vaddr + len <= region_elt->vaddr + region_elt->len)
185 printk(KERN_ERR "\t%p, %ld --> %p\n",
186 region_elt->vaddr,
187 region_elt->len,
188 (void *)region_elt->paddr);
189 }
190 }
191
192 return *region ? 0 : -1;
193}
194
195int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
196 unsigned long *kvaddr, unsigned long len)
197{
198 struct adsp_pmem_region *region;
199 void *vaddr = *addr;
200 unsigned long *paddr = (unsigned long *)addr;
201 int ret;
202
203 ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
204 if (ret) {
205 printk(KERN_ERR "adsp: not patching %s (paddr & kvaddr),"
206 " lookup (%p, %ld) failed\n",
207 module->name, vaddr, len);
208 return ret;
209 }
210 *paddr = region->paddr + (vaddr - region->vaddr);
211 *kvaddr = region->kvaddr + (vaddr - region->vaddr);
212 return 0;
213}
214
215int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
216 unsigned long len)
217{
218 struct adsp_pmem_region *region;
219 void *vaddr = *addr;
220 unsigned long *paddr = (unsigned long *)addr;
221 int ret;
222
223 ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
224 if (ret) {
225 printk(KERN_ERR "adsp: not patching %s, lookup (%p, %ld) failed\n",
226 module->name, vaddr, len);
227 return ret;
228 }
229
230 *paddr = region->paddr + (vaddr - region->vaddr);
231 return 0;
232}
233
234static int adsp_verify_cmd(struct msm_adsp_module *module,
235 unsigned int queue_id, void *cmd_data,
236 size_t cmd_size)
237{
238 /* call the per module verifier */
239 if (module->verify_cmd)
240 return module->verify_cmd(module, queue_id, cmd_data,
241 cmd_size);
242 else
243 printk(KERN_INFO "adsp: no packet verifying function "
244 "for task %s\n", module->name);
245 return 0;
246}
247
248static long adsp_write_cmd(struct adsp_device *adev, void __user *arg)
249{
250 struct adsp_command_t cmd;
251 unsigned char buf[256];
252 void *cmd_data;
253 long rc;
254
255 if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
256 return -EFAULT;
257
258 if (cmd.len > 256) {
259 cmd_data = kmalloc(cmd.len, GFP_USER);
260 if (!cmd_data)
261 return -ENOMEM;
262 } else {
263 cmd_data = buf;
264 }
265
266 if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) {
267 rc = -EFAULT;
268 goto end;
269 }
270
271 mutex_lock(&adev->module->pmem_regions_lock);
272 if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) {
273 printk(KERN_ERR "module %s: verify failed.\n",
274 adev->module->name);
275 rc = -EINVAL;
276 goto end;
277 }
278 rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len);
279end:
280 mutex_unlock(&adev->module->pmem_regions_lock);
281
282 if (cmd.len > 256)
283 kfree(cmd_data);
284
285 return rc;
286}
287
288static int adsp_events_pending(struct adsp_device *adev)
289{
290 unsigned long flags;
291 int yes;
292 spin_lock_irqsave(&adev->event_queue_lock, flags);
293 yes = !list_empty(&adev->event_queue);
294 spin_unlock_irqrestore(&adev->event_queue_lock, flags);
295 return yes || adev->abort;
296}
297
298static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr,
299 struct adsp_pmem_region **region)
300{
301 struct hlist_node *node;
302 unsigned long paddr = (unsigned long)(*addr);
303 struct adsp_pmem_region *region_elt;
304
305 hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
306 if (paddr >= region_elt->paddr &&
307 paddr < region_elt->paddr + region_elt->len) {
308 *region = region_elt;
309 return 0;
310 }
311 }
312 return -1;
313}
314
315int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr)
316{
317 struct adsp_pmem_region *region;
318 unsigned long paddr = (unsigned long)(*addr);
319 unsigned long *vaddr = (unsigned long *)addr;
320 int ret;
321
322 ret = adsp_pmem_lookup_paddr(module, addr, &region);
323 if (ret) {
324 printk(KERN_ERR "adsp: not patching %s, paddr %p lookup failed\n",
325 module->name, vaddr);
326 return ret;
327 }
328
329 *vaddr = (unsigned long)region->vaddr + (paddr - region->paddr);
330 return 0;
331}
332
333static int adsp_patch_event(struct msm_adsp_module *module,
334 struct adsp_event *event)
335{
336 /* call the per-module msg verifier */
337 if (module->patch_event)
338 return module->patch_event(module, event);
339 return 0;
340}
341
342static long adsp_get_event(struct adsp_device *adev, void __user *arg)
343{
344 unsigned long flags;
345 struct adsp_event *data = NULL;
346 struct adsp_event_t evt;
347 int timeout;
348 long rc = 0;
349
350 if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t)))
351 return -EFAULT;
352
353 timeout = (int)evt.timeout_ms;
354
355 if (timeout > 0) {
356 rc = wait_event_interruptible_timeout(
357 adev->event_wait, adsp_events_pending(adev),
358 msecs_to_jiffies(timeout));
359 if (rc == 0)
360 return -ETIMEDOUT;
361 } else {
362 rc = wait_event_interruptible(
363 adev->event_wait, adsp_events_pending(adev));
364 }
365 if (rc < 0)
366 return rc;
367
368 if (adev->abort)
369 return -ENODEV;
370
371 spin_lock_irqsave(&adev->event_queue_lock, flags);
372 if (!list_empty(&adev->event_queue)) {
373 data = list_first_entry(&adev->event_queue,
374 struct adsp_event, list);
375 list_del(&data->list);
376 }
377 spin_unlock_irqrestore(&adev->event_queue_lock, flags);
378
379 if (!data)
380 return -EAGAIN;
381
382 /* DSP messages are type 0; they may contain physical addresses */
383 if (data->type == 0)
384 adsp_patch_event(adev->module, data);
385
386 /* map adsp_event --> adsp_event_t */
387 if (evt.len < data->size) {
388 rc = -ETOOSMALL;
389 goto end;
390 }
391 if (data->msg_id != EVENT_MSG_ID) {
392 if (copy_to_user((void *)(evt.data), data->data.msg16,
393 data->size)) {
394 rc = -EFAULT;
395 goto end;
396 }
397 } else {
398 if (copy_to_user((void *)(evt.data), data->data.msg32,
399 data->size)) {
400 rc = -EFAULT;
401 goto end;
402 }
403 }
404
405 evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */
406 evt.msg_id = data->msg_id;
407 evt.flags = data->is16;
408 evt.len = data->size;
409 if (copy_to_user(arg, &evt, sizeof(evt)))
410 rc = -EFAULT;
411end:
412 kfree(data);
413 return rc;
414}
415
416static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
417{
418 struct adsp_device *adev = filp->private_data;
419
420 switch (cmd) {
421 case ADSP_IOCTL_ENABLE:
422 return msm_adsp_enable(adev->module);
423
424 case ADSP_IOCTL_DISABLE:
425 return msm_adsp_disable(adev->module);
426
427 case ADSP_IOCTL_DISABLE_EVENT_RSP:
428 return 0;
429
430 case ADSP_IOCTL_DISABLE_ACK:
431 pr_err("adsp: ADSP_IOCTL_DISABLE_ACK is not implemented.\n");
432 break;
433
434 case ADSP_IOCTL_WRITE_COMMAND:
435 return adsp_write_cmd(adev, (void __user *) arg);
436
437 case ADSP_IOCTL_GET_EVENT:
438 return adsp_get_event(adev, (void __user *) arg);
439
440 case ADSP_IOCTL_SET_CLKRATE: {
441#if CONFIG_MSM_AMSS_VERSION==6350
442 unsigned long clk_rate;
443 if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate)))
444 return -EFAULT;
445 return adsp_set_clkrate(adev->module, clk_rate);
446#endif
447 }
448
449 case ADSP_IOCTL_REGISTER_PMEM: {
450 struct adsp_pmem_info info;
451 if (copy_from_user(&info, (void *) arg, sizeof(info)))
452 return -EFAULT;
453 return adsp_pmem_add(adev->module, &info);
454 }
455
456 case ADSP_IOCTL_ABORT_EVENT_READ:
457 adev->abort = 1;
458 wake_up(&adev->event_wait);
459 break;
460
461 default:
462 break;
463 }
464 return -EINVAL;
465}
466
467static int adsp_release(struct inode *inode, struct file *filp)
468{
469 struct adsp_device *adev = filp->private_data;
470 struct msm_adsp_module *module = adev->module;
471 struct hlist_node *node, *tmp;
472 struct adsp_pmem_region *region;
473
474 pr_info("adsp_release() '%s'\n", adev->name);
475
476 /* clear module before putting it to avoid race with open() */
477 adev->module = NULL;
478
479 mutex_lock(&module->pmem_regions_lock);
480 hlist_for_each_safe(node, tmp, &module->pmem_regions) {
481 region = hlist_entry(node, struct adsp_pmem_region, list);
482 hlist_del(node);
483 put_pmem_file(region->file);
484 kfree(region);
485 }
486 mutex_unlock(&module->pmem_regions_lock);
487 BUG_ON(!hlist_empty(&module->pmem_regions));
488
489 msm_adsp_put(module);
490 return 0;
491}
492
493static void adsp_event(void *driver_data, unsigned id, size_t len,
494 void (*getevent)(void *ptr, size_t len))
495{
496 struct adsp_device *adev = driver_data;
497 struct adsp_event *event;
498 unsigned long flags;
499
500 if (len > ADSP_EVENT_MAX_SIZE) {
501 pr_err("adsp_event: event too large (%d bytes)\n", len);
502 return;
503 }
504
505 event = kmalloc(sizeof(*event), GFP_ATOMIC);
506 if (!event) {
507 pr_err("adsp_event: cannot allocate buffer\n");
508 return;
509 }
510
511 if (id != EVENT_MSG_ID) {
512 event->type = 0;
513 event->is16 = 0;
514 event->msg_id = id;
515 event->size = len;
516
517 getevent(event->data.msg16, len);
518 } else {
519 event->type = 1;
520 event->is16 = 1;
521 event->msg_id = id;
522 event->size = len;
523 getevent(event->data.msg32, len);
524 }
525
526 spin_lock_irqsave(&adev->event_queue_lock, flags);
527 list_add_tail(&event->list, &adev->event_queue);
528 spin_unlock_irqrestore(&adev->event_queue_lock, flags);
529 wake_up(&adev->event_wait);
530}
531
532static struct msm_adsp_ops adsp_ops = {
533 .event = adsp_event,
534};
535
536static int adsp_open(struct inode *inode, struct file *filp)
537{
538 struct adsp_device *adev;
539 int rc;
540
541 rc = nonseekable_open(inode, filp);
542 if (rc < 0)
543 return rc;
544
545 adev = inode_to_device(inode);
546 if (!adev)
547 return -ENODEV;
548
549 pr_info("adsp_open() name = '%s'\n", adev->name);
550
551 rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev);
552 if (rc)
553 return rc;
554
555 pr_info("adsp_open() module '%s' adev %p\n", adev->name, adev);
556 filp->private_data = adev;
557 adev->abort = 0;
558 INIT_HLIST_HEAD(&adev->module->pmem_regions);
559 mutex_init(&adev->module->pmem_regions_lock);
560
561 return 0;
562}
563
564static unsigned adsp_device_count;
565static struct adsp_device *adsp_devices;
566
567static struct adsp_device *inode_to_device(struct inode *inode)
568{
569 unsigned n = MINOR(inode->i_rdev);
570 if (n < adsp_device_count) {
571 if (adsp_devices[n].device)
572 return adsp_devices + n;
573 }
574 return NULL;
575}
576
577static dev_t adsp_devno;
578static struct class *adsp_class;
579
580static struct file_operations adsp_fops = {
581 .owner = THIS_MODULE,
582 .open = adsp_open,
583 .unlocked_ioctl = adsp_ioctl,
584 .release = adsp_release,
585 .llseek = no_llseek,
586};
587
588static void adsp_create(struct adsp_device *adev, const char *name,
589 struct device *parent, dev_t devt)
590{
591 struct device *dev;
592 int rc;
593
594 dev = device_create(adsp_class, parent, devt, "%s", name);
595 if (IS_ERR(dev))
596 return;
597
598 init_waitqueue_head(&adev->event_wait);
599 INIT_LIST_HEAD(&adev->event_queue);
600 spin_lock_init(&adev->event_queue_lock);
601
602 cdev_init(&adev->cdev, &adsp_fops);
603 adev->cdev.owner = THIS_MODULE;
604
605 rc = cdev_add(&adev->cdev, devt, 1);
606 if (rc < 0) {
607 device_destroy(adsp_class, devt);
608 } else {
609 adev->device = dev;
610 adev->name = name;
611 }
612}
613
614void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n)
615{
616 int rc;
617
618 adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL);
619 if (!adsp_devices)
620 return;
621
622 adsp_class = class_create(THIS_MODULE, "adsp");
623 if (IS_ERR(adsp_class))
624 goto fail_create_class;
625
626 rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp");
627 if (rc < 0)
628 goto fail_alloc_region;
629
630 adsp_device_count = n;
631 for (n = 0; n < adsp_device_count; n++) {
632 adsp_create(adsp_devices + n,
633 modules[n].name, &modules[n].pdev.dev,
634 MKDEV(MAJOR(adsp_devno), n));
635 }
636
637 return;
638
639fail_alloc_region:
640 class_unregister(adsp_class);
641fail_create_class:
642 kfree(adsp_devices);
643}
diff --git a/drivers/staging/dream/qdsp5/adsp_info.c b/drivers/staging/dream/qdsp5/adsp_info.c
deleted file mode 100644
index b9c77d20b5c4..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_info.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/* arch/arm/mach-msm/adsp_info.c
2 *
3 * Copyright (c) 2008 QUALCOMM Incorporated.
4 * Copyright (c) 2008 QUALCOMM USA, INC.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include "adsp.h"
18
19/* Firmware modules */
20#define QDSP_MODULE_KERNEL 0x0106dd4e
21#define QDSP_MODULE_AFETASK 0x0106dd6f
22#define QDSP_MODULE_AUDPLAY0TASK 0x0106dd70
23#define QDSP_MODULE_AUDPLAY1TASK 0x0106dd71
24#define QDSP_MODULE_AUDPPTASK 0x0106dd72
25#define QDSP_MODULE_VIDEOTASK 0x0106dd73
26#define QDSP_MODULE_VIDEO_AAC_VOC 0x0106dd74
27#define QDSP_MODULE_PCM_DEC 0x0106dd75
28#define QDSP_MODULE_AUDIO_DEC_MP3 0x0106dd76
29#define QDSP_MODULE_AUDIO_DEC_AAC 0x0106dd77
30#define QDSP_MODULE_AUDIO_DEC_WMA 0x0106dd78
31#define QDSP_MODULE_HOSTPCM 0x0106dd79
32#define QDSP_MODULE_DTMF 0x0106dd7a
33#define QDSP_MODULE_AUDRECTASK 0x0106dd7b
34#define QDSP_MODULE_AUDPREPROCTASK 0x0106dd7c
35#define QDSP_MODULE_SBC_ENC 0x0106dd7d
36#define QDSP_MODULE_VOC_UMTS 0x0106dd9a
37#define QDSP_MODULE_VOC_CDMA 0x0106dd98
38#define QDSP_MODULE_VOC_PCM 0x0106dd7f
39#define QDSP_MODULE_VOCENCTASK 0x0106dd80
40#define QDSP_MODULE_VOCDECTASK 0x0106dd81
41#define QDSP_MODULE_VOICEPROCTASK 0x0106dd82
42#define QDSP_MODULE_VIDEOENCTASK 0x0106dd83
43#define QDSP_MODULE_VFETASK 0x0106dd84
44#define QDSP_MODULE_WAV_ENC 0x0106dd85
45#define QDSP_MODULE_AACLC_ENC 0x0106dd86
46#define QDSP_MODULE_VIDEO_AMR 0x0106dd87
47#define QDSP_MODULE_VOC_AMR 0x0106dd88
48#define QDSP_MODULE_VOC_EVRC 0x0106dd89
49#define QDSP_MODULE_VOC_13K 0x0106dd8a
50#define QDSP_MODULE_VOC_FGV 0x0106dd8b
51#define QDSP_MODULE_DIAGTASK 0x0106dd8c
52#define QDSP_MODULE_JPEGTASK 0x0106dd8d
53#define QDSP_MODULE_LPMTASK 0x0106dd8e
54#define QDSP_MODULE_QCAMTASK 0x0106dd8f
55#define QDSP_MODULE_MODMATHTASK 0x0106dd90
56#define QDSP_MODULE_AUDPLAY2TASK 0x0106dd91
57#define QDSP_MODULE_AUDPLAY3TASK 0x0106dd92
58#define QDSP_MODULE_AUDPLAY4TASK 0x0106dd93
59#define QDSP_MODULE_GRAPHICSTASK 0x0106dd94
60#define QDSP_MODULE_MIDI 0x0106dd95
61#define QDSP_MODULE_GAUDIO 0x0106dd96
62#define QDSP_MODULE_VDEC_LP_MODE 0x0106dd97
63#define QDSP_MODULE_MAX 0x7fffffff
64
65 /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
66#define QDSP_MODULE_32BIT_DUMMY 0x10000
67
68static uint32_t *qdsp_task_to_module[IMG_MAX];
69static uint32_t *qdsp_queue_offset_table[IMG_MAX];
70
71#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
72 { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
73 .clk_name = clkname, .clk_rate = clkrate, \
74 .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
75
76static struct adsp_module_info module_info[] = {
77 QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
78 QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
79 QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
80 QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
81 QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
82 adsp_vfe_patch_event),
83 QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
84 QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
85 QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd,
86 adsp_jpeg_patch_event),
87 QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
88 adsp_video_verify_cmd, NULL),
89 QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
90 QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
91 adsp_videoenc_verify_cmd, NULL),
92};
93
94int adsp_init_info(struct adsp_info *info)
95{
96 uint32_t img_num;
97
98 info->send_irq = 0x00c00200;
99 info->read_ctrl = 0x00400038;
100 info->write_ctrl = 0x00400034;
101
102 info->max_msg16_size = 193;
103 info->max_msg32_size = 8;
104 for (img_num = 0; img_num < IMG_MAX; img_num++)
105 qdsp_queue_offset_table[img_num] =
106 &info->init_info_ptr->queue_offsets[img_num][0];
107
108 for (img_num = 0; img_num < IMG_MAX; img_num++)
109 qdsp_task_to_module[img_num] =
110 &info->init_info_ptr->task_to_module_tbl[img_num][0];
111 info->max_task_id = 30;
112 info->max_module_id = QDSP_MODULE_MAX - 1;
113 info->max_queue_id = QDSP_MAX_NUM_QUEUES;
114 info->max_image_id = 2;
115 info->queue_offset = qdsp_queue_offset_table;
116 info->task_to_module = qdsp_task_to_module;
117
118 info->module_count = ARRAY_SIZE(module_info);
119 info->module = module_info;
120 return 0;
121}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c b/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c
deleted file mode 100644
index 4f493edb6c94..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c
+++ /dev/null
@@ -1,31 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
2 *
3 * Verification code for aDSP JPEG events.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5jpegmsg.h>
20#include "adsp.h"
21
22int adsp_jpeg_patch_event(struct msm_adsp_module *module,
23 struct adsp_event *event)
24{
25 if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) {
26 jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16;
27 return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr);
28 }
29
30 return 0;
31}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c
deleted file mode 100644
index b33eba25569c..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
2 *
3 * Verification code for aDSP JPEG packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5jpegcmdi.h>
20#include "adsp.h"
21
22static uint32_t dec_fmt;
23
24static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size,
25 uint32_t *chroma_size)
26{
27 uint32_t fmt, luma_width, luma_height;
28
29 fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M;
30 luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M)
31 >> 16;
32 luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M;
33 *luma_size = luma_width * luma_height;
34 if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2)
35 *chroma_size = *luma_size/2;
36 else
37 *chroma_size = *luma_size;
38}
39
40static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module,
41 void *cmd_data, size_t cmd_size)
42{
43 jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data;
44 uint32_t luma_size, chroma_size;
45 int i, num_frags;
46
47 if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) {
48 printk(KERN_ERR "adsp: module %s: JPEG ENC CFG invalid cmd_size %d\n",
49 module->name, cmd_size);
50 return -1;
51 }
52
53 get_sizes(cmd, &luma_size, &chroma_size);
54 num_frags = (cmd->process_cfg >> 10) & 0xf;
55 num_frags = ((num_frags == 1) ? num_frags : num_frags * 2);
56 for (i = 0; i < num_frags; i += 2) {
57 if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) ||
58 adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size))
59 return -1;
60 }
61
62 if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1,
63 cmd->op_buf_0_cfg_part2) ||
64 adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1,
65 cmd->op_buf_1_cfg_part2))
66 return -1;
67 return 0;
68}
69
70static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module,
71 void *cmd_data, size_t cmd_size)
72{
73 jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data;
74 uint32_t div;
75
76 if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) {
77 printk(KERN_ERR "adsp: module %s: JPEG DEC CFG invalid cmd_size %d\n",
78 module->name, cmd_size);
79 return -1;
80 }
81
82 if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1,
83 cmd->ip_stream_buf_cfg_part2) ||
84 adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1,
85 cmd->op_stream_buf_0_cfg_part2) ||
86 adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1,
87 cmd->op_stream_buf_1_cfg_part2))
88 return -1;
89 dec_fmt = cmd->op_data_format &
90 JPEG_CMD_DEC_OP_DATA_FORMAT_M;
91 div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
92 if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3,
93 cmd->op_stream_buf_0_cfg_part2 / div) ||
94 adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3,
95 cmd->op_stream_buf_1_cfg_part2 / div))
96 return -1;
97 return 0;
98}
99
100static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module,
101 void *cmd_data, size_t cmd_size)
102{
103 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
104 switch(cmd_id) {
105 case JPEG_CMD_ENC_CFG:
106 return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size);
107 case JPEG_CMD_DEC_CFG:
108 return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size);
109 default:
110 if (cmd_id > 1) {
111 printk(KERN_ERR "adsp: module %s: invalid JPEG CFG cmd_id %d\n", module->name, cmd_id);
112 return -1;
113 }
114 }
115 return 0;
116}
117
118static int verify_jpeg_action_cmd(struct msm_adsp_module *module,
119 void *cmd_data, size_t cmd_size)
120{
121 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
122 switch (cmd_id) {
123 case JPEG_CMD_ENC_OP_CONSUMED:
124 {
125 jpeg_cmd_enc_op_consumed *cmd =
126 (jpeg_cmd_enc_op_consumed *)cmd_data;
127
128 if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
129 printk(KERN_ERR "adsp: module %s: JPEG_CMD_ENC_OP_CONSUMED invalid size %d\n",
130 module->name, cmd_size);
131 return -1;
132 }
133
134 if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr,
135 cmd->op_buf_size))
136 return -1;
137 }
138 break;
139 case JPEG_CMD_DEC_OP_CONSUMED:
140 {
141 uint32_t div;
142 jpeg_cmd_dec_op_consumed *cmd =
143 (jpeg_cmd_dec_op_consumed *)cmd_data;
144
145 if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
146 printk(KERN_ERR "adsp: module %s: JPEG_CMD_DEC_OP_CONSUMED invalid size %d\n",
147 module->name, cmd_size);
148 return -1;
149 }
150
151 div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
152 if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr,
153 cmd->luma_op_buf_size) ||
154 adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr,
155 cmd->luma_op_buf_size / div))
156 return -1;
157 }
158 break;
159 default:
160 if (cmd_id > 7) {
161 printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
162 module->name, cmd_id);
163 return -1;
164 }
165 }
166 return 0;
167}
168
169int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
170 unsigned int queue_id, void *cmd_data,
171 size_t cmd_size)
172{
173 switch(queue_id) {
174 case QDSP_uPJpegCfgCmdQueue:
175 return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size);
176 case QDSP_uPJpegActionCmdQueue:
177 return verify_jpeg_action_cmd(module, cmd_data, cmd_size);
178 default:
179 return -1;
180 }
181}
182
diff --git a/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c
deleted file mode 100644
index 1e23ef392700..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
2 *
3 * Verificion code for aDSP LPM packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5lpmcmdi.h>
20#include "adsp.h"
21
22int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
23 unsigned int queue_id, void *cmd_data,
24 size_t cmd_size)
25{
26 uint32_t cmd_id, col_height, input_row_incr, output_row_incr,
27 input_size, output_size;
28 uint32_t size_mask = 0x0fff;
29 lpm_cmd_start *cmd;
30
31 if (queue_id != QDSP_lpmCommandQueue) {
32 printk(KERN_ERR "adsp: module %s: wrong queue id %d\n",
33 module->name, queue_id);
34 return -1;
35 }
36
37 cmd = (lpm_cmd_start *)cmd_data;
38 cmd_id = cmd->cmd_id;
39
40 if (cmd_id == LPM_CMD_START) {
41 if (cmd_size != sizeof(lpm_cmd_start)) {
42 printk(KERN_ERR "adsp: module %s: wrong size %d, expect %d\n",
43 module->name, cmd_size, sizeof(lpm_cmd_start));
44 return -1;
45 }
46 col_height = cmd->ip_data_cfg_part1 & size_mask;
47 input_row_incr = cmd->ip_data_cfg_part2 & size_mask;
48 output_row_incr = cmd->op_data_cfg_part1 & size_mask;
49 input_size = col_height * input_row_incr;
50 output_size = col_height * output_row_incr;
51 if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module,
52 (void **)(&cmd->ip_data_cfg_part4),
53 input_size)) ||
54 (cmd->op_data_cfg_part3 && adsp_pmem_fixup(module,
55 (void **)(&cmd->op_data_cfg_part3),
56 output_size)))
57 return -1;
58 } else if (cmd_id > 1) {
59 printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
60 module->name, cmd_id);
61 return -1;
62 }
63 return 0;
64}
65
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c b/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c
deleted file mode 100644
index a56392b3521c..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
2 *
3 * Verification code for aDSP VFE packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5vfemsg.h>
20#include "adsp.h"
21
22static int patch_op_event(struct msm_adsp_module *module,
23 struct adsp_event *event)
24{
25 vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16;
26 if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) ||
27 adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr))
28 return -1;
29 return 0;
30}
31
32static int patch_af_wb_event(struct msm_adsp_module *module,
33 struct adsp_event *event)
34{
35 vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16;
36 return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf);
37}
38
39int adsp_vfe_patch_event(struct msm_adsp_module *module,
40 struct adsp_event *event)
41{
42 switch(event->msg_id) {
43 case VFE_MSG_OP1:
44 case VFE_MSG_OP2:
45 return patch_op_event(module, event);
46 case VFE_MSG_STATS_AF:
47 case VFE_MSG_STATS_WB_EXP:
48 return patch_af_wb_event(module, event);
49 default:
50 break;
51 }
52
53 return 0;
54}
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
deleted file mode 100644
index 927d50a730ff..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
2 *
3 * Verification code for aDSP VFE packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <mach/qdsp5/qdsp5vfecmdi.h>
20#include "adsp.h"
21
22static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
23static uint32_t af_size = 4228;
24static uint32_t awb_size = 8196;
25
26static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
27 void *cmd_data, size_t cmd_size)
28{
29 vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
30 void **addr_y = (void **)&cmd->op1_buf_y_addr;
31 void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
32
33 if (cmd_size != sizeof(vfe_cmd_op1_ack))
34 return -1;
35 if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
36 (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
37 return -1;
38 return 0;
39}
40
41static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
42 void *cmd_data, size_t cmd_size)
43{
44 int i;
45 vfe_cmd_stats_autofocus_cfg *cmd =
46 (vfe_cmd_stats_autofocus_cfg *)cmd_data;
47
48 if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
49 return -1;
50
51 for (i = 0; i < 3; i++) {
52 void **addr = (void **)(&cmd->af_stats_op_buf[i]);
53 if (*addr && adsp_pmem_fixup(module, addr, af_size))
54 return -1;
55 }
56 return 0;
57}
58
59static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
60 void *cmd_data, size_t cmd_size)
61{
62 vfe_cmd_stats_wb_exp_cfg *cmd =
63 (vfe_cmd_stats_wb_exp_cfg *)cmd_data;
64 int i;
65
66 if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
67 return -1;
68
69 for (i = 0; i < 3; i++) {
70 void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
71 if (*addr && adsp_pmem_fixup(module, addr, awb_size))
72 return -1;
73 }
74 return 0;
75}
76
77static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
78 void *cmd_data, size_t cmd_size)
79{
80 vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
81 void **addr = (void **)&cmd->af_stats_op_buf;
82
83 if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
84 return -1;
85
86 if (*addr && adsp_pmem_fixup(module, addr, af_size))
87 return -1;
88 return 0;
89}
90
91static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
92 void *cmd_data, size_t cmd_size)
93{
94 vfe_cmd_stats_wb_exp_ack *cmd =
95 (vfe_cmd_stats_wb_exp_ack *)cmd_data;
96 void **addr = (void **)&cmd->wb_exp_stats_op_buf;
97
98 if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
99 return -1;
100
101 if (*addr && adsp_pmem_fixup(module, addr, awb_size))
102 return -1;
103 return 0;
104}
105
106static int verify_vfe_command(struct msm_adsp_module *module,
107 void *cmd_data, size_t cmd_size)
108{
109 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
110 switch (cmd_id) {
111 case VFE_CMD_OP1_ACK:
112 return verify_cmd_op_ack(module, cmd_data, cmd_size);
113 case VFE_CMD_OP2_ACK:
114 return verify_cmd_op_ack(module, cmd_data, cmd_size);
115 case VFE_CMD_STATS_AUTOFOCUS_CFG:
116 return verify_cmd_stats_autofocus_cfg(module, cmd_data,
117 cmd_size);
118 case VFE_CMD_STATS_WB_EXP_CFG:
119 return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
120 case VFE_CMD_STATS_AF_ACK:
121 return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
122 case VFE_CMD_STATS_WB_EXP_ACK:
123 return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
124 default:
125 if (cmd_id > 29) {
126 printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
127 return -1;
128 }
129 }
130 return 0;
131}
132
133static int verify_vfe_command_scale(struct msm_adsp_module *module,
134 void *cmd_data, size_t cmd_size)
135{
136 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
137 // FIXME: check the size
138 if (cmd_id > 1) {
139 printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
140 return -1;
141 }
142 return 0;
143}
144
145
146static uint32_t get_size(uint32_t hw)
147{
148 uint32_t height, width;
149 uint32_t height_mask = 0x3ffc;
150 uint32_t width_mask = 0x3ffc000;
151
152 height = (hw & height_mask) >> 2;
153 width = (hw & width_mask) >> 14 ;
154 return height * width;
155}
156
157static int verify_vfe_command_table(struct msm_adsp_module *module,
158 void *cmd_data, size_t cmd_size)
159{
160 uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
161 int i;
162
163 switch (cmd_id) {
164 case VFE_CMD_AXI_IP_CFG:
165 {
166 vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
167 uint32_t size;
168 if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
169 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
170 module->name, cmd_size);
171 return -1;
172 }
173 size = get_size(cmd->ip_cfg_part2);
174
175 for (i = 0; i < 8; i++) {
176 void **addr = (void **)
177 &cmd->ip_buf_addr[i];
178 if (*addr && adsp_pmem_fixup(module, addr, size))
179 return -1;
180 }
181 }
182 case VFE_CMD_AXI_OP_CFG:
183 {
184 vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
185 void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
186
187 if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
188 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
189 module->name, cmd_size);
190 return -1;
191 }
192 size1_y = get_size(cmd->op1_y_cfg_part2);
193 size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
194 size2_y = get_size(cmd->op2_y_cfg_part2);
195 size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
196 for (i = 0; i < 8; i++) {
197 addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
198 addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
199 addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
200 addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
201/*
202 printk("module %s: [%d] %p %p %p %p\n",
203 module->name, i,
204 *addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
205*/
206 if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
207 (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
208 (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
209 (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
210 return -1;
211 }
212 }
213 default:
214 if (cmd_id > 4) {
215 printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
216 module->name, cmd_id);
217 return -1;
218 }
219 }
220 return 0;
221}
222
223int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
224 unsigned int queue_id, void *cmd_data,
225 size_t cmd_size)
226{
227 switch (queue_id) {
228 case QDSP_vfeCommandQueue:
229 return verify_vfe_command(module, cmd_data, cmd_size);
230 case QDSP_vfeCommandScaleQueue:
231 return verify_vfe_command_scale(module, cmd_data, cmd_size);
232 case QDSP_vfeCommandTableQueue:
233 return verify_vfe_command_table(module, cmd_data, cmd_size);
234 default:
235 printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
236 module->name, queue_id);
237 return -1;
238 }
239}
diff --git a/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c
deleted file mode 100644
index 53aff77cfd92..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c
+++ /dev/null
@@ -1,163 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
2 *
3 * Verificion code for aDSP VDEC packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/io.h>
19
20#define ADSP_DEBUG_MSGS 0
21#if ADSP_DEBUG_MSGS
22#define DLOG(fmt,args...) \
23 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
24 ##args); } \
25 while (0)
26#else
27#define DLOG(x...) do {} while (0)
28#endif
29
30
31#include <mach/qdsp5/qdsp5vdeccmdi.h>
32#include "adsp.h"
33
34static inline void *high_low_short_to_ptr(unsigned short high,
35 unsigned short low)
36{
37 return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
38}
39
40static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
41 unsigned short *low)
42{
43 *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
44 *low = (unsigned short)((unsigned long)ptr & 0xffff);
45}
46
47static int pmem_fixup_high_low(unsigned short *high,
48 unsigned short *low,
49 unsigned short size_high,
50 unsigned short size_low,
51 struct msm_adsp_module *module,
52 unsigned long *addr, unsigned long *size)
53{
54 void *phys_addr;
55 unsigned long phys_size;
56 unsigned long kvaddr;
57
58 phys_addr = high_low_short_to_ptr(*high, *low);
59 phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
60 DLOG("virt %x %x\n", phys_addr, phys_size);
61 if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
62 DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
63 *high, *low, size_high, size_low, phys_addr, phys_size);
64 return -1;
65 }
66 ptr_to_high_low_short(phys_addr, high, low);
67 DLOG("phys %x %x\n", phys_addr, phys_size);
68 if (addr)
69 *addr = kvaddr;
70 if (size)
71 *size = phys_size;
72 return 0;
73}
74
75static int verify_vdec_pkt_cmd(struct msm_adsp_module *module,
76 void *cmd_data, size_t cmd_size)
77{
78 unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
79 viddec_cmd_subframe_pkt *pkt;
80 unsigned long subframe_pkt_addr;
81 unsigned long subframe_pkt_size;
82 viddec_cmd_frame_header_packet *frame_header_pkt;
83 int i, num_addr, skip;
84 unsigned short *frame_buffer_high, *frame_buffer_low;
85 unsigned long frame_buffer_size;
86 unsigned short frame_buffer_size_high, frame_buffer_size_low;
87
88 DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
89 if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) {
90 printk(KERN_INFO "adsp_video: unknown video packet %u\n",
91 cmd_id);
92 return 0;
93 }
94 if (cmd_size < sizeof(viddec_cmd_subframe_pkt))
95 return -1;
96
97 pkt = (viddec_cmd_subframe_pkt *)cmd_data;
98
99 if (pmem_fixup_high_low(&(pkt->subframe_packet_high),
100 &(pkt->subframe_packet_low),
101 pkt->subframe_packet_size_high,
102 pkt->subframe_packet_size_low,
103 module,
104 &subframe_pkt_addr,
105 &subframe_pkt_size))
106 return -1;
107
108 /* deref those ptrs and check if they are a frame header packet */
109 frame_header_pkt = (viddec_cmd_frame_header_packet *)subframe_pkt_addr;
110
111 switch (frame_header_pkt->packet_id) {
112 case 0xB201: /* h.264 */
113 num_addr = skip = 8;
114 break;
115 case 0x4D01: /* mpeg-4 and h.263 */
116 num_addr = 3;
117 skip = 0;
118 break;
119 default:
120 return 0;
121 }
122
123 frame_buffer_high = &frame_header_pkt->frame_buffer_0_high;
124 frame_buffer_low = &frame_header_pkt->frame_buffer_0_low;
125 frame_buffer_size = (frame_header_pkt->x_dimension *
126 frame_header_pkt->y_dimension * 3) / 2;
127 ptr_to_high_low_short((void *)frame_buffer_size,
128 &frame_buffer_size_high,
129 &frame_buffer_size_low);
130 for (i = 0; i < num_addr; i++) {
131 if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
132 frame_buffer_size_high,
133 frame_buffer_size_low,
134 module,
135 NULL, NULL))
136 return -1;
137 frame_buffer_high += 2;
138 frame_buffer_low += 2;
139 }
140 /* Patch the output buffer. */
141 frame_buffer_high += 2*skip;
142 frame_buffer_low += 2*skip;
143 if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
144 frame_buffer_size_high,
145 frame_buffer_size_low, module, NULL, NULL))
146 return -1;
147 return 0;
148}
149
150int adsp_video_verify_cmd(struct msm_adsp_module *module,
151 unsigned int queue_id, void *cmd_data,
152 size_t cmd_size)
153{
154 switch (queue_id) {
155 case QDSP_mpuVDecPktQueue:
156 DLOG("\n");
157 return verify_vdec_pkt_cmd(module, cmd_data, cmd_size);
158 default:
159 printk(KERN_INFO "unknown video queue %u\n", queue_id);
160 return 0;
161 }
162}
163
diff --git a/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
deleted file mode 100644
index ee3744950523..000000000000
--- a/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
2 *
3 * Verificion code for aDSP VENC packets from userspace.
4 *
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/io.h>
19
20#define ADSP_DEBUG_MSGS 0
21#if ADSP_DEBUG_MSGS
22#define DLOG(fmt,args...) \
23 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
24 ##args); } \
25 while (0)
26#else
27#define DLOG(x...) do {} while (0)
28#endif
29
30#include <mach/qdsp5/qdsp5venccmdi.h>
31#include "adsp.h"
32
33
34static unsigned short x_dimension, y_dimension;
35
36static inline void *high_low_short_to_ptr(unsigned short high,
37 unsigned short low)
38{
39 return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
40}
41
42static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
43 unsigned short *low)
44{
45 *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
46 *low = (unsigned short)((unsigned long)ptr & 0xffff);
47}
48
49static int pmem_fixup_high_low(unsigned short *high,
50 unsigned short *low,
51 unsigned short size_high,
52 unsigned short size_low,
53 struct msm_adsp_module *module,
54 unsigned long *addr, unsigned long *size)
55{
56 void *phys_addr;
57 unsigned long phys_size;
58 unsigned long kvaddr;
59
60 phys_addr = high_low_short_to_ptr(*high, *low);
61 phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
62 DLOG("virt %x %x\n", phys_addr, phys_size);
63 if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
64 DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
65 *high, *low, size_high, size_low, phys_addr, phys_size);
66 return -1;
67 }
68 ptr_to_high_low_short(phys_addr, high, low);
69 DLOG("phys %x %x\n", phys_addr, phys_size);
70 if (addr)
71 *addr = kvaddr;
72 if (size)
73 *size = phys_size;
74 return 0;
75}
76
77static int verify_venc_cmd(struct msm_adsp_module *module,
78 void *cmd_data, size_t cmd_size)
79{
80 unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
81 unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
82 unsigned short frame_buf_size_high, frame_buf_size_low;
83 unsigned short luma_buf_size_high, luma_buf_size_low;
84 unsigned short chroma_buf_size_high, chroma_buf_size_low;
85 videnc_cmd_cfg *config_cmd;
86 videnc_cmd_frame_start *frame_cmd;
87 videnc_cmd_dis *dis_cmd;
88
89 DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
90 switch (cmd_id) {
91 case VIDENC_CMD_ACTIVE:
92 if (cmd_size < sizeof(videnc_cmd_active))
93 return -1;
94 break;
95 case VIDENC_CMD_IDLE:
96 if (cmd_size < sizeof(videnc_cmd_idle))
97 return -1;
98 x_dimension = y_dimension = 0;
99 break;
100 case VIDENC_CMD_STATUS_QUERY:
101 if (cmd_size < sizeof(videnc_cmd_status_query))
102 return -1;
103 break;
104 case VIDENC_CMD_RC_CFG:
105 if (cmd_size < sizeof(videnc_cmd_rc_cfg))
106 return -1;
107 break;
108 case VIDENC_CMD_INTRA_REFRESH:
109 if (cmd_size < sizeof(videnc_cmd_intra_refresh))
110 return -1;
111 break;
112 case VIDENC_CMD_DIGITAL_ZOOM:
113 if (cmd_size < sizeof(videnc_cmd_digital_zoom))
114 return -1;
115 break;
116 case VIDENC_CMD_DIS_CFG:
117 if (cmd_size < sizeof(videnc_cmd_dis_cfg))
118 return -1;
119 break;
120 case VIDENC_CMD_CFG:
121 if (cmd_size < sizeof(videnc_cmd_cfg))
122 return -1;
123 config_cmd = (videnc_cmd_cfg *)cmd_data;
124 x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
125 x_dimension = x_dimension*16;
126 y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
127 y_dimension = y_dimension * 16;
128 break;
129 case VIDENC_CMD_FRAME_START:
130 if (cmd_size < sizeof(videnc_cmd_frame_start))
131 return -1;
132 frame_cmd = (videnc_cmd_frame_start *)cmd_data;
133 luma_buf_size = x_dimension * y_dimension;
134 chroma_buf_size = luma_buf_size>>1;
135 frame_buf_size = luma_buf_size + chroma_buf_size;
136 ptr_to_high_low_short((void *)luma_buf_size,
137 &luma_buf_size_high,
138 &luma_buf_size_low);
139 ptr_to_high_low_short((void *)chroma_buf_size,
140 &chroma_buf_size_high,
141 &chroma_buf_size_low);
142 ptr_to_high_low_short((void *)frame_buf_size,
143 &frame_buf_size_high,
144 &frame_buf_size_low);
145 /* Address of raw Y data. */
146 if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
147 &frame_cmd->input_luma_addr_low,
148 luma_buf_size_high,
149 luma_buf_size_low,
150 module,
151 NULL, NULL))
152 return -1;
153 /* Address of raw CbCr data */
154 if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
155 &frame_cmd->input_chroma_addr_low,
156 chroma_buf_size_high,
157 chroma_buf_size_low,
158 module,
159 NULL, NULL))
160 return -1;
161 /* Reference VOP */
162 if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
163 &frame_cmd->ref_vop_buf_ptr_low,
164 frame_buf_size_high,
165 frame_buf_size_low,
166 module,
167 NULL, NULL))
168 return -1;
169 /* Encoded Packet Address */
170 if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
171 &frame_cmd->enc_pkt_buf_ptr_low,
172 frame_cmd->enc_pkt_buf_size_high,
173 frame_cmd->enc_pkt_buf_size_low,
174 module,
175 NULL, NULL))
176 return -1;
177 /* Unfiltered VOP Buffer Address */
178 if (pmem_fixup_high_low(
179 &frame_cmd->unfilt_recon_vop_buf_ptr_high,
180 &frame_cmd->unfilt_recon_vop_buf_ptr_low,
181 frame_buf_size_high,
182 frame_buf_size_low,
183 module,
184 NULL, NULL))
185 return -1;
186 /* Filtered VOP Buffer Address */
187 if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
188 &frame_cmd->filt_recon_vop_buf_ptr_low,
189 frame_buf_size_high,
190 frame_buf_size_low,
191 module,
192 NULL, NULL))
193 return -1;
194 break;
195 case VIDENC_CMD_DIS:
196 if (cmd_size < sizeof(videnc_cmd_dis))
197 return -1;
198 dis_cmd = (videnc_cmd_dis *)cmd_data;
199 luma_buf_size = x_dimension * y_dimension;
200 ptr_to_high_low_short((void *)luma_buf_size,
201 &luma_buf_size_high,
202 &luma_buf_size_low);
203 /* Prev VFE Luma Output Address */
204 if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
205 &dis_cmd->vfe_out_prev_luma_addr_low,
206 luma_buf_size_high,
207 luma_buf_size_low,
208 module,
209 NULL, NULL))
210 return -1;
211 break;
212 default:
213 printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
214 cmd_id);
215 return 0;
216 }
217
218 return 0;
219}
220
221
222int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
223 unsigned int queue_id, void *cmd_data,
224 size_t cmd_size)
225{
226 switch (queue_id) {
227 case QDSP_mpuVEncCmdQueue:
228 DLOG("\n");
229 return verify_venc_cmd(module, cmd_data, cmd_size);
230 default:
231 printk(KERN_INFO "unknown video queue %u\n", queue_id);
232 return 0;
233 }
234}
235
diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c
deleted file mode 100644
index 45f4c78ab6e7..000000000000
--- a/drivers/staging/dream/qdsp5/audio_aac.c
+++ /dev/null
@@ -1,1054 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audio_aac.c
2 *
3 * aac audio decoder device
4 *
5 * Copyright (C) 2008 Google, Inc.
6 * Copyright (C) 2008 HTC Corporation
7 * Copyright (c) 2008-2009 QUALCOMM USA, INC.
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/fs.h>
22#include <linux/miscdevice.h>
23#include <linux/uaccess.h>
24#include <linux/kthread.h>
25#include <linux/wait.h>
26#include <linux/dma-mapping.h>
27#include <linux/gfp.h>
28
29#include <linux/delay.h>
30
31#include <asm/atomic.h>
32#include <asm/ioctls.h>
33#include "audmgr.h"
34
35#include <mach/msm_adsp.h>
36#include <mach/msm_audio_aac.h>
37#include <mach/qdsp5/qdsp5audppcmdi.h>
38#include <mach/qdsp5/qdsp5audppmsg.h>
39#include <mach/qdsp5/qdsp5audplaycmdi.h>
40#include <mach/qdsp5/qdsp5audplaymsg.h>
41
42/* for queue ids - should be relative to module number*/
43#include "adsp.h"
44
45#ifdef DEBUG
46#define dprintk(format, arg...) \
47printk(KERN_DEBUG format, ## arg)
48#else
49#define dprintk(format, arg...) do {} while (0)
50#endif
51
52#define BUFSZ 32768
53#define DMASZ (BUFSZ * 2)
54
55#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
56#define AUDDEC_DEC_AAC 5
57
58#define PCM_BUFSZ_MIN 9600 /* Hold one stereo AAC frame */
59#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
60 but support 2 buffers currently */
61#define ROUTING_MODE_FTRT 1
62#define ROUTING_MODE_RT 2
63/* Decoder status received from AUDPPTASK */
64#define AUDPP_DEC_STATUS_SLEEP 0
65#define AUDPP_DEC_STATUS_INIT 1
66#define AUDPP_DEC_STATUS_CFG 2
67#define AUDPP_DEC_STATUS_PLAY 3
68
69struct buffer {
70 void *data;
71 unsigned size;
72 unsigned used; /* Input usage actual DSP produced PCM size */
73 unsigned addr;
74};
75
76struct audio {
77 struct buffer out[2];
78
79 spinlock_t dsp_lock;
80
81 uint8_t out_head;
82 uint8_t out_tail;
83 uint8_t out_needed; /* number of buffers the dsp is waiting for */
84
85 atomic_t out_bytes;
86
87 struct mutex lock;
88 struct mutex write_lock;
89 wait_queue_head_t write_wait;
90
91 /* Host PCM section */
92 struct buffer in[PCM_BUF_MAX_COUNT];
93 struct mutex read_lock;
94 wait_queue_head_t read_wait; /* Wait queue for read */
95 char *read_data; /* pointer to reader buffer */
96 dma_addr_t read_phys; /* physical address of reader buffer */
97 uint8_t read_next; /* index to input buffers to be read next */
98 uint8_t fill_next; /* index to buffer that DSP should be filling */
99 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
100 /* ---- End of Host PCM section */
101
102 struct msm_adsp_module *audplay;
103
104 /* configuration to use on next enable */
105 uint32_t out_sample_rate;
106 uint32_t out_channel_mode;
107 struct msm_audio_aac_config aac_config;
108 struct audmgr audmgr;
109
110 /* data allocated for various buffers */
111 char *data;
112 dma_addr_t phys;
113
114 int rflush; /* Read flush */
115 int wflush; /* Write flush */
116 int opened;
117 int enabled;
118 int running;
119 int stopped; /* set when stopped, cleared on flush */
120 int pcm_feedback;
121 int buf_refresh;
122
123 int reserved; /* A byte is being reserved */
124 char rsv_byte; /* Handle odd length user data */
125
126 unsigned volume;
127
128 uint16_t dec_id;
129 uint32_t read_ptr_offset;
130};
131
132static int auddec_dsp_config(struct audio *audio, int enable);
133static void audpp_cmd_cfg_adec_params(struct audio *audio);
134static void audpp_cmd_cfg_routing_mode(struct audio *audio);
135static void audplay_send_data(struct audio *audio, unsigned needed);
136static void audplay_config_hostpcm(struct audio *audio);
137static void audplay_buffer_refresh(struct audio *audio);
138static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
139
140/* must be called with audio->lock held */
141static int audio_enable(struct audio *audio)
142{
143 struct audmgr_config cfg;
144 int rc;
145
146 dprintk("audio_enable()\n");
147
148 if (audio->enabled)
149 return 0;
150
151 audio->out_tail = 0;
152 audio->out_needed = 0;
153
154 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
155 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
156 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
157 cfg.codec = RPC_AUD_DEF_CODEC_AAC;
158 cfg.snd_method = RPC_SND_METHOD_MIDI;
159
160 rc = audmgr_enable(&audio->audmgr, &cfg);
161 if (rc < 0)
162 return rc;
163
164 if (msm_adsp_enable(audio->audplay)) {
165 pr_err("audio: msm_adsp_enable(audplay) failed\n");
166 audmgr_disable(&audio->audmgr);
167 return -ENODEV;
168 }
169
170 if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
171 pr_err("audio: audpp_enable() failed\n");
172 msm_adsp_disable(audio->audplay);
173 audmgr_disable(&audio->audmgr);
174 return -ENODEV;
175 }
176 audio->enabled = 1;
177 return 0;
178}
179
180/* must be called with audio->lock held */
181static int audio_disable(struct audio *audio)
182{
183 dprintk("audio_disable()\n");
184 if (audio->enabled) {
185 audio->enabled = 0;
186 auddec_dsp_config(audio, 0);
187 wake_up(&audio->write_wait);
188 wake_up(&audio->read_wait);
189 msm_adsp_disable(audio->audplay);
190 audpp_disable(audio->dec_id, audio);
191 audmgr_disable(&audio->audmgr);
192 audio->out_needed = 0;
193 }
194 return 0;
195}
196
197/* ------------------- dsp --------------------- */
198static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
199{
200 uint8_t index;
201 unsigned long flags;
202
203 if (audio->rflush)
204 return;
205
206 spin_lock_irqsave(&audio->dsp_lock, flags);
207 for (index = 0; index < payload[1]; index++) {
208 if (audio->in[audio->fill_next].addr ==
209 payload[2 + index * 2]) {
210 dprintk("audio_update_pcm_buf_entry: in[%d] ready\n",
211 audio->fill_next);
212 audio->in[audio->fill_next].used =
213 payload[3 + index * 2];
214 if ((++audio->fill_next) == audio->pcm_buf_count)
215 audio->fill_next = 0;
216
217 } else {
218 pr_err
219 ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
220 , audio->in[audio->fill_next].addr,
221 payload[1 + index * 2]);
222 break;
223 }
224 }
225 if (audio->in[audio->fill_next].used == 0) {
226 audplay_buffer_refresh(audio);
227 } else {
228 dprintk("audio_update_pcm_buf_entry: read cannot keep up\n");
229 audio->buf_refresh = 1;
230 }
231 wake_up(&audio->read_wait);
232 spin_unlock_irqrestore(&audio->dsp_lock, flags);
233
234}
235
236static void audplay_dsp_event(void *data, unsigned id, size_t len,
237 void (*getevent) (void *ptr, size_t len))
238{
239 struct audio *audio = data;
240 uint32_t msg[28];
241 getevent(msg, sizeof(msg));
242
243 dprintk("audplay_dsp_event: msg_id=%x\n", id);
244
245 switch (id) {
246 case AUDPLAY_MSG_DEC_NEEDS_DATA:
247 audplay_send_data(audio, 1);
248 break;
249
250 case AUDPLAY_MSG_BUFFER_UPDATE:
251 audio_update_pcm_buf_entry(audio, msg);
252 break;
253
254 default:
255 pr_err("unexpected message from decoder \n");
256 }
257}
258
259static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
260{
261 struct audio *audio = private;
262
263 switch (id) {
264 case AUDPP_MSG_STATUS_MSG:{
265 unsigned status = msg[1];
266
267 switch (status) {
268 case AUDPP_DEC_STATUS_SLEEP:
269 dprintk("decoder status: sleep \n");
270 break;
271
272 case AUDPP_DEC_STATUS_INIT:
273 dprintk("decoder status: init \n");
274 audpp_cmd_cfg_routing_mode(audio);
275 break;
276
277 case AUDPP_DEC_STATUS_CFG:
278 dprintk("decoder status: cfg \n");
279 break;
280 case AUDPP_DEC_STATUS_PLAY:
281 dprintk("decoder status: play \n");
282 if (audio->pcm_feedback) {
283 audplay_config_hostpcm(audio);
284 audplay_buffer_refresh(audio);
285 }
286 break;
287 default:
288 pr_err("unknown decoder status \n");
289 }
290 break;
291 }
292 case AUDPP_MSG_CFG_MSG:
293 if (msg[0] == AUDPP_MSG_ENA_ENA) {
294 dprintk("audio_dsp_event: CFG_MSG ENABLE\n");
295 auddec_dsp_config(audio, 1);
296 audio->out_needed = 0;
297 audio->running = 1;
298 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
299 0);
300 audpp_avsync(audio->dec_id, 22050);
301 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
302 dprintk("audio_dsp_event: CFG_MSG DISABLE\n");
303 audpp_avsync(audio->dec_id, 0);
304 audio->running = 0;
305 } else {
306 pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
307 }
308 break;
309 case AUDPP_MSG_ROUTING_ACK:
310 dprintk("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
311 audpp_cmd_cfg_adec_params(audio);
312 break;
313
314 case AUDPP_MSG_FLUSH_ACK:
315 dprintk("%s: FLUSH_ACK\n", __func__);
316 audio->wflush = 0;
317 audio->rflush = 0;
318 if (audio->pcm_feedback)
319 audplay_buffer_refresh(audio);
320 break;
321
322 default:
323 pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
324 }
325
326}
327
328struct msm_adsp_ops audplay_adsp_ops_aac = {
329 .event = audplay_dsp_event,
330};
331
332#define audplay_send_queue0(audio, cmd, len) \
333 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
334 cmd, len)
335
336static int auddec_dsp_config(struct audio *audio, int enable)
337{
338 audpp_cmd_cfg_dec_type cmd;
339
340 memset(&cmd, 0, sizeof(cmd));
341 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
342 if (enable)
343 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
344 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC;
345 else
346 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
347
348 return audpp_send_queue1(&cmd, sizeof(cmd));
349}
350
351static void audpp_cmd_cfg_adec_params(struct audio *audio)
352{
353 audpp_cmd_cfg_adec_params_aac cmd;
354
355 memset(&cmd, 0, sizeof(cmd));
356 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
357 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN;
358 cmd.common.dec_id = audio->dec_id;
359 cmd.common.input_sampling_frequency = audio->out_sample_rate;
360 cmd.format = audio->aac_config.format;
361 cmd.audio_object = audio->aac_config.audio_object;
362 cmd.ep_config = audio->aac_config.ep_config;
363 cmd.aac_section_data_resilience_flag =
364 audio->aac_config.aac_section_data_resilience_flag;
365 cmd.aac_scalefactor_data_resilience_flag =
366 audio->aac_config.aac_scalefactor_data_resilience_flag;
367 cmd.aac_spectral_data_resilience_flag =
368 audio->aac_config.aac_spectral_data_resilience_flag;
369 cmd.sbr_on_flag = audio->aac_config.sbr_on_flag;
370 cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag;
371 cmd.channel_configuration = audio->aac_config.channel_configuration;
372
373 audpp_send_queue2(&cmd, sizeof(cmd));
374}
375
376static void audpp_cmd_cfg_routing_mode(struct audio *audio)
377{
378 struct audpp_cmd_routing_mode cmd;
379 dprintk("audpp_cmd_cfg_routing_mode()\n");
380 memset(&cmd, 0, sizeof(cmd));
381 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
382 cmd.object_number = audio->dec_id;
383 if (audio->pcm_feedback)
384 cmd.routing_mode = ROUTING_MODE_FTRT;
385 else
386 cmd.routing_mode = ROUTING_MODE_RT;
387
388 audpp_send_queue1(&cmd, sizeof(cmd));
389}
390
391static int audplay_dsp_send_data_avail(struct audio *audio,
392 unsigned idx, unsigned len)
393{
394 audplay_cmd_bitstream_data_avail cmd;
395
396 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
397 cmd.decoder_id = audio->dec_id;
398 cmd.buf_ptr = audio->out[idx].addr;
399 cmd.buf_size = len / 2;
400 cmd.partition_number = 0;
401 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
402}
403
404static void audplay_buffer_refresh(struct audio *audio)
405{
406 struct audplay_cmd_buffer_refresh refresh_cmd;
407
408 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
409 refresh_cmd.num_buffers = 1;
410 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
411 refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
412 (audio->in[audio->fill_next].size % 1024); /* AAC frame size */
413 refresh_cmd.buf_read_count = 0;
414 dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
415 refresh_cmd.buf0_address, refresh_cmd.buf0_length);
416 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
417}
418
419static void audplay_config_hostpcm(struct audio *audio)
420{
421 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
422
423 dprintk("audplay_config_hostpcm()\n");
424 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
425 cfg_cmd.max_buffers = audio->pcm_buf_count;
426 cfg_cmd.byte_swap = 0;
427 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
428 cfg_cmd.feedback_frequency = 1;
429 cfg_cmd.partition_number = 0;
430 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
431
432}
433
434static void audplay_send_data(struct audio *audio, unsigned needed)
435{
436 struct buffer *frame;
437 unsigned long flags;
438
439 spin_lock_irqsave(&audio->dsp_lock, flags);
440 if (!audio->running)
441 goto done;
442
443 if (needed && !audio->wflush) {
444 /* We were called from the callback because the DSP
445 * requested more data. Note that the DSP does want
446 * more data, and if a buffer was in-flight, mark it
447 * as available (since the DSP must now be done with
448 * it).
449 */
450 audio->out_needed = 1;
451 frame = audio->out + audio->out_tail;
452 if (frame->used == 0xffffffff) {
453 dprintk("frame %d free\n", audio->out_tail);
454 frame->used = 0;
455 audio->out_tail ^= 1;
456 wake_up(&audio->write_wait);
457 }
458 }
459
460 if (audio->out_needed) {
461 /* If the DSP currently wants data and we have a
462 * buffer available, we will send it and reset
463 * the needed flag. We'll mark the buffer as in-flight
464 * so that it won't be recycled until the next buffer
465 * is requested
466 */
467
468 frame = audio->out + audio->out_tail;
469 if (frame->used) {
470 BUG_ON(frame->used == 0xffffffff);
471/* printk("frame %d busy\n", audio->out_tail); */
472 audplay_dsp_send_data_avail(audio, audio->out_tail,
473 frame->used);
474 frame->used = 0xffffffff;
475 audio->out_needed = 0;
476 }
477 }
478 done:
479 spin_unlock_irqrestore(&audio->dsp_lock, flags);
480}
481
482/* ------------------- device --------------------- */
483
484static void audio_flush(struct audio *audio)
485{
486 audio->out[0].used = 0;
487 audio->out[1].used = 0;
488 audio->out_head = 0;
489 audio->out_tail = 0;
490 audio->reserved = 0;
491 audio->out_needed = 0;
492 atomic_set(&audio->out_bytes, 0);
493}
494
495static void audio_flush_pcm_buf(struct audio *audio)
496{
497 uint8_t index;
498
499 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
500 audio->in[index].used = 0;
501 audio->buf_refresh = 0;
502 audio->read_next = 0;
503 audio->fill_next = 0;
504}
505
506static int audaac_validate_usr_config(struct msm_audio_aac_config *config)
507{
508 int ret_val = -1;
509
510 if (config->format != AUDIO_AAC_FORMAT_ADTS &&
511 config->format != AUDIO_AAC_FORMAT_RAW &&
512 config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW &&
513 config->format != AUDIO_AAC_FORMAT_LOAS)
514 goto done;
515
516 if (config->audio_object != AUDIO_AAC_OBJECT_LC &&
517 config->audio_object != AUDIO_AAC_OBJECT_LTP &&
518 config->audio_object != AUDIO_AAC_OBJECT_ERLC)
519 goto done;
520
521 if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) {
522 if (config->ep_config > 3)
523 goto done;
524 if (config->aac_scalefactor_data_resilience_flag !=
525 AUDIO_AAC_SCA_DATA_RES_OFF &&
526 config->aac_scalefactor_data_resilience_flag !=
527 AUDIO_AAC_SCA_DATA_RES_ON)
528 goto done;
529 if (config->aac_section_data_resilience_flag !=
530 AUDIO_AAC_SEC_DATA_RES_OFF &&
531 config->aac_section_data_resilience_flag !=
532 AUDIO_AAC_SEC_DATA_RES_ON)
533 goto done;
534 if (config->aac_spectral_data_resilience_flag !=
535 AUDIO_AAC_SPEC_DATA_RES_OFF &&
536 config->aac_spectral_data_resilience_flag !=
537 AUDIO_AAC_SPEC_DATA_RES_ON)
538 goto done;
539 } else {
540 config->aac_section_data_resilience_flag =
541 AUDIO_AAC_SEC_DATA_RES_OFF;
542 config->aac_scalefactor_data_resilience_flag =
543 AUDIO_AAC_SCA_DATA_RES_OFF;
544 config->aac_spectral_data_resilience_flag =
545 AUDIO_AAC_SPEC_DATA_RES_OFF;
546 }
547
548 if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF &&
549 config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON)
550 goto done;
551
552 if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF &&
553 config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON)
554 goto done;
555
556 if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR)
557 goto done;
558
559 if (config->channel_configuration > 2)
560 goto done;
561
562 ret_val = 0;
563 done:
564 return ret_val;
565}
566
567static void audio_ioport_reset(struct audio *audio)
568{
569 /* Make sure read/write thread are free from
570 * sleep and knowing that system is not able
571 * to process io request at the moment
572 */
573 wake_up(&audio->write_wait);
574 mutex_lock(&audio->write_lock);
575 audio_flush(audio);
576 mutex_unlock(&audio->write_lock);
577 wake_up(&audio->read_wait);
578 mutex_lock(&audio->read_lock);
579 audio_flush_pcm_buf(audio);
580 mutex_unlock(&audio->read_lock);
581}
582
583static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
584{
585 struct audio *audio = file->private_data;
586 int rc = 0;
587
588 dprintk("audio_ioctl() cmd = %d\n", cmd);
589
590 if (cmd == AUDIO_GET_STATS) {
591 struct msm_audio_stats stats;
592 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
593 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
594 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
595 return -EFAULT;
596 return 0;
597 }
598 if (cmd == AUDIO_SET_VOLUME) {
599 unsigned long flags;
600 spin_lock_irqsave(&audio->dsp_lock, flags);
601 audio->volume = arg;
602 if (audio->running)
603 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
604 spin_unlock_irqrestore(&audio->dsp_lock, flags);
605 return 0;
606 }
607 mutex_lock(&audio->lock);
608 switch (cmd) {
609 case AUDIO_START:
610 rc = audio_enable(audio);
611 break;
612 case AUDIO_STOP:
613 rc = audio_disable(audio);
614 audio->stopped = 1;
615 audio_ioport_reset(audio);
616 audio->stopped = 0;
617 break;
618 case AUDIO_FLUSH:
619 dprintk("%s: AUDIO_FLUSH\n", __func__);
620 audio->rflush = 1;
621 audio->wflush = 1;
622 audio_ioport_reset(audio);
623 if (audio->running)
624 audpp_flush(audio->dec_id);
625 else {
626 audio->rflush = 0;
627 audio->wflush = 0;
628 }
629 break;
630
631 case AUDIO_SET_CONFIG:{
632 struct msm_audio_config config;
633
634 if (copy_from_user
635 (&config, (void *)arg, sizeof(config))) {
636 rc = -EFAULT;
637 break;
638 }
639
640 if (config.channel_count == 1) {
641 config.channel_count =
642 AUDPP_CMD_PCM_INTF_MONO_V;
643 } else if (config.channel_count == 2) {
644 config.channel_count =
645 AUDPP_CMD_PCM_INTF_STEREO_V;
646 } else {
647 rc = -EINVAL;
648 break;
649 }
650
651 audio->out_sample_rate = config.sample_rate;
652 audio->out_channel_mode = config.channel_count;
653 rc = 0;
654 break;
655 }
656 case AUDIO_GET_CONFIG:{
657 struct msm_audio_config config;
658 config.buffer_size = BUFSZ;
659 config.buffer_count = 2;
660 config.sample_rate = audio->out_sample_rate;
661 if (audio->out_channel_mode ==
662 AUDPP_CMD_PCM_INTF_MONO_V) {
663 config.channel_count = 1;
664 } else {
665 config.channel_count = 2;
666 }
667 config.unused[0] = 0;
668 config.unused[1] = 0;
669 config.unused[2] = 0;
670 config.unused[3] = 0;
671 if (copy_to_user((void *)arg, &config,
672 sizeof(config)))
673 rc = -EFAULT;
674 else
675 rc = 0;
676
677 break;
678 }
679 case AUDIO_GET_AAC_CONFIG:{
680 if (copy_to_user((void *)arg, &audio->aac_config,
681 sizeof(audio->aac_config)))
682 rc = -EFAULT;
683 else
684 rc = 0;
685 break;
686 }
687 case AUDIO_SET_AAC_CONFIG:{
688 struct msm_audio_aac_config usr_config;
689
690 if (copy_from_user
691 (&usr_config, (void *)arg,
692 sizeof(usr_config))) {
693 rc = -EFAULT;
694 break;
695 }
696
697 if (audaac_validate_usr_config(&usr_config) == 0) {
698 audio->aac_config = usr_config;
699 rc = 0;
700 } else
701 rc = -EINVAL;
702
703 break;
704 }
705 case AUDIO_GET_PCM_CONFIG:{
706 struct msm_audio_pcm_config config;
707 config.pcm_feedback = 0;
708 config.buffer_count = PCM_BUF_MAX_COUNT;
709 config.buffer_size = PCM_BUFSZ_MIN;
710 if (copy_to_user((void *)arg, &config,
711 sizeof(config)))
712 rc = -EFAULT;
713 else
714 rc = 0;
715 break;
716 }
717 case AUDIO_SET_PCM_CONFIG:{
718 struct msm_audio_pcm_config config;
719 if (copy_from_user
720 (&config, (void *)arg, sizeof(config))) {
721 rc = -EFAULT;
722 break;
723 }
724 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
725 (config.buffer_count == 1))
726 config.buffer_count = PCM_BUF_MAX_COUNT;
727
728 if (config.buffer_size < PCM_BUFSZ_MIN)
729 config.buffer_size = PCM_BUFSZ_MIN;
730
731 /* Check if pcm feedback is required */
732 if ((config.pcm_feedback) && (!audio->read_data)) {
733 dprintk("ioctl: allocate PCM buffer %d\n",
734 config.buffer_count *
735 config.buffer_size);
736 audio->read_data =
737 dma_alloc_coherent(NULL,
738 config.buffer_size *
739 config.buffer_count,
740 &audio->read_phys,
741 GFP_KERNEL);
742 if (!audio->read_data) {
743 pr_err("audio_aac: buf alloc fail\n");
744 rc = -1;
745 } else {
746 uint8_t index;
747 uint32_t offset = 0;
748 audio->pcm_feedback = 1;
749 audio->buf_refresh = 0;
750 audio->pcm_buf_count =
751 config.buffer_count;
752 audio->read_next = 0;
753 audio->fill_next = 0;
754
755 for (index = 0;
756 index < config.buffer_count;
757 index++) {
758 audio->in[index].data =
759 audio->read_data + offset;
760 audio->in[index].addr =
761 audio->read_phys + offset;
762 audio->in[index].size =
763 config.buffer_size;
764 audio->in[index].used = 0;
765 offset += config.buffer_size;
766 }
767 rc = 0;
768 }
769 } else {
770 rc = 0;
771 }
772 break;
773 }
774 case AUDIO_PAUSE:
775 dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
776 rc = audpp_pause(audio->dec_id, (int) arg);
777 break;
778 default:
779 rc = -EINVAL;
780 }
781 mutex_unlock(&audio->lock);
782 return rc;
783}
784
785static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
786 loff_t *pos)
787{
788 struct audio *audio = file->private_data;
789 const char __user *start = buf;
790 int rc = 0;
791
792 if (!audio->pcm_feedback)
793 return 0; /* PCM feedback is not enabled. Nothing to read */
794
795 mutex_lock(&audio->read_lock);
796 dprintk("audio_read() %d \n", count);
797 while (count > 0) {
798 rc = wait_event_interruptible(audio->read_wait,
799 (audio->in[audio->read_next].
800 used > 0) || (audio->stopped)
801 || (audio->rflush));
802
803 if (rc < 0)
804 break;
805
806 if (audio->stopped || audio->rflush) {
807 rc = -EBUSY;
808 break;
809 }
810
811 if (count < audio->in[audio->read_next].used) {
812 /* Read must happen in frame boundary. Since driver
813 does not know frame size, read count must be greater
814 or equal to size of PCM samples */
815 dprintk("audio_read: no partial frame done reading\n");
816 break;
817 } else {
818 dprintk("audio_read: read from in[%d]\n",
819 audio->read_next);
820 if (copy_to_user
821 (buf, audio->in[audio->read_next].data,
822 audio->in[audio->read_next].used)) {
823 pr_err("audio_read: invalid addr %x \n",
824 (unsigned int)buf);
825 rc = -EFAULT;
826 break;
827 }
828 count -= audio->in[audio->read_next].used;
829 buf += audio->in[audio->read_next].used;
830 audio->in[audio->read_next].used = 0;
831 if ((++audio->read_next) == audio->pcm_buf_count)
832 audio->read_next = 0;
833 if (audio->in[audio->read_next].used == 0)
834 break; /* No data ready at this moment
835 * Exit while loop to prevent
836 * output thread sleep too long
837 */
838 }
839 }
840
841 /* don't feed output buffer to HW decoder during flushing
842 * buffer refresh command will be sent once flush completes
843 * send buf refresh command here can confuse HW decoder
844 */
845 if (audio->buf_refresh && !audio->rflush) {
846 audio->buf_refresh = 0;
847 dprintk("audio_read: kick start pcm feedback again\n");
848 audplay_buffer_refresh(audio);
849 }
850
851 mutex_unlock(&audio->read_lock);
852
853 if (buf > start)
854 rc = buf - start;
855
856 dprintk("audio_read: read %d bytes\n", rc);
857 return rc;
858}
859
860static ssize_t audio_write(struct file *file, const char __user *buf,
861 size_t count, loff_t *pos)
862{
863 struct audio *audio = file->private_data;
864 const char __user *start = buf;
865 struct buffer *frame;
866 size_t xfer;
867 char *cpy_ptr;
868 int rc = 0;
869 unsigned dsize;
870
871 mutex_lock(&audio->write_lock);
872 while (count > 0) {
873 frame = audio->out + audio->out_head;
874 cpy_ptr = frame->data;
875 dsize = 0;
876 rc = wait_event_interruptible(audio->write_wait,
877 (frame->used == 0)
878 || (audio->stopped)
879 || (audio->wflush));
880 if (rc < 0)
881 break;
882 if (audio->stopped || audio->wflush) {
883 rc = -EBUSY;
884 break;
885 }
886
887 if (audio->reserved) {
888 dprintk("%s: append reserved byte %x\n",
889 __func__, audio->rsv_byte);
890 *cpy_ptr = audio->rsv_byte;
891 xfer = (count > (frame->size - 1)) ?
892 frame->size - 1 : count;
893 cpy_ptr++;
894 dsize = 1;
895 audio->reserved = 0;
896 } else
897 xfer = (count > frame->size) ? frame->size : count;
898
899 if (copy_from_user(cpy_ptr, buf, xfer)) {
900 rc = -EFAULT;
901 break;
902 }
903
904 dsize += xfer;
905 if (dsize & 1) {
906 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
907 dprintk("%s: odd length buf reserve last byte %x\n",
908 __func__, audio->rsv_byte);
909 audio->reserved = 1;
910 dsize--;
911 }
912 count -= xfer;
913 buf += xfer;
914
915 if (dsize > 0) {
916 audio->out_head ^= 1;
917 frame->used = dsize;
918 audplay_send_data(audio, 0);
919 }
920 }
921 mutex_unlock(&audio->write_lock);
922 if (buf > start)
923 return buf - start;
924 return rc;
925}
926
927static int audio_release(struct inode *inode, struct file *file)
928{
929 struct audio *audio = file->private_data;
930
931 dprintk("audio_release()\n");
932
933 mutex_lock(&audio->lock);
934 audio_disable(audio);
935 audio_flush(audio);
936 audio_flush_pcm_buf(audio);
937 msm_adsp_put(audio->audplay);
938 audio->audplay = NULL;
939 audio->opened = 0;
940 audio->reserved = 0;
941 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
942 audio->data = NULL;
943 if (audio->read_data != NULL) {
944 dma_free_coherent(NULL,
945 audio->in[0].size * audio->pcm_buf_count,
946 audio->read_data, audio->read_phys);
947 audio->read_data = NULL;
948 }
949 audio->pcm_feedback = 0;
950 mutex_unlock(&audio->lock);
951 return 0;
952}
953
954static struct audio the_aac_audio;
955
956static int audio_open(struct inode *inode, struct file *file)
957{
958 struct audio *audio = &the_aac_audio;
959 int rc;
960
961 mutex_lock(&audio->lock);
962
963 if (audio->opened) {
964 pr_err("audio: busy\n");
965 rc = -EBUSY;
966 goto done;
967 }
968
969 if (!audio->data) {
970 audio->data = dma_alloc_coherent(NULL, DMASZ,
971 &audio->phys, GFP_KERNEL);
972 if (!audio->data) {
973 pr_err("audio: could not allocate DMA buffers\n");
974 rc = -ENOMEM;
975 goto done;
976 }
977 }
978
979 rc = audmgr_open(&audio->audmgr);
980 if (rc)
981 goto done;
982
983 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
984 &audplay_adsp_ops_aac, audio);
985 if (rc) {
986 pr_err("audio: failed to get audplay0 dsp module\n");
987 goto done;
988 }
989 audio->out_sample_rate = 44100;
990 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
991 audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS;
992 audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC;
993 audio->aac_config.ep_config = 0;
994 audio->aac_config.aac_section_data_resilience_flag =
995 AUDIO_AAC_SEC_DATA_RES_OFF;
996 audio->aac_config.aac_scalefactor_data_resilience_flag =
997 AUDIO_AAC_SCA_DATA_RES_OFF;
998 audio->aac_config.aac_spectral_data_resilience_flag =
999 AUDIO_AAC_SPEC_DATA_RES_OFF;
1000 audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON;
1001 audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON;
1002 audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR;
1003 audio->aac_config.channel_configuration = 2;
1004 audio->dec_id = 0;
1005
1006 audio->out[0].data = audio->data + 0;
1007 audio->out[0].addr = audio->phys + 0;
1008 audio->out[0].size = BUFSZ;
1009
1010 audio->out[1].data = audio->data + BUFSZ;
1011 audio->out[1].addr = audio->phys + BUFSZ;
1012 audio->out[1].size = BUFSZ;
1013
1014 audio->volume = 0x2000; /* Q13 1.0 */
1015
1016 audio_flush(audio);
1017
1018 file->private_data = audio;
1019 audio->opened = 1;
1020 rc = 0;
1021done:
1022 mutex_unlock(&audio->lock);
1023 return rc;
1024}
1025
1026static struct file_operations audio_aac_fops = {
1027 .owner = THIS_MODULE,
1028 .open = audio_open,
1029 .release = audio_release,
1030 .read = audio_read,
1031 .write = audio_write,
1032 .unlocked_ioctl = audio_ioctl,
1033 .llseek = noop_llseek,
1034};
1035
1036struct miscdevice audio_aac_misc = {
1037 .minor = MISC_DYNAMIC_MINOR,
1038 .name = "msm_aac",
1039 .fops = &audio_aac_fops,
1040};
1041
1042static int __init audio_init(void)
1043{
1044 mutex_init(&the_aac_audio.lock);
1045 mutex_init(&the_aac_audio.write_lock);
1046 mutex_init(&the_aac_audio.read_lock);
1047 spin_lock_init(&the_aac_audio.dsp_lock);
1048 init_waitqueue_head(&the_aac_audio.write_wait);
1049 init_waitqueue_head(&the_aac_audio.read_wait);
1050 the_aac_audio.read_data = NULL;
1051 return misc_register(&audio_aac_misc);
1052}
1053
1054device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c
deleted file mode 100644
index 402bbc13281a..000000000000
--- a/drivers/staging/dream/qdsp5/audio_amrnb.c
+++ /dev/null
@@ -1,875 +0,0 @@
1/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c
2 *
3 * amrnb audio decoder device
4 *
5 * Copyright (c) 2008 QUALCOMM USA, INC.
6 *
7 * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
8 *
9 * Copyright (C) 2008 Google, Inc.
10 * Copyright (C) 2008 HTC Corporation
11 *
12 * All source code in this file is licensed under the following license except
13 * where indicated.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License version 2 as published
17 * by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 *
23 * See the GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, you can find it at http://www.fsf.org
26 */
27
28#include <linux/module.h>
29#include <linux/fs.h>
30#include <linux/miscdevice.h>
31#include <linux/uaccess.h>
32#include <linux/kthread.h>
33#include <linux/wait.h>
34#include <linux/dma-mapping.h>
35#include <linux/gfp.h>
36
37#include <linux/delay.h>
38
39#include <asm/atomic.h>
40#include <asm/ioctls.h>
41#include <mach/msm_adsp.h>
42#include <linux/msm_audio.h>
43#include "audmgr.h"
44
45#include <mach/qdsp5/qdsp5audppcmdi.h>
46#include <mach/qdsp5/qdsp5audppmsg.h>
47#include <mach/qdsp5/qdsp5audplaycmdi.h>
48#include <mach/qdsp5/qdsp5audplaymsg.h>
49
50/* for queue ids - should be relative to module number*/
51#include "adsp.h"
52
53#define DEBUG
54#ifdef DEBUG
55#define dprintk(format, arg...) \
56printk(KERN_DEBUG format, ## arg)
57#else
58#define dprintk(format, arg...) do {} while (0)
59#endif
60
61#define BUFSZ 1024 /* Hold minimum 700ms voice data */
62#define DMASZ (BUFSZ * 2)
63
64#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
65#define AUDDEC_DEC_AMRNB 10
66
67#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
68#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */
69#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
70 but support 2 buffers currently */
71#define ROUTING_MODE_FTRT 1
72#define ROUTING_MODE_RT 2
73/* Decoder status received from AUDPPTASK */
74#define AUDPP_DEC_STATUS_SLEEP 0
75#define AUDPP_DEC_STATUS_INIT 1
76#define AUDPP_DEC_STATUS_CFG 2
77#define AUDPP_DEC_STATUS_PLAY 3
78
79struct buffer {
80 void *data;
81 unsigned size;
82 unsigned used; /* Input usage actual DSP produced PCM size */
83 unsigned addr;
84};
85
86struct audio {
87 struct buffer out[2];
88
89 spinlock_t dsp_lock;
90
91 uint8_t out_head;
92 uint8_t out_tail;
93 uint8_t out_needed; /* number of buffers the dsp is waiting for */
94
95 atomic_t out_bytes;
96
97 struct mutex lock;
98 struct mutex write_lock;
99 wait_queue_head_t write_wait;
100
101 /* Host PCM section */
102 struct buffer in[PCM_BUF_MAX_COUNT];
103 struct mutex read_lock;
104 wait_queue_head_t read_wait; /* Wait queue for read */
105 char *read_data; /* pointer to reader buffer */
106 dma_addr_t read_phys; /* physical address of reader buffer */
107 uint8_t read_next; /* index to input buffers to be read next */
108 uint8_t fill_next; /* index to buffer that DSP should be filling */
109 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
110 /* ---- End of Host PCM section */
111
112 struct msm_adsp_module *audplay;
113
114 struct audmgr audmgr;
115
116 /* data allocated for various buffers */
117 char *data;
118 dma_addr_t phys;
119
120 uint8_t opened:1;
121 uint8_t enabled:1;
122 uint8_t running:1;
123 uint8_t stopped:1; /* set when stopped, cleared on flush */
124 uint8_t pcm_feedback:1;
125 uint8_t buf_refresh:1;
126
127 unsigned volume;
128
129 uint16_t dec_id;
130 uint32_t read_ptr_offset;
131};
132
133struct audpp_cmd_cfg_adec_params_amrnb {
134 audpp_cmd_cfg_adec_params_common common;
135 unsigned short stereo_cfg;
136} __attribute__((packed)) ;
137
138static int auddec_dsp_config(struct audio *audio, int enable);
139static void audpp_cmd_cfg_adec_params(struct audio *audio);
140static void audpp_cmd_cfg_routing_mode(struct audio *audio);
141static void audamrnb_send_data(struct audio *audio, unsigned needed);
142static void audamrnb_config_hostpcm(struct audio *audio);
143static void audamrnb_buffer_refresh(struct audio *audio);
144static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
145
146/* must be called with audio->lock held */
147static int audamrnb_enable(struct audio *audio)
148{
149 struct audmgr_config cfg;
150 int rc;
151
152 dprintk("audamrnb_enable()\n");
153
154 if (audio->enabled)
155 return 0;
156
157 audio->out_tail = 0;
158 audio->out_needed = 0;
159
160 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
161 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
162 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
163 cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB;
164 cfg.snd_method = RPC_SND_METHOD_MIDI;
165
166 rc = audmgr_enable(&audio->audmgr, &cfg);
167 if (rc < 0)
168 return rc;
169
170 if (msm_adsp_enable(audio->audplay)) {
171 pr_err("audio: msm_adsp_enable(audplay) failed\n");
172 audmgr_disable(&audio->audmgr);
173 return -ENODEV;
174 }
175
176 if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) {
177 pr_err("audio: audpp_enable() failed\n");
178 msm_adsp_disable(audio->audplay);
179 audmgr_disable(&audio->audmgr);
180 return -ENODEV;
181 }
182 audio->enabled = 1;
183 return 0;
184}
185
186/* must be called with audio->lock held */
187static int audamrnb_disable(struct audio *audio)
188{
189 dprintk("audamrnb_disable()\n");
190 if (audio->enabled) {
191 audio->enabled = 0;
192 auddec_dsp_config(audio, 0);
193 wake_up(&audio->write_wait);
194 wake_up(&audio->read_wait);
195 msm_adsp_disable(audio->audplay);
196 audpp_disable(audio->dec_id, audio);
197 audmgr_disable(&audio->audmgr);
198 audio->out_needed = 0;
199 }
200 return 0;
201}
202
203/* ------------------- dsp --------------------- */
204static void audamrnb_update_pcm_buf_entry(struct audio *audio,
205 uint32_t *payload)
206{
207 uint8_t index;
208 unsigned long flags;
209
210 spin_lock_irqsave(&audio->dsp_lock, flags);
211 for (index = 0; index < payload[1]; index++) {
212 if (audio->in[audio->fill_next].addr ==
213 payload[2 + index * 2]) {
214 dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n",
215 audio->fill_next);
216 audio->in[audio->fill_next].used =
217 payload[3 + index * 2];
218 if ((++audio->fill_next) == audio->pcm_buf_count)
219 audio->fill_next = 0;
220
221 } else {
222 pr_err
223 ("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n"
224 , audio->in[audio->fill_next].addr,
225 payload[1 + index * 2]);
226 break;
227 }
228 }
229 if (audio->in[audio->fill_next].used == 0) {
230 audamrnb_buffer_refresh(audio);
231 } else {
232 dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n");
233 audio->buf_refresh = 1;
234 }
235
236 spin_unlock_irqrestore(&audio->dsp_lock, flags);
237 wake_up(&audio->read_wait);
238}
239
240static void audplay_dsp_event(void *data, unsigned id, size_t len,
241 void (*getevent) (void *ptr, size_t len))
242{
243 struct audio *audio = data;
244 uint32_t msg[28];
245 getevent(msg, sizeof(msg));
246
247 dprintk("audplay_dsp_event: msg_id=%x\n", id);
248
249 switch (id) {
250 case AUDPLAY_MSG_DEC_NEEDS_DATA:
251 audamrnb_send_data(audio, 1);
252 break;
253
254 case AUDPLAY_MSG_BUFFER_UPDATE:
255 audamrnb_update_pcm_buf_entry(audio, msg);
256 break;
257
258 default:
259 pr_err("unexpected message from decoder \n");
260 }
261}
262
263static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg)
264{
265 struct audio *audio = private;
266
267 switch (id) {
268 case AUDPP_MSG_STATUS_MSG:{
269 unsigned status = msg[1];
270
271 switch (status) {
272 case AUDPP_DEC_STATUS_SLEEP:
273 dprintk("decoder status: sleep \n");
274 break;
275
276 case AUDPP_DEC_STATUS_INIT:
277 dprintk("decoder status: init \n");
278 audpp_cmd_cfg_routing_mode(audio);
279 break;
280
281 case AUDPP_DEC_STATUS_CFG:
282 dprintk("decoder status: cfg \n");
283 break;
284 case AUDPP_DEC_STATUS_PLAY:
285 dprintk("decoder status: play \n");
286 if (audio->pcm_feedback) {
287 audamrnb_config_hostpcm(audio);
288 audamrnb_buffer_refresh(audio);
289 }
290 break;
291 default:
292 pr_err("unknown decoder status \n");
293 break;
294 }
295 break;
296 }
297 case AUDPP_MSG_CFG_MSG:
298 if (msg[0] == AUDPP_MSG_ENA_ENA) {
299 dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n");
300 auddec_dsp_config(audio, 1);
301 audio->out_needed = 0;
302 audio->running = 1;
303 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
304 0);
305 audpp_avsync(audio->dec_id, 22050);
306 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
307 dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n");
308 audpp_avsync(audio->dec_id, 0);
309 audio->running = 0;
310 } else {
311 pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]);
312 }
313 break;
314 case AUDPP_MSG_ROUTING_ACK:
315 dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
316 audpp_cmd_cfg_adec_params(audio);
317 break;
318
319 default:
320 pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id);
321 }
322
323}
324
325struct msm_adsp_ops audplay_adsp_ops_amrnb = {
326 .event = audplay_dsp_event,
327};
328
329#define audplay_send_queue0(audio, cmd, len) \
330 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
331 cmd, len)
332
333static int auddec_dsp_config(struct audio *audio, int enable)
334{
335 audpp_cmd_cfg_dec_type cmd;
336
337 memset(&cmd, 0, sizeof(cmd));
338 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
339 if (enable)
340 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
341 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB;
342 else
343 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
344
345 return audpp_send_queue1(&cmd, sizeof(cmd));
346}
347
348static void audpp_cmd_cfg_adec_params(struct audio *audio)
349{
350 struct audpp_cmd_cfg_adec_params_amrnb cmd;
351
352 memset(&cmd, 0, sizeof(cmd));
353 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
354 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
355 cmd.common.dec_id = audio->dec_id;
356 cmd.common.input_sampling_frequency = 8000;
357 cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
358
359 audpp_send_queue2(&cmd, sizeof(cmd));
360}
361
362static void audpp_cmd_cfg_routing_mode(struct audio *audio)
363{
364 struct audpp_cmd_routing_mode cmd;
365 dprintk("audpp_cmd_cfg_routing_mode()\n");
366 memset(&cmd, 0, sizeof(cmd));
367 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
368 cmd.object_number = audio->dec_id;
369 if (audio->pcm_feedback)
370 cmd.routing_mode = ROUTING_MODE_FTRT;
371 else
372 cmd.routing_mode = ROUTING_MODE_RT;
373
374 audpp_send_queue1(&cmd, sizeof(cmd));
375}
376
377static int audplay_dsp_send_data_avail(struct audio *audio,
378 unsigned idx, unsigned len)
379{
380 audplay_cmd_bitstream_data_avail cmd;
381
382 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
383 cmd.decoder_id = audio->dec_id;
384 cmd.buf_ptr = audio->out[idx].addr;
385 cmd.buf_size = len / 2;
386 cmd.partition_number = 0;
387 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
388}
389
390static void audamrnb_buffer_refresh(struct audio *audio)
391{
392 struct audplay_cmd_buffer_refresh refresh_cmd;
393
394 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
395 refresh_cmd.num_buffers = 1;
396 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
397 refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
398 (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ);
399 refresh_cmd.buf_read_count = 0;
400 dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
401 refresh_cmd.buf0_address, refresh_cmd.buf0_length);
402 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
403}
404
405static void audamrnb_config_hostpcm(struct audio *audio)
406{
407 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
408
409 dprintk("audamrnb_config_hostpcm()\n");
410 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
411 cfg_cmd.max_buffers = audio->pcm_buf_count;
412 cfg_cmd.byte_swap = 0;
413 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
414 cfg_cmd.feedback_frequency = 1;
415 cfg_cmd.partition_number = 0;
416 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
417
418}
419
420static void audamrnb_send_data(struct audio *audio, unsigned needed)
421{
422 struct buffer *frame;
423 unsigned long flags;
424
425 spin_lock_irqsave(&audio->dsp_lock, flags);
426 if (!audio->running)
427 goto done;
428
429 if (needed) {
430 /* We were called from the callback because the DSP
431 * requested more data. Note that the DSP does want
432 * more data, and if a buffer was in-flight, mark it
433 * as available (since the DSP must now be done with
434 * it).
435 */
436 audio->out_needed = 1;
437 frame = audio->out + audio->out_tail;
438 if (frame->used == 0xffffffff) {
439 frame->used = 0;
440 audio->out_tail ^= 1;
441 wake_up(&audio->write_wait);
442 }
443 }
444
445 if (audio->out_needed) {
446 /* If the DSP currently wants data and we have a
447 * buffer available, we will send it and reset
448 * the needed flag. We'll mark the buffer as in-flight
449 * so that it won't be recycled until the next buffer
450 * is requested
451 */
452
453 frame = audio->out + audio->out_tail;
454 if (frame->used) {
455 BUG_ON(frame->used == 0xffffffff);
456/* printk("frame %d busy\n", audio->out_tail); */
457 audplay_dsp_send_data_avail(audio, audio->out_tail,
458 frame->used);
459 frame->used = 0xffffffff;
460 audio->out_needed = 0;
461 }
462 }
463 done:
464 spin_unlock_irqrestore(&audio->dsp_lock, flags);
465}
466
467/* ------------------- device --------------------- */
468
469static void audamrnb_flush(struct audio *audio)
470{
471 audio->out[0].used = 0;
472 audio->out[1].used = 0;
473 audio->out_head = 0;
474 audio->out_tail = 0;
475 audio->stopped = 0;
476 atomic_set(&audio->out_bytes, 0);
477}
478
479static void audamrnb_flush_pcm_buf(struct audio *audio)
480{
481 uint8_t index;
482
483 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
484 audio->in[index].used = 0;
485
486 audio->read_next = 0;
487 audio->fill_next = 0;
488}
489
490static long audamrnb_ioctl(struct file *file, unsigned int cmd,
491 unsigned long arg)
492{
493 struct audio *audio = file->private_data;
494 int rc = 0;
495
496 dprintk("audamrnb_ioctl() cmd = %d\n", cmd);
497
498 if (cmd == AUDIO_GET_STATS) {
499 struct msm_audio_stats stats;
500 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
501 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
502 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
503 return -EFAULT;
504 return 0;
505 }
506 if (cmd == AUDIO_SET_VOLUME) {
507 unsigned long flags;
508 spin_lock_irqsave(&audio->dsp_lock, flags);
509 audio->volume = arg;
510 if (audio->running)
511 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
512 spin_unlock_irqrestore(&audio->dsp_lock, flags);
513 return 0;
514 }
515 mutex_lock(&audio->lock);
516 switch (cmd) {
517 case AUDIO_START:
518 rc = audamrnb_enable(audio);
519 break;
520 case AUDIO_STOP:
521 rc = audamrnb_disable(audio);
522 audio->stopped = 1;
523 break;
524 case AUDIO_FLUSH:
525 if (audio->stopped) {
526 /* Make sure we're stopped and we wake any threads
527 * that might be blocked holding the write_lock.
528 * While audio->stopped write threads will always
529 * exit immediately.
530 */
531 wake_up(&audio->write_wait);
532 mutex_lock(&audio->write_lock);
533 audamrnb_flush(audio);
534 mutex_unlock(&audio->write_lock);
535 wake_up(&audio->read_wait);
536 mutex_lock(&audio->read_lock);
537 audamrnb_flush_pcm_buf(audio);
538 mutex_unlock(&audio->read_lock);
539 break;
540 }
541
542 case AUDIO_SET_CONFIG:{
543 dprintk("AUDIO_SET_CONFIG not applicable \n");
544 break;
545 }
546 case AUDIO_GET_CONFIG:{
547 struct msm_audio_config config;
548 config.buffer_size = BUFSZ;
549 config.buffer_count = 2;
550 config.sample_rate = 8000;
551 config.channel_count = 1;
552 config.unused[0] = 0;
553 config.unused[1] = 0;
554 config.unused[2] = 0;
555 config.unused[3] = 0;
556 if (copy_to_user((void *)arg, &config,
557 sizeof(config)))
558 rc = -EFAULT;
559 else
560 rc = 0;
561
562 break;
563 }
564 case AUDIO_GET_PCM_CONFIG:{
565 struct msm_audio_pcm_config config;
566 config.pcm_feedback = 0;
567 config.buffer_count = PCM_BUF_MAX_COUNT;
568 config.buffer_size = PCM_BUFSZ_MIN;
569 if (copy_to_user((void *)arg, &config,
570 sizeof(config)))
571 rc = -EFAULT;
572 else
573 rc = 0;
574 break;
575 }
576 case AUDIO_SET_PCM_CONFIG:{
577 struct msm_audio_pcm_config config;
578 if (copy_from_user
579 (&config, (void *)arg, sizeof(config))) {
580 rc = -EFAULT;
581 break;
582 }
583 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
584 (config.buffer_count == 1))
585 config.buffer_count = PCM_BUF_MAX_COUNT;
586
587 if (config.buffer_size < PCM_BUFSZ_MIN)
588 config.buffer_size = PCM_BUFSZ_MIN;
589
590 /* Check if pcm feedback is required */
591 if ((config.pcm_feedback) && (!audio->read_data)) {
592 dprintk("audamrnb_ioctl: allocate PCM buf %d\n",
593 config.buffer_count *
594 config.buffer_size);
595 audio->read_data =
596 dma_alloc_coherent(NULL,
597 config.buffer_size *
598 config.buffer_count,
599 &audio->read_phys,
600 GFP_KERNEL);
601 if (!audio->read_data) {
602 pr_err("audamrnb_ioctl: no mem for pcm buf\n");
603 rc = -1;
604 } else {
605 uint8_t index;
606 uint32_t offset = 0;
607 audio->pcm_feedback = 1;
608 audio->buf_refresh = 0;
609 audio->pcm_buf_count =
610 config.buffer_count;
611 audio->read_next = 0;
612 audio->fill_next = 0;
613
614 for (index = 0;
615 index < config.buffer_count; index++) {
616 audio->in[index].data =
617 audio->read_data + offset;
618 audio->in[index].addr =
619 audio->read_phys + offset;
620 audio->in[index].size =
621 config.buffer_size;
622 audio->in[index].used = 0;
623 offset += config.buffer_size;
624 }
625 rc = 0;
626 }
627 } else {
628 rc = 0;
629 }
630 break;
631 }
632 default:
633 rc = -EINVAL;
634 }
635 mutex_unlock(&audio->lock);
636 return rc;
637}
638
639static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count,
640 loff_t *pos)
641{
642 struct audio *audio = file->private_data;
643 const char __user *start = buf;
644 int rc = 0;
645
646 if (!audio->pcm_feedback)
647 return 0; /* PCM feedback is not enabled. Nothing to read */
648
649 mutex_lock(&audio->read_lock);
650 dprintk("audamrnb_read() %d \n", count);
651 while (count > 0) {
652 rc = wait_event_interruptible(audio->read_wait,
653 (audio->in[audio->read_next].
654 used > 0) || (audio->stopped));
655
656 if (rc < 0)
657 break;
658
659 if (audio->stopped) {
660 rc = -EBUSY;
661 break;
662 }
663
664 if (count < audio->in[audio->read_next].used) {
665 /* Read must happen in frame boundary. Since driver does
666 * not know frame size, read count must be greater or
667 * equal to size of PCM samples
668 */
669 dprintk("audamrnb_read:read stop - partial frame\n");
670 break;
671 } else {
672 dprintk("audamrnb_read: read from in[%d]\n",
673 audio->read_next);
674 if (copy_to_user
675 (buf, audio->in[audio->read_next].data,
676 audio->in[audio->read_next].used)) {
677 pr_err("audamrnb_read: invalid addr %x \n",
678 (unsigned int)buf);
679 rc = -EFAULT;
680 break;
681 }
682 count -= audio->in[audio->read_next].used;
683 buf += audio->in[audio->read_next].used;
684 audio->in[audio->read_next].used = 0;
685 if ((++audio->read_next) == audio->pcm_buf_count)
686 audio->read_next = 0;
687 }
688 }
689
690 if (audio->buf_refresh) {
691 audio->buf_refresh = 0;
692 dprintk("audamrnb_read: kick start pcm feedback again\n");
693 audamrnb_buffer_refresh(audio);
694 }
695
696 mutex_unlock(&audio->read_lock);
697
698 if (buf > start)
699 rc = buf - start;
700
701 dprintk("audamrnb_read: read %d bytes\n", rc);
702 return rc;
703}
704
705static ssize_t audamrnb_write(struct file *file, const char __user *buf,
706 size_t count, loff_t *pos)
707{
708 struct audio *audio = file->private_data;
709 const char __user *start = buf;
710 struct buffer *frame;
711 size_t xfer;
712 int rc = 0;
713
714 if (count & 1)
715 return -EINVAL;
716 dprintk("audamrnb_write() \n");
717 mutex_lock(&audio->write_lock);
718 while (count > 0) {
719 frame = audio->out + audio->out_head;
720 rc = wait_event_interruptible(audio->write_wait,
721 (frame->used == 0)
722 || (audio->stopped));
723 dprintk("audamrnb_write() buffer available\n");
724 if (rc < 0)
725 break;
726 if (audio->stopped) {
727 rc = -EBUSY;
728 break;
729 }
730 xfer = (count > frame->size) ? frame->size : count;
731 if (copy_from_user(frame->data, buf, xfer)) {
732 rc = -EFAULT;
733 break;
734 }
735
736 frame->used = xfer;
737 audio->out_head ^= 1;
738 count -= xfer;
739 buf += xfer;
740
741 audamrnb_send_data(audio, 0);
742
743 }
744 mutex_unlock(&audio->write_lock);
745 if (buf > start)
746 return buf - start;
747 return rc;
748}
749
750static int audamrnb_release(struct inode *inode, struct file *file)
751{
752 struct audio *audio = file->private_data;
753
754 dprintk("audamrnb_release()\n");
755
756 mutex_lock(&audio->lock);
757 audamrnb_disable(audio);
758 audamrnb_flush(audio);
759 audamrnb_flush_pcm_buf(audio);
760 msm_adsp_put(audio->audplay);
761 audio->audplay = NULL;
762 audio->opened = 0;
763 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
764 audio->data = NULL;
765 if (audio->read_data != NULL) {
766 dma_free_coherent(NULL,
767 audio->in[0].size * audio->pcm_buf_count,
768 audio->read_data, audio->read_phys);
769 audio->read_data = NULL;
770 }
771 audio->pcm_feedback = 0;
772 mutex_unlock(&audio->lock);
773 return 0;
774}
775
776static struct audio the_amrnb_audio;
777
778static int audamrnb_open(struct inode *inode, struct file *file)
779{
780 struct audio *audio = &the_amrnb_audio;
781 int rc;
782
783 mutex_lock(&audio->lock);
784
785 if (audio->opened) {
786 pr_err("audio: busy\n");
787 rc = -EBUSY;
788 goto done;
789 }
790
791 if (!audio->data) {
792 audio->data = dma_alloc_coherent(NULL, DMASZ,
793 &audio->phys, GFP_KERNEL);
794 if (!audio->data) {
795 pr_err("audio: could not allocate DMA buffers\n");
796 rc = -ENOMEM;
797 goto done;
798 }
799 }
800
801 rc = audmgr_open(&audio->audmgr);
802 if (rc)
803 goto done;
804
805 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
806 &audplay_adsp_ops_amrnb, audio);
807 if (rc) {
808 pr_err("audio: failed to get audplay0 dsp module\n");
809 audmgr_disable(&audio->audmgr);
810 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
811 audio->data = NULL;
812 goto done;
813 }
814
815 audio->dec_id = 0;
816
817 audio->out[0].data = audio->data + 0;
818 audio->out[0].addr = audio->phys + 0;
819 audio->out[0].size = BUFSZ;
820
821 audio->out[1].data = audio->data + BUFSZ;
822 audio->out[1].addr = audio->phys + BUFSZ;
823 audio->out[1].size = BUFSZ;
824
825 audio->volume = 0x2000; /* Q13 1.0 */
826
827 audamrnb_flush(audio);
828
829 file->private_data = audio;
830 audio->opened = 1;
831 rc = 0;
832done:
833 mutex_unlock(&audio->lock);
834 return rc;
835}
836
837static struct file_operations audio_amrnb_fops = {
838 .owner = THIS_MODULE,
839 .open = audamrnb_open,
840 .release = audamrnb_release,
841 .read = audamrnb_read,
842 .write = audamrnb_write,
843 .unlocked_ioctl = audamrnb_ioctl,
844 .llseek = noop_llseek,
845};
846
847struct miscdevice audio_amrnb_misc = {
848 .minor = MISC_DYNAMIC_MINOR,
849 .name = "msm_amrnb",
850 .fops = &audio_amrnb_fops,
851};
852
853static int __init audamrnb_init(void)
854{
855 mutex_init(&the_amrnb_audio.lock);
856 mutex_init(&the_amrnb_audio.write_lock);
857 mutex_init(&the_amrnb_audio.read_lock);
858 spin_lock_init(&the_amrnb_audio.dsp_lock);
859 init_waitqueue_head(&the_amrnb_audio.write_wait);
860 init_waitqueue_head(&the_amrnb_audio.read_wait);
861 the_amrnb_audio.read_data = NULL;
862 return misc_register(&audio_amrnb_misc);
863}
864
865static void __exit audamrnb_exit(void)
866{
867 misc_deregister(&audio_amrnb_misc);
868}
869
870module_init(audamrnb_init);
871module_exit(audamrnb_exit);
872
873MODULE_DESCRIPTION("MSM AMR-NB driver");
874MODULE_LICENSE("GPL v2");
875MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c
deleted file mode 100644
index 24a892647370..000000000000
--- a/drivers/staging/dream/qdsp5/audio_evrc.c
+++ /dev/null
@@ -1,847 +0,0 @@
1/* arch/arm/mach-msm/audio_evrc.c
2 *
3 * Copyright (c) 2008 QUALCOMM USA, INC.
4 *
5 * This code also borrows from audio_aac.c, which is
6 * Copyright (C) 2008 Google, Inc.
7 * Copyright (C) 2008 HTC Corporation
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you can find it at http://www.fsf.org.
20 */
21
22#include <linux/module.h>
23#include <linux/fs.h>
24#include <linux/miscdevice.h>
25#include <linux/uaccess.h>
26#include <linux/kthread.h>
27#include <linux/wait.h>
28#include <linux/dma-mapping.h>
29#include <linux/delay.h>
30#include <linux/gfp.h>
31
32#include <asm/atomic.h>
33#include <asm/ioctls.h>
34#include <mach/msm_adsp.h>
35#include <linux/msm_audio.h>
36#include "audmgr.h"
37
38#include <mach/qdsp5/qdsp5audppcmdi.h>
39#include <mach/qdsp5/qdsp5audppmsg.h>
40#include <mach/qdsp5/qdsp5audplaycmdi.h>
41#include <mach/qdsp5/qdsp5audplaymsg.h>
42
43#include "adsp.h"
44
45#ifdef DEBUG
46#define dprintk(format, arg...) \
47 printk(KERN_DEBUG format, ## arg)
48#else
49#define dprintk(format, arg...) do {} while (0)
50#endif
51
52/* Hold 30 packets of 24 bytes each*/
53#define BUFSZ 720
54#define DMASZ (BUFSZ * 2)
55
56#define AUDDEC_DEC_EVRC 12
57
58#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
59#define PCM_BUF_MAX_COUNT 5
60/* DSP only accepts 5 buffers at most
61 * but support 2 buffers currently
62 */
63#define EVRC_DECODED_FRSZ 320 /* EVRC 20ms 8KHz mono PCM size */
64
65#define ROUTING_MODE_FTRT 1
66#define ROUTING_MODE_RT 2
67/* Decoder status received from AUDPPTASK */
68#define AUDPP_DEC_STATUS_SLEEP 0
69#define AUDPP_DEC_STATUS_INIT 1
70#define AUDPP_DEC_STATUS_CFG 2
71#define AUDPP_DEC_STATUS_PLAY 3
72
73struct buffer {
74 void *data;
75 unsigned size;
76 unsigned used; /* Input usage actual DSP produced PCM size */
77 unsigned addr;
78};
79
80struct audio {
81 struct buffer out[2];
82
83 spinlock_t dsp_lock;
84
85 uint8_t out_head;
86 uint8_t out_tail;
87 uint8_t out_needed; /* number of buffers the dsp is waiting for */
88
89 atomic_t out_bytes;
90
91 struct mutex lock;
92 struct mutex write_lock;
93 wait_queue_head_t write_wait;
94
95 /* Host PCM section */
96 struct buffer in[PCM_BUF_MAX_COUNT];
97 struct mutex read_lock;
98 wait_queue_head_t read_wait; /* Wait queue for read */
99 char *read_data; /* pointer to reader buffer */
100 dma_addr_t read_phys; /* physical address of reader buffer */
101 uint8_t read_next; /* index to input buffers to be read next */
102 uint8_t fill_next; /* index to buffer that DSP should be filling */
103 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
104 /* ---- End of Host PCM section */
105
106 struct msm_adsp_module *audplay;
107 struct audmgr audmgr;
108
109 /* data allocated for various buffers */
110 char *data;
111 dma_addr_t phys;
112
113 uint8_t opened:1;
114 uint8_t enabled:1;
115 uint8_t running:1;
116 uint8_t stopped:1; /* set when stopped, cleared on flush */
117 uint8_t pcm_feedback:1;
118 uint8_t buf_refresh:1;
119
120 unsigned volume;
121 uint16_t dec_id;
122 uint32_t read_ptr_offset;
123};
124static struct audio the_evrc_audio;
125
126static int auddec_dsp_config(struct audio *audio, int enable);
127static void audpp_cmd_cfg_adec_params(struct audio *audio);
128static void audpp_cmd_cfg_routing_mode(struct audio *audio);
129static void audevrc_send_data(struct audio *audio, unsigned needed);
130static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
131static void audevrc_config_hostpcm(struct audio *audio);
132static void audevrc_buffer_refresh(struct audio *audio);
133
134/* must be called with audio->lock held */
135static int audevrc_enable(struct audio *audio)
136{
137 struct audmgr_config cfg;
138 int rc;
139
140 if (audio->enabled)
141 return 0;
142
143 audio->out_tail = 0;
144 audio->out_needed = 0;
145
146 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
147 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
148 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
149 cfg.codec = RPC_AUD_DEF_CODEC_EVRC;
150 cfg.snd_method = RPC_SND_METHOD_MIDI;
151
152 rc = audmgr_enable(&audio->audmgr, &cfg);
153 if (rc < 0)
154 return rc;
155
156 if (msm_adsp_enable(audio->audplay)) {
157 pr_err("audio: msm_adsp_enable(audplay) failed\n");
158 audmgr_disable(&audio->audmgr);
159 return -ENODEV;
160 }
161
162 if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) {
163 pr_err("audio: audpp_enable() failed\n");
164 msm_adsp_disable(audio->audplay);
165 audmgr_disable(&audio->audmgr);
166 return -ENODEV;
167 }
168 audio->enabled = 1;
169 return 0;
170}
171
172/* must be called with audio->lock held */
173static int audevrc_disable(struct audio *audio)
174{
175 if (audio->enabled) {
176 audio->enabled = 0;
177 auddec_dsp_config(audio, 0);
178 wake_up(&audio->write_wait);
179 wake_up(&audio->read_wait);
180 msm_adsp_disable(audio->audplay);
181 audpp_disable(audio->dec_id, audio);
182 audmgr_disable(&audio->audmgr);
183 audio->out_needed = 0;
184 }
185 return 0;
186}
187
188/* ------------------- dsp --------------------- */
189
190static void audevrc_update_pcm_buf_entry(struct audio *audio,
191 uint32_t *payload)
192{
193 uint8_t index;
194 unsigned long flags;
195
196 spin_lock_irqsave(&audio->dsp_lock, flags);
197 for (index = 0; index < payload[1]; index++) {
198 if (audio->in[audio->fill_next].addr
199 == payload[2 + index * 2]) {
200 dprintk("audevrc_update_pcm_buf_entry: in[%d] ready\n",
201 audio->fill_next);
202 audio->in[audio->fill_next].used =
203 payload[3 + index * 2];
204 if ((++audio->fill_next) == audio->pcm_buf_count)
205 audio->fill_next = 0;
206
207 } else {
208 pr_err
209 ("audevrc_update_pcm_buf_entry: expected=%x ret=%x\n",
210 audio->in[audio->fill_next].addr,
211 payload[1 + index * 2]);
212 break;
213 }
214 }
215 if (audio->in[audio->fill_next].used == 0) {
216 audevrc_buffer_refresh(audio);
217 } else {
218 dprintk("audevrc_update_pcm_buf_entry: read cannot keep up\n");
219 audio->buf_refresh = 1;
220 }
221
222 spin_unlock_irqrestore(&audio->dsp_lock, flags);
223 wake_up(&audio->read_wait);
224}
225
226static void audplay_dsp_event(void *data, unsigned id, size_t len,
227 void (*getevent) (void *ptr, size_t len))
228{
229 struct audio *audio = data;
230 uint32_t msg[28];
231 getevent(msg, sizeof(msg));
232
233 dprintk("audplay_dsp_event: msg_id=%x\n", id);
234 switch (id) {
235 case AUDPLAY_MSG_DEC_NEEDS_DATA:
236 audevrc_send_data(audio, 1);
237 break;
238 case AUDPLAY_MSG_BUFFER_UPDATE:
239 dprintk("audevrc_update_pcm_buf_entry:======> \n");
240 audevrc_update_pcm_buf_entry(audio, msg);
241 break;
242 default:
243 pr_err("unexpected message from decoder \n");
244 }
245}
246
247static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg)
248{
249 struct audio *audio = private;
250
251 switch (id) {
252 case AUDPP_MSG_STATUS_MSG:{
253 unsigned status = msg[1];
254
255 switch (status) {
256 case AUDPP_DEC_STATUS_SLEEP:
257 dprintk("decoder status: sleep \n");
258 break;
259
260 case AUDPP_DEC_STATUS_INIT:
261 dprintk("decoder status: init \n");
262 audpp_cmd_cfg_routing_mode(audio);
263 break;
264
265 case AUDPP_DEC_STATUS_CFG:
266 dprintk("decoder status: cfg \n");
267 break;
268 case AUDPP_DEC_STATUS_PLAY:
269 dprintk("decoder status: play \n");
270 if (audio->pcm_feedback) {
271 audevrc_config_hostpcm(audio);
272 audevrc_buffer_refresh(audio);
273 }
274 break;
275 default:
276 pr_err("unknown decoder status \n");
277 }
278 break;
279 }
280 case AUDPP_MSG_CFG_MSG:
281 if (msg[0] == AUDPP_MSG_ENA_ENA) {
282 dprintk("audevrc_dsp_event: CFG_MSG ENABLE\n");
283 auddec_dsp_config(audio, 1);
284 audio->out_needed = 0;
285 audio->running = 1;
286 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
287 0);
288 audpp_avsync(audio->dec_id, 22050);
289 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
290 dprintk("audevrc_dsp_event: CFG_MSG DISABLE\n");
291 audpp_avsync(audio->dec_id, 0);
292 audio->running = 0;
293 } else {
294 pr_err("audevrc_dsp_event: CFG_MSG %d?\n", msg[0]);
295 }
296 break;
297 case AUDPP_MSG_ROUTING_ACK:
298 dprintk("audevrc_dsp_event: ROUTING_ACK\n");
299 audpp_cmd_cfg_adec_params(audio);
300 break;
301
302 default:
303 pr_err("audevrc_dsp_event: UNKNOWN (%d)\n", id);
304 }
305
306}
307
308struct msm_adsp_ops audplay_adsp_ops_evrc = {
309 .event = audplay_dsp_event,
310};
311
312#define audplay_send_queue0(audio, cmd, len) \
313 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
314 cmd, len)
315
316static int auddec_dsp_config(struct audio *audio, int enable)
317{
318 audpp_cmd_cfg_dec_type cmd;
319
320 memset(&cmd, 0, sizeof(cmd));
321 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
322 if (enable)
323 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
324 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC;
325 else
326 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
327
328 return audpp_send_queue1(&cmd, sizeof(cmd));
329}
330
331static void audpp_cmd_cfg_adec_params(struct audio *audio)
332{
333 struct audpp_cmd_cfg_adec_params_evrc cmd;
334
335 memset(&cmd, 0, sizeof(cmd));
336 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
337 cmd.common.length = sizeof(cmd);
338 cmd.common.dec_id = audio->dec_id;
339 cmd.common.input_sampling_frequency = 8000;
340 cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
341
342 audpp_send_queue2(&cmd, sizeof(cmd));
343}
344
345static void audpp_cmd_cfg_routing_mode(struct audio *audio)
346{
347 struct audpp_cmd_routing_mode cmd;
348 dprintk("audpp_cmd_cfg_routing_mode()\n");
349 memset(&cmd, 0, sizeof(cmd));
350 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
351 cmd.object_number = audio->dec_id;
352 if (audio->pcm_feedback)
353 cmd.routing_mode = ROUTING_MODE_FTRT;
354 else
355 cmd.routing_mode = ROUTING_MODE_RT;
356
357 audpp_send_queue1(&cmd, sizeof(cmd));
358}
359
360static int audplay_dsp_send_data_avail(struct audio *audio,
361 unsigned idx, unsigned len)
362{
363 audplay_cmd_bitstream_data_avail cmd;
364
365 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
366 cmd.decoder_id = audio->dec_id;
367 cmd.buf_ptr = audio->out[idx].addr;
368 cmd.buf_size = len / 2;
369 cmd.partition_number = 0;
370 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
371}
372
373static void audevrc_buffer_refresh(struct audio *audio)
374{
375 struct audplay_cmd_buffer_refresh refresh_cmd;
376
377 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
378 refresh_cmd.num_buffers = 1;
379 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
380 refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
381
382 refresh_cmd.buf_read_count = 0;
383 dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
384 refresh_cmd.buf0_address, refresh_cmd.buf0_length);
385 audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
386}
387
388static void audevrc_config_hostpcm(struct audio *audio)
389{
390 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
391
392 dprintk("audevrc_config_hostpcm()\n");
393 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
394 cfg_cmd.max_buffers = 1;
395 cfg_cmd.byte_swap = 0;
396 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
397 cfg_cmd.feedback_frequency = 1;
398 cfg_cmd.partition_number = 0;
399 audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
400
401}
402
403static void audevrc_send_data(struct audio *audio, unsigned needed)
404{
405 struct buffer *frame;
406 unsigned long flags;
407
408 spin_lock_irqsave(&audio->dsp_lock, flags);
409 if (!audio->running)
410 goto done;
411
412 if (needed) {
413 /* We were called from the callback because the DSP
414 * requested more data. Note that the DSP does want
415 * more data, and if a buffer was in-flight, mark it
416 * as available (since the DSP must now be done with
417 * it).
418 */
419 audio->out_needed = 1;
420 frame = audio->out + audio->out_tail;
421 if (frame->used == 0xffffffff) {
422 dprintk("frame %d free\n", audio->out_tail);
423 frame->used = 0;
424 audio->out_tail ^= 1;
425 wake_up(&audio->write_wait);
426 }
427 }
428
429 if (audio->out_needed) {
430 /* If the DSP currently wants data and we have a
431 * buffer available, we will send it and reset
432 * the needed flag. We'll mark the buffer as in-flight
433 * so that it won't be recycled until the next buffer
434 * is requested
435 */
436
437 frame = audio->out + audio->out_tail;
438 if (frame->used) {
439 BUG_ON(frame->used == 0xffffffff);
440 dprintk("frame %d busy\n", audio->out_tail);
441 audplay_dsp_send_data_avail(audio, audio->out_tail,
442 frame->used);
443 frame->used = 0xffffffff;
444 audio->out_needed = 0;
445 }
446 }
447done:
448 spin_unlock_irqrestore(&audio->dsp_lock, flags);
449}
450
451/* ------------------- device --------------------- */
452
453static void audevrc_flush(struct audio *audio)
454{
455 audio->out[0].used = 0;
456 audio->out[1].used = 0;
457 audio->out_head = 0;
458 audio->out_tail = 0;
459 audio->stopped = 0;
460 atomic_set(&audio->out_bytes, 0);
461}
462
463static void audevrc_flush_pcm_buf(struct audio *audio)
464{
465 uint8_t index;
466
467 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
468 audio->in[index].used = 0;
469
470 audio->read_next = 0;
471 audio->fill_next = 0;
472}
473
474static long audevrc_ioctl(struct file *file, unsigned int cmd,
475 unsigned long arg)
476{
477 struct audio *audio = file->private_data;
478 int rc = 0;
479
480 dprintk("audevrc_ioctl() cmd = %d\n", cmd);
481
482 if (cmd == AUDIO_GET_STATS) {
483 struct msm_audio_stats stats;
484 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
485 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
486 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
487 return -EFAULT;
488 return 0;
489 }
490 if (cmd == AUDIO_SET_VOLUME) {
491 unsigned long flags;
492 spin_lock_irqsave(&audio->dsp_lock, flags);
493 audio->volume = arg;
494 if (audio->running)
495 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
496 spin_unlock_irqrestore(&audio->dsp_lock, flags);
497 return 0;
498 }
499 mutex_lock(&audio->lock);
500 switch (cmd) {
501 case AUDIO_START:
502 rc = audevrc_enable(audio);
503 break;
504 case AUDIO_STOP:
505 rc = audevrc_disable(audio);
506 audio->stopped = 1;
507 break;
508 case AUDIO_SET_CONFIG:{
509 dprintk("AUDIO_SET_CONFIG not applicable \n");
510 break;
511 }
512 case AUDIO_GET_CONFIG:{
513 struct msm_audio_config config;
514 config.buffer_size = BUFSZ;
515 config.buffer_count = 2;
516 config.sample_rate = 8000;
517 config.channel_count = 1;
518 config.unused[0] = 0;
519 config.unused[1] = 0;
520 config.unused[2] = 0;
521 config.unused[3] = 0;
522 if (copy_to_user((void *)arg, &config, sizeof(config)))
523 rc = -EFAULT;
524 else
525 rc = 0;
526 break;
527 }
528 case AUDIO_GET_PCM_CONFIG:{
529 struct msm_audio_pcm_config config;
530 config.pcm_feedback = 0;
531 config.buffer_count = PCM_BUF_MAX_COUNT;
532 config.buffer_size = PCM_BUFSZ_MIN;
533 if (copy_to_user((void *)arg, &config, sizeof(config)))
534 rc = -EFAULT;
535 else
536 rc = 0;
537 break;
538 }
539 case AUDIO_SET_PCM_CONFIG:{
540 struct msm_audio_pcm_config config;
541 if (copy_from_user
542 (&config, (void *)arg, sizeof(config))) {
543 rc = -EFAULT;
544 break;
545 }
546 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
547 (config.buffer_count == 1))
548 config.buffer_count = PCM_BUF_MAX_COUNT;
549
550 if (config.buffer_size < PCM_BUFSZ_MIN)
551 config.buffer_size = PCM_BUFSZ_MIN;
552
553 /* Check if pcm feedback is required */
554 if ((config.pcm_feedback) && (!audio->read_data)) {
555 dprintk("audevrc_ioctl: allocate PCM buf %d\n",
556 config.buffer_count *
557 config.buffer_size);
558 audio->read_data =
559 dma_alloc_coherent(NULL,
560 config.buffer_size *
561 config.buffer_count,
562 &audio->read_phys,
563 GFP_KERNEL);
564 if (!audio->read_data) {
565 pr_err
566 ("audevrc_ioctl: no mem for pcm buf\n");
567 rc = -1;
568 } else {
569 uint8_t index;
570 uint32_t offset = 0;
571 audio->pcm_feedback = 1;
572 audio->buf_refresh = 0;
573 audio->pcm_buf_count =
574 config.buffer_count;
575 audio->read_next = 0;
576 audio->fill_next = 0;
577
578 for (index = 0;
579 index < config.buffer_count;
580 index++) {
581 audio->in[index].data =
582 audio->read_data + offset;
583 audio->in[index].addr =
584 audio->read_phys + offset;
585 audio->in[index].size =
586 config.buffer_size;
587 audio->in[index].used = 0;
588 offset += config.buffer_size;
589 }
590 rc = 0;
591 }
592 } else {
593 rc = 0;
594 }
595 break;
596 }
597 case AUDIO_PAUSE:
598 dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
599 rc = audpp_pause(audio->dec_id, (int) arg);
600 break;
601 default:
602 rc = -EINVAL;
603 }
604 mutex_unlock(&audio->lock);
605 return rc;
606}
607
608static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count,
609 loff_t *pos)
610{
611 struct audio *audio = file->private_data;
612 const char __user *start = buf;
613 int rc = 0;
614 if (!audio->pcm_feedback) {
615 return 0;
616 /* PCM feedback is not enabled. Nothing to read */
617 }
618 mutex_lock(&audio->read_lock);
619 dprintk("audevrc_read() \n");
620 while (count > 0) {
621 rc = wait_event_interruptible(audio->read_wait,
622 (audio->in[audio->read_next].
623 used > 0) || (audio->stopped));
624 dprintk("audevrc_read() wait terminated \n");
625 if (rc < 0)
626 break;
627 if (audio->stopped) {
628 rc = -EBUSY;
629 break;
630 }
631 if (count < audio->in[audio->read_next].used) {
632 /* Read must happen in frame boundary. Since driver does
633 * not know frame size, read count must be greater or
634 * equal to size of PCM samples
635 */
636 dprintk("audevrc_read:read stop - partial frame\n");
637 break;
638 } else {
639 dprintk("audevrc_read: read from in[%d]\n",
640 audio->read_next);
641 if (copy_to_user
642 (buf, audio->in[audio->read_next].data,
643 audio->in[audio->read_next].used)) {
644 pr_err("audevrc_read: invalid addr %x \n",
645 (unsigned int)buf);
646 rc = -EFAULT;
647 break;
648 }
649 count -= audio->in[audio->read_next].used;
650 buf += audio->in[audio->read_next].used;
651 audio->in[audio->read_next].used = 0;
652 if ((++audio->read_next) == audio->pcm_buf_count)
653 audio->read_next = 0;
654 if (audio->in[audio->read_next].used == 0)
655 break; /* No data ready at this moment
656 * Exit while loop to prevent
657 * output thread sleep too long
658 */
659
660 }
661 }
662 if (audio->buf_refresh) {
663 audio->buf_refresh = 0;
664 dprintk("audevrc_read: kick start pcm feedback again\n");
665 audevrc_buffer_refresh(audio);
666 }
667 mutex_unlock(&audio->read_lock);
668 if (buf > start)
669 rc = buf - start;
670 dprintk("audevrc_read: read %d bytes\n", rc);
671 return rc;
672}
673
674static ssize_t audevrc_write(struct file *file, const char __user *buf,
675 size_t count, loff_t *pos)
676{
677 struct audio *audio = file->private_data;
678 const char __user *start = buf;
679 struct buffer *frame;
680 size_t xfer;
681 int rc = 0;
682
683 if (count & 1)
684 return -EINVAL;
685 mutex_lock(&audio->write_lock);
686 dprintk("audevrc_write() \n");
687 while (count > 0) {
688 frame = audio->out + audio->out_head;
689 rc = wait_event_interruptible(audio->write_wait,
690 (frame->used == 0)
691 || (audio->stopped));
692 if (rc < 0)
693 break;
694 if (audio->stopped) {
695 rc = -EBUSY;
696 break;
697 }
698 xfer = (count > frame->size) ? frame->size : count;
699 if (copy_from_user(frame->data, buf, xfer)) {
700 rc = -EFAULT;
701 break;
702 }
703
704 frame->used = xfer;
705 audio->out_head ^= 1;
706 count -= xfer;
707 buf += xfer;
708
709 audevrc_send_data(audio, 0);
710
711 }
712 mutex_unlock(&audio->write_lock);
713 if (buf > start)
714 return buf - start;
715 return rc;
716}
717
718static int audevrc_release(struct inode *inode, struct file *file)
719{
720 struct audio *audio = file->private_data;
721
722 dprintk("audevrc_release()\n");
723
724 mutex_lock(&audio->lock);
725 audevrc_disable(audio);
726 audevrc_flush(audio);
727 audevrc_flush_pcm_buf(audio);
728 msm_adsp_put(audio->audplay);
729 audio->audplay = NULL;
730 audio->opened = 0;
731 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
732 audio->data = NULL;
733 if (audio->read_data != NULL) {
734 dma_free_coherent(NULL,
735 audio->in[0].size * audio->pcm_buf_count,
736 audio->read_data, audio->read_phys);
737 audio->read_data = NULL;
738 }
739 audio->pcm_feedback = 0;
740 mutex_unlock(&audio->lock);
741 return 0;
742}
743
744static struct audio the_evrc_audio;
745
746static int audevrc_open(struct inode *inode, struct file *file)
747{
748 struct audio *audio = &the_evrc_audio;
749 int rc;
750
751 if (audio->opened) {
752 pr_err("audio: busy\n");
753 return -EBUSY;
754 }
755
756 /* Acquire Lock */
757 mutex_lock(&audio->lock);
758
759 if (!audio->data) {
760 audio->data = dma_alloc_coherent(NULL, DMASZ,
761 &audio->phys, GFP_KERNEL);
762 if (!audio->data) {
763 pr_err("audio: could not allocate DMA buffers\n");
764 rc = -ENOMEM;
765 goto dma_fail;
766 }
767 }
768
769 rc = audmgr_open(&audio->audmgr);
770 if (rc)
771 goto audmgr_fail;
772
773 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
774 &audplay_adsp_ops_evrc, audio);
775 if (rc) {
776 pr_err("audio: failed to get audplay0 dsp module\n");
777 goto adsp_fail;
778 }
779
780 audio->dec_id = 0;
781
782 audio->out[0].data = audio->data + 0;
783 audio->out[0].addr = audio->phys + 0;
784 audio->out[0].size = BUFSZ;
785
786 audio->out[1].data = audio->data + BUFSZ;
787 audio->out[1].addr = audio->phys + BUFSZ;
788 audio->out[1].size = BUFSZ;
789
790 audio->volume = 0x3FFF;
791
792 audevrc_flush(audio);
793
794 audio->opened = 1;
795 file->private_data = audio;
796
797 mutex_unlock(&audio->lock);
798 return rc;
799
800adsp_fail:
801 audmgr_close(&audio->audmgr);
802audmgr_fail:
803 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
804dma_fail:
805 mutex_unlock(&audio->lock);
806 return rc;
807}
808
809static struct file_operations audio_evrc_fops = {
810 .owner = THIS_MODULE,
811 .open = audevrc_open,
812 .release = audevrc_release,
813 .read = audevrc_read,
814 .write = audevrc_write,
815 .unlocked_ioctl = audevrc_ioctl,
816 .llseek = noop_llseek,
817};
818
819struct miscdevice audio_evrc_misc = {
820 .minor = MISC_DYNAMIC_MINOR,
821 .name = "msm_evrc",
822 .fops = &audio_evrc_fops,
823};
824
825static int __init audevrc_init(void)
826{
827 mutex_init(&the_evrc_audio.lock);
828 mutex_init(&the_evrc_audio.write_lock);
829 mutex_init(&the_evrc_audio.read_lock);
830 spin_lock_init(&the_evrc_audio.dsp_lock);
831 init_waitqueue_head(&the_evrc_audio.write_wait);
832 init_waitqueue_head(&the_evrc_audio.read_wait);
833 the_evrc_audio.read_data = NULL;
834 return misc_register(&audio_evrc_misc);
835}
836
837static void __exit audevrc_exit(void)
838{
839 misc_deregister(&audio_evrc_misc);
840}
841
842module_init(audevrc_init);
843module_exit(audevrc_exit);
844
845MODULE_DESCRIPTION("MSM EVRC driver");
846MODULE_LICENSE("GPL v2");
847MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c
deleted file mode 100644
index b51fa096074e..000000000000
--- a/drivers/staging/dream/qdsp5/audio_in.c
+++ /dev/null
@@ -1,970 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audio_in.c
2 *
3 * pcm audio input device
4 *
5 * Copyright (C) 2008 Google, Inc.
6 * Copyright (C) 2008 HTC Corporation
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/fs.h>
21#include <linux/miscdevice.h>
22#include <linux/uaccess.h>
23#include <linux/kthread.h>
24#include <linux/wait.h>
25#include <linux/dma-mapping.h>
26#include <linux/gfp.h>
27
28#include <linux/delay.h>
29
30#include <linux/msm_audio.h>
31
32#include <asm/atomic.h>
33#include <asm/ioctls.h>
34#include <mach/msm_adsp.h>
35#include <mach/msm_rpcrouter.h>
36
37#include "audmgr.h"
38
39#include <mach/qdsp5/qdsp5audpreproccmdi.h>
40#include <mach/qdsp5/qdsp5audpreprocmsg.h>
41#include <mach/qdsp5/qdsp5audreccmdi.h>
42#include <mach/qdsp5/qdsp5audrecmsg.h>
43
44/* for queue ids - should be relative to module number*/
45#include "adsp.h"
46
47/* FRAME_NUM must be a power of two */
48#define FRAME_NUM (8)
49#define FRAME_SIZE (2052 * 2)
50#define MONO_DATA_SIZE (2048)
51#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2)
52#define DMASZ (FRAME_SIZE * FRAME_NUM)
53
54#define AGC_PARAM_SIZE (20)
55#define NS_PARAM_SIZE (6)
56#define IIR_PARAM_SIZE (48)
57#define DEBUG (0)
58
59#define AGC_ENABLE 0x0001
60#define NS_ENABLE 0x0002
61#define IIR_ENABLE 0x0004
62
63struct tx_agc_config {
64 uint16_t agc_params[AGC_PARAM_SIZE];
65};
66
67struct ns_config {
68 uint16_t ns_params[NS_PARAM_SIZE];
69};
70
71struct tx_iir_filter {
72 uint16_t num_bands;
73 uint16_t iir_params[IIR_PARAM_SIZE];
74};
75
76struct audpre_cmd_iir_config_type {
77 uint16_t cmd_id;
78 uint16_t active_flag;
79 uint16_t num_bands;
80 uint16_t iir_params[IIR_PARAM_SIZE];
81};
82
83struct buffer {
84 void *data;
85 uint32_t size;
86 uint32_t read;
87 uint32_t addr;
88};
89
90struct audio_in {
91 struct buffer in[FRAME_NUM];
92
93 spinlock_t dsp_lock;
94
95 atomic_t in_bytes;
96
97 struct mutex lock;
98 struct mutex read_lock;
99 wait_queue_head_t wait;
100
101 struct msm_adsp_module *audpre;
102 struct msm_adsp_module *audrec;
103
104 /* configuration to use on next enable */
105 uint32_t samp_rate;
106 uint32_t channel_mode;
107 uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
108 uint32_t type; /* 0 for PCM ,1 for AAC */
109 uint32_t dsp_cnt;
110 uint32_t in_head; /* next buffer dsp will write */
111 uint32_t in_tail; /* next buffer read() will read */
112 uint32_t in_count; /* number of buffers available to read() */
113
114 unsigned short samp_rate_index;
115
116 struct audmgr audmgr;
117
118 /* data allocated for various buffers */
119 char *data;
120 dma_addr_t phys;
121
122 int opened;
123 int enabled;
124 int running;
125 int stopped; /* set when stopped, cleared on flush */
126
127 /* audpre settings */
128 int agc_enable;
129 struct tx_agc_config agc;
130
131 int ns_enable;
132 struct ns_config ns;
133
134 int iir_enable;
135 struct tx_iir_filter iir;
136};
137
138static int audio_in_dsp_enable(struct audio_in *audio, int enable);
139static int audio_in_encoder_config(struct audio_in *audio);
140static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
141static void audio_flush(struct audio_in *audio);
142static int audio_dsp_set_agc(struct audio_in *audio);
143static int audio_dsp_set_ns(struct audio_in *audio);
144static int audio_dsp_set_tx_iir(struct audio_in *audio);
145
146static unsigned convert_dsp_samp_index(unsigned index)
147{
148 switch (index) {
149 case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000;
150 case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100;
151 case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000;
152 case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000;
153 case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050;
154 case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000;
155 case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000;
156 case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025;
157 case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000;
158 default: return AUDREC_CMD_SAMP_RATE_INDX_11025;
159 }
160}
161
162static unsigned convert_samp_rate(unsigned hz)
163{
164 switch (hz) {
165 case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
166 case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
167 case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
168 case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
169 case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
170 case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
171 case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
172 case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
173 case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000;
174 default: return RPC_AUD_DEF_SAMPLE_RATE_11025;
175 }
176}
177
178static unsigned convert_samp_index(unsigned index)
179{
180 switch (index) {
181 case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000;
182 case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100;
183 case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000;
184 case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000;
185 case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050;
186 case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000;
187 case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000;
188 case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025;
189 case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000;
190 default: return 11025;
191 }
192}
193
194/* must be called with audio->lock held */
195static int audio_in_enable(struct audio_in *audio)
196{
197 struct audmgr_config cfg;
198 int rc;
199
200 if (audio->enabled)
201 return 0;
202
203 cfg.tx_rate = audio->samp_rate;
204 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
205 cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
206 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
207 cfg.codec = RPC_AUD_DEF_CODEC_PCM;
208 else
209 cfg.codec = RPC_AUD_DEF_CODEC_AAC;
210 cfg.snd_method = RPC_SND_METHOD_MIDI;
211
212 rc = audmgr_enable(&audio->audmgr, &cfg);
213 if (rc < 0)
214 return rc;
215
216 if (msm_adsp_enable(audio->audpre)) {
217 pr_err("audrec: msm_adsp_enable(audpre) failed\n");
218 return -ENODEV;
219 }
220 if (msm_adsp_enable(audio->audrec)) {
221 pr_err("audrec: msm_adsp_enable(audrec) failed\n");
222 return -ENODEV;
223 }
224
225 audio->enabled = 1;
226 audio_in_dsp_enable(audio, 1);
227
228 return 0;
229}
230
231/* must be called with audio->lock held */
232static int audio_in_disable(struct audio_in *audio)
233{
234 if (audio->enabled) {
235 audio->enabled = 0;
236
237 audio_in_dsp_enable(audio, 0);
238
239 wake_up(&audio->wait);
240
241 msm_adsp_disable(audio->audrec);
242 msm_adsp_disable(audio->audpre);
243 audmgr_disable(&audio->audmgr);
244 }
245 return 0;
246}
247
248/* ------------------- dsp --------------------- */
249static void audpre_dsp_event(void *data, unsigned id, size_t len,
250 void (*getevent)(void *ptr, size_t len))
251{
252 uint16_t msg[2];
253 getevent(msg, sizeof(msg));
254
255 switch (id) {
256 case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
257 pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
258 break;
259 case AUDPREPROC_MSG_ERROR_MSG_ID:
260 pr_info("audpre: err_index %d\n", msg[0]);
261 break;
262 default:
263 pr_err("audpre: unknown event %d\n", id);
264 }
265}
266
267struct audio_frame {
268 uint16_t count_low;
269 uint16_t count_high;
270 uint16_t bytes;
271 uint16_t unknown;
272 unsigned char samples[];
273} __attribute__((packed));
274
275static void audio_in_get_dsp_frames(struct audio_in *audio)
276{
277 struct audio_frame *frame;
278 uint32_t index;
279 unsigned long flags;
280
281 index = audio->in_head;
282
283 /* XXX check for bogus frame size? */
284
285 frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame));
286
287 spin_lock_irqsave(&audio->dsp_lock, flags);
288 audio->in[index].size = frame->bytes;
289
290 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
291
292 /* If overflow, move the tail index foward. */
293 if (audio->in_head == audio->in_tail)
294 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
295 else
296 audio->in_count++;
297
298 audio_dsp_read_buffer(audio, audio->dsp_cnt++);
299 spin_unlock_irqrestore(&audio->dsp_lock, flags);
300
301 wake_up(&audio->wait);
302}
303
304static void audrec_dsp_event(void *data, unsigned id, size_t len,
305 void (*getevent)(void *ptr, size_t len))
306{
307 struct audio_in *audio = data;
308 uint16_t msg[3];
309 getevent(msg, sizeof(msg));
310
311 switch (id) {
312 case AUDREC_MSG_CMD_CFG_DONE_MSG:
313 if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) {
314 if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) {
315 pr_info("audpre: CFG ENABLED\n");
316 audio_dsp_set_agc(audio);
317 audio_dsp_set_ns(audio);
318 audio_dsp_set_tx_iir(audio);
319 audio_in_encoder_config(audio);
320 } else {
321 pr_info("audrec: CFG SLEEP\n");
322 audio->running = 0;
323 }
324 } else {
325 pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]);
326 }
327 break;
328 case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
329 pr_info("audrec: PARAM CFG DONE\n");
330 audio->running = 1;
331 break;
332 }
333 case AUDREC_MSG_FATAL_ERR_MSG:
334 pr_err("audrec: ERROR %x\n", msg[0]);
335 break;
336 case AUDREC_MSG_PACKET_READY_MSG:
337/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */
338 audio_in_get_dsp_frames(audio);
339 break;
340 default:
341 pr_err("audrec: unknown event %d\n", id);
342 }
343}
344
345struct msm_adsp_ops audpre_adsp_ops = {
346 .event = audpre_dsp_event,
347};
348
349struct msm_adsp_ops audrec_adsp_ops = {
350 .event = audrec_dsp_event,
351};
352
353
354#define audio_send_queue_pre(audio, cmd, len) \
355 msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
356#define audio_send_queue_recbs(audio, cmd, len) \
357 msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len)
358#define audio_send_queue_rec(audio, cmd, len) \
359 msm_adsp_write(audio->audrec, \
360 QDSP_uPAudRecCmdQueue, cmd, len)
361
362static int audio_dsp_set_agc(struct audio_in *audio)
363{
364 audpreproc_cmd_cfg_agc_params cmd;
365
366 memset(&cmd, 0, sizeof(cmd));
367 cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
368
369 if (audio->agc_enable) {
370 /* cmd.tx_agc_param_mask = 0xFE00 from sample code */
371 cmd.tx_agc_param_mask =
372 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) |
373 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) |
374 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) |
375 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) |
376 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) |
377 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) |
378 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
379 cmd.tx_agc_enable_flag =
380 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
381 memcpy(&cmd.static_gain, &audio->agc.agc_params[0],
382 sizeof(uint16_t) * 6);
383 /* cmd.param_mask = 0xFFF0 from sample code */
384 cmd.param_mask =
385 (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) |
386 (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) |
387 (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) |
388 (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) |
389 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) |
390 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) |
391 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) |
392 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) |
393 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) |
394 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) |
395 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) |
396 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK);
397 memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6],
398 sizeof(uint16_t) * 14);
399
400 } else {
401 cmd.tx_agc_param_mask =
402 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
403 cmd.tx_agc_enable_flag =
404 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
405 }
406#if DEBUG
407 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
408 pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask);
409 pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag);
410 pr_info("static_gain = 0x%04x\n", cmd.static_gain);
411 pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag);
412 pr_info("expander_th = 0x%04x\n", cmd.expander_th);
413 pr_info("expander_slope = 0x%04x\n", cmd.expander_slope);
414 pr_info("compressor_th = 0x%04x\n", cmd.compressor_th);
415 pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope);
416 pr_info("param_mask = 0x%04x\n", cmd.param_mask);
417 pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk);
418 pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down);
419 pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up);
420 pr_info("aig_max = 0x%04x\n", cmd.aig_max);
421 pr_info("aig_min = 0x%04x\n", cmd.aig_min);
422 pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek);
423 pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast);
424 pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow);
425 pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw);
426 pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw);
427 pr_info("delay = 0x%04x\n", cmd.delay);
428 pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw);
429 pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw);
430 pr_info("rms_tav = 0x%04x\n", cmd.rms_tav);
431#endif
432 return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
433}
434
435static int audio_dsp_set_ns(struct audio_in *audio)
436{
437 audpreproc_cmd_cfg_ns_params cmd;
438
439 memset(&cmd, 0, sizeof(cmd));
440 cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
441
442 if (audio->ns_enable) {
443 /* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */
444 cmd.ec_mode_new =
445 AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA |
446 AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA |
447 AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA;
448 memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params,
449 sizeof(audio->ns.ns_params));
450 } else {
451 cmd.ec_mode_new =
452 AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS |
453 AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS |
454 AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS |
455 AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS |
456 AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS |
457 AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS |
458 AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS |
459 AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS |
460 AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS |
461 AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS |
462 AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS |
463 AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS |
464 AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS;
465 }
466#if DEBUG
467 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
468 pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new);
469 pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n);
470 pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size);
471 pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns);
472 pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d);
473 pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e);
474 pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n);
475#endif
476 return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
477}
478
479static int audio_dsp_set_tx_iir(struct audio_in *audio)
480{
481 struct audpre_cmd_iir_config_type cmd;
482
483 memset(&cmd, 0, sizeof(cmd));
484 cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
485
486 if (audio->iir_enable) {
487 cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
488 cmd.num_bands = audio->iir.num_bands;
489 memcpy(&cmd.iir_params, &audio->iir.iir_params,
490 sizeof(audio->iir.iir_params));
491 } else {
492 cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;
493 }
494#if DEBUG
495 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
496 pr_info("active_flag = 0x%04x\n", cmd.active_flag);
497#endif
498 return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
499}
500
501static int audio_in_dsp_enable(struct audio_in *audio, int enable)
502{
503 audrec_cmd_cfg cmd;
504
505 memset(&cmd, 0, sizeof(cmd));
506 cmd.cmd_id = AUDREC_CMD_CFG;
507 cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS;
508 cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type);
509 cmd.type_1 = 0;
510
511 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
512}
513
514static int audio_in_encoder_config(struct audio_in *audio)
515{
516 audrec_cmd_arec0param_cfg cmd;
517 uint16_t *data = (void *) audio->data;
518 unsigned n;
519
520 memset(&cmd, 0, sizeof(cmd));
521 cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG;
522 cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16;
523 cmd.ptr_to_extpkt_buffer_lsw = audio->phys;
524 cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */
525 cmd.samp_rate_index = audio->samp_rate_index;
526 cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */
527
528 /* FIXME have no idea why cmd.rec_quality is fixed
529 * as 0x1C00 from sample code
530 */
531 cmd.rec_quality = 0x1C00;
532
533 /* prepare buffer pointers:
534 * Mono: 1024 samples + 4 halfword header
535 * Stereo: 2048 samples + 4 halfword header
536 * AAC
537 * Mono/Stere: 768 + 4 halfword header
538 */
539 for (n = 0; n < FRAME_NUM; n++) {
540 audio->in[n].data = data + 4;
541 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
542 data += (4 + (audio->channel_mode ? 2048 : 1024));
543 else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
544 data += (4 + 768);
545 }
546
547 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
548}
549
550static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
551{
552 audrec_cmd_packet_ext_ptr cmd;
553
554 memset(&cmd, 0, sizeof(cmd));
555 cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
556 /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */
557 cmd.type = AUDREC_CMD_TYPE_0;
558 cmd.curr_rec_count_msw = read_cnt >> 16;
559 cmd.curr_rec_count_lsw = read_cnt;
560
561 return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
562}
563
564/* ------------------- device --------------------- */
565
566static void audio_enable_agc(struct audio_in *audio, int enable)
567{
568 if (audio->agc_enable != enable) {
569 audio->agc_enable = enable;
570 if (audio->running)
571 audio_dsp_set_agc(audio);
572 }
573}
574
575static void audio_enable_ns(struct audio_in *audio, int enable)
576{
577 if (audio->ns_enable != enable) {
578 audio->ns_enable = enable;
579 if (audio->running)
580 audio_dsp_set_ns(audio);
581 }
582}
583
584static void audio_enable_tx_iir(struct audio_in *audio, int enable)
585{
586 if (audio->iir_enable != enable) {
587 audio->iir_enable = enable;
588 if (audio->running)
589 audio_dsp_set_tx_iir(audio);
590 }
591}
592
593static void audio_flush(struct audio_in *audio)
594{
595 int i;
596
597 audio->dsp_cnt = 0;
598 audio->in_head = 0;
599 audio->in_tail = 0;
600 audio->in_count = 0;
601 for (i = 0; i < FRAME_NUM; i++) {
602 audio->in[i].size = 0;
603 audio->in[i].read = 0;
604 }
605}
606
607static long audio_in_ioctl(struct file *file,
608 unsigned int cmd, unsigned long arg)
609{
610 struct audio_in *audio = file->private_data;
611 int rc;
612
613 if (cmd == AUDIO_GET_STATS) {
614 struct msm_audio_stats stats;
615 stats.byte_count = atomic_read(&audio->in_bytes);
616 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
617 return -EFAULT;
618 return 0;
619 }
620
621 mutex_lock(&audio->lock);
622 switch (cmd) {
623 case AUDIO_START:
624 rc = audio_in_enable(audio);
625 break;
626 case AUDIO_STOP:
627 rc = audio_in_disable(audio);
628 audio->stopped = 1;
629 break;
630 case AUDIO_FLUSH:
631 if (audio->stopped) {
632 /* Make sure we're stopped and we wake any threads
633 * that might be blocked holding the read_lock.
634 * While audio->stopped read threads will always
635 * exit immediately.
636 */
637 wake_up(&audio->wait);
638 mutex_lock(&audio->read_lock);
639 audio_flush(audio);
640 mutex_unlock(&audio->read_lock);
641 }
642 case AUDIO_SET_CONFIG: {
643 struct msm_audio_config cfg;
644 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
645 rc = -EFAULT;
646 break;
647 }
648 if (cfg.channel_count == 1) {
649 cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO;
650 } else if (cfg.channel_count == 2) {
651 cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO;
652 } else {
653 rc = -EINVAL;
654 break;
655 }
656
657 if (cfg.type == 0) {
658 cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV;
659 } else if (cfg.type == 1) {
660 cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC;
661 } else {
662 rc = -EINVAL;
663 break;
664 }
665 audio->samp_rate = convert_samp_rate(cfg.sample_rate);
666 audio->samp_rate_index =
667 convert_dsp_samp_index(cfg.sample_rate);
668 audio->channel_mode = cfg.channel_count;
669 audio->buffer_size =
670 audio->channel_mode ? STEREO_DATA_SIZE
671 : MONO_DATA_SIZE;
672 audio->type = cfg.type;
673 rc = 0;
674 break;
675 }
676 case AUDIO_GET_CONFIG: {
677 struct msm_audio_config cfg;
678 cfg.buffer_size = audio->buffer_size;
679 cfg.buffer_count = FRAME_NUM;
680 cfg.sample_rate = convert_samp_index(audio->samp_rate);
681 if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
682 cfg.channel_count = 1;
683 else
684 cfg.channel_count = 2;
685 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
686 cfg.type = 0;
687 else
688 cfg.type = 1;
689 cfg.unused[0] = 0;
690 cfg.unused[1] = 0;
691 cfg.unused[2] = 0;
692 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
693 rc = -EFAULT;
694 else
695 rc = 0;
696 break;
697 }
698 default:
699 rc = -EINVAL;
700 }
701 mutex_unlock(&audio->lock);
702 return rc;
703}
704
705static ssize_t audio_in_read(struct file *file,
706 char __user *buf,
707 size_t count, loff_t *pos)
708{
709 struct audio_in *audio = file->private_data;
710 unsigned long flags;
711 const char __user *start = buf;
712 void *data;
713 uint32_t index;
714 uint32_t size;
715 int rc = 0;
716
717 mutex_lock(&audio->read_lock);
718 while (count > 0) {
719 rc = wait_event_interruptible(
720 audio->wait, (audio->in_count > 0) || audio->stopped);
721 if (rc < 0)
722 break;
723
724 if (audio->stopped) {
725 rc = -EBUSY;
726 break;
727 }
728
729 index = audio->in_tail;
730 data = (uint8_t *) audio->in[index].data;
731 size = audio->in[index].size;
732 if (count >= size) {
733 if (copy_to_user(buf, data, size)) {
734 rc = -EFAULT;
735 break;
736 }
737 spin_lock_irqsave(&audio->dsp_lock, flags);
738 if (index != audio->in_tail) {
739 /* overrun -- data is invalid and we need to retry */
740 spin_unlock_irqrestore(&audio->dsp_lock, flags);
741 continue;
742 }
743 audio->in[index].size = 0;
744 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
745 audio->in_count--;
746 spin_unlock_irqrestore(&audio->dsp_lock, flags);
747 count -= size;
748 buf += size;
749 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
750 break;
751 } else {
752 pr_err("audio_in: short read\n");
753 break;
754 }
755 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
756 break; /* AAC only read one frame */
757 }
758 mutex_unlock(&audio->read_lock);
759
760 if (buf > start)
761 return buf - start;
762
763 return rc;
764}
765
766static ssize_t audio_in_write(struct file *file,
767 const char __user *buf,
768 size_t count, loff_t *pos)
769{
770 return -EINVAL;
771}
772
773static int audio_in_release(struct inode *inode, struct file *file)
774{
775 struct audio_in *audio = file->private_data;
776
777 mutex_lock(&audio->lock);
778 audio_in_disable(audio);
779 audio_flush(audio);
780 msm_adsp_put(audio->audrec);
781 msm_adsp_put(audio->audpre);
782 audio->audrec = NULL;
783 audio->audpre = NULL;
784 audio->opened = 0;
785 mutex_unlock(&audio->lock);
786 return 0;
787}
788
789static struct audio_in the_audio_in;
790
791static int audio_in_open(struct inode *inode, struct file *file)
792{
793 struct audio_in *audio = &the_audio_in;
794 int rc;
795
796 mutex_lock(&audio->lock);
797 if (audio->opened) {
798 rc = -EBUSY;
799 goto done;
800 }
801
802 /* Settings will be re-config at AUDIO_SET_CONFIG,
803 * but at least we need to have initial config
804 */
805 audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
806 audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
807 audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
808 audio->buffer_size = MONO_DATA_SIZE;
809 audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV;
810
811 rc = audmgr_open(&audio->audmgr);
812 if (rc)
813 goto done;
814 rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
815 &audpre_adsp_ops, audio);
816 if (rc)
817 goto done;
818 rc = msm_adsp_get("AUDRECTASK", &audio->audrec,
819 &audrec_adsp_ops, audio);
820 if (rc)
821 goto done;
822
823 audio->dsp_cnt = 0;
824 audio->stopped = 0;
825
826 audio_flush(audio);
827
828 file->private_data = audio;
829 audio->opened = 1;
830 rc = 0;
831done:
832 mutex_unlock(&audio->lock);
833 return rc;
834}
835
836static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
837{
838 struct audio_in *audio = file->private_data;
839 int rc = 0, enable;
840 uint16_t enable_mask;
841#if DEBUG
842 int i;
843#endif
844
845 mutex_lock(&audio->lock);
846 switch (cmd) {
847 case AUDIO_ENABLE_AUDPRE: {
848 if (copy_from_user(&enable_mask, (void *) arg,
849 sizeof(enable_mask)))
850 goto out_fault;
851
852 enable = (enable_mask & AGC_ENABLE) ? 1 : 0;
853 audio_enable_agc(audio, enable);
854 enable = (enable_mask & NS_ENABLE) ? 1 : 0;
855 audio_enable_ns(audio, enable);
856 enable = (enable_mask & IIR_ENABLE) ? 1 : 0;
857 audio_enable_tx_iir(audio, enable);
858 break;
859 }
860 case AUDIO_SET_AGC: {
861 if (copy_from_user(&audio->agc, (void *) arg,
862 sizeof(audio->agc)))
863 goto out_fault;
864#if DEBUG
865 pr_info("set agc\n");
866 for (i = 0; i < AGC_PARAM_SIZE; i++) \
867 pr_info("agc_params[%d] = 0x%04x\n", i,
868 audio->agc.agc_params[i]);
869#endif
870 break;
871 }
872 case AUDIO_SET_NS: {
873 if (copy_from_user(&audio->ns, (void *) arg,
874 sizeof(audio->ns)))
875 goto out_fault;
876#if DEBUG
877 pr_info("set ns\n");
878 for (i = 0; i < NS_PARAM_SIZE; i++) \
879 pr_info("ns_params[%d] = 0x%04x\n",
880 i, audio->ns.ns_params[i]);
881#endif
882 break;
883 }
884 case AUDIO_SET_TX_IIR: {
885 if (copy_from_user(&audio->iir, (void *) arg,
886 sizeof(audio->iir)))
887 goto out_fault;
888#if DEBUG
889 pr_info("set iir\n");
890 pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands);
891 for (i = 0; i < IIR_PARAM_SIZE; i++) \
892 pr_info("iir_params[%d] = 0x%04x\n",
893 i, audio->iir.iir_params[i]);
894#endif
895 break;
896 }
897 default:
898 rc = -EINVAL;
899 }
900
901 goto out;
902
903out_fault:
904 rc = -EFAULT;
905out:
906 mutex_unlock(&audio->lock);
907 return rc;
908}
909
910static int audpre_open(struct inode *inode, struct file *file)
911{
912 struct audio_in *audio = &the_audio_in;
913 file->private_data = audio;
914 return 0;
915}
916
917static struct file_operations audio_fops = {
918 .owner = THIS_MODULE,
919 .open = audio_in_open,
920 .release = audio_in_release,
921 .read = audio_in_read,
922 .write = audio_in_write,
923 .unlocked_ioctl = audio_in_ioctl,
924 .llseek = noop_llseek,
925};
926
927static struct file_operations audpre_fops = {
928 .owner = THIS_MODULE,
929 .open = audpre_open,
930 .unlocked_ioctl = audpre_ioctl,
931 .llseek = noop_llseek,
932};
933
934struct miscdevice audio_in_misc = {
935 .minor = MISC_DYNAMIC_MINOR,
936 .name = "msm_pcm_in",
937 .fops = &audio_fops,
938};
939
940struct miscdevice audpre_misc = {
941 .minor = MISC_DYNAMIC_MINOR,
942 .name = "msm_audpre",
943 .fops = &audpre_fops,
944};
945
946static int __init audio_in_init(void)
947{
948 int rc;
949 the_audio_in.data = dma_alloc_coherent(NULL, DMASZ,
950 &the_audio_in.phys, GFP_KERNEL);
951 if (!the_audio_in.data) {
952 printk(KERN_ERR "%s: Unable to allocate DMA buffer\n",
953 __func__);
954 return -ENOMEM;
955 }
956
957 mutex_init(&the_audio_in.lock);
958 mutex_init(&the_audio_in.read_lock);
959 spin_lock_init(&the_audio_in.dsp_lock);
960 init_waitqueue_head(&the_audio_in.wait);
961 rc = misc_register(&audio_in_misc);
962 if (!rc) {
963 rc = misc_register(&audpre_misc);
964 if (rc < 0)
965 misc_deregister(&audio_in_misc);
966 }
967 return rc;
968}
969
970device_initcall(audio_in_init);
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
deleted file mode 100644
index 409a19ce6039..000000000000
--- a/drivers/staging/dream/qdsp5/audio_mp3.c
+++ /dev/null
@@ -1,972 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audio_mp3.c
2 *
3 * mp3 audio output device
4 *
5 * Copyright (C) 2008 Google, Inc.
6 * Copyright (C) 2008 HTC Corporation
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/fs.h>
21#include <linux/miscdevice.h>
22#include <linux/uaccess.h>
23#include <linux/kthread.h>
24#include <linux/wait.h>
25#include <linux/dma-mapping.h>
26#include <linux/gfp.h>
27
28#include <linux/delay.h>
29
30#include <asm/atomic.h>
31#include <asm/ioctls.h>
32#include <mach/msm_adsp.h>
33
34#include <linux/msm_audio.h>
35
36#include "audmgr.h"
37
38#include <mach/qdsp5/qdsp5audppcmdi.h>
39#include <mach/qdsp5/qdsp5audppmsg.h>
40#include <mach/qdsp5/qdsp5audplaycmdi.h>
41#include <mach/qdsp5/qdsp5audplaymsg.h>
42
43/* for queue ids - should be relative to module number*/
44#include "adsp.h"
45
46#ifdef DEBUG
47#define dprintk(format, arg...) \
48printk(KERN_DEBUG format, ## arg)
49#else
50#define dprintk(format, arg...) do {} while (0)
51#endif
52
53/* Size must be power of 2 */
54#define BUFSZ_MAX 32768
55#define BUFSZ_MIN 4096
56#define DMASZ_MAX (BUFSZ_MAX * 2)
57#define DMASZ_MIN (BUFSZ_MIN * 2)
58
59#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
60#define AUDDEC_DEC_MP3 2
61
62#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */
63#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
64 but support 2 buffers currently */
65#define ROUTING_MODE_FTRT 1
66#define ROUTING_MODE_RT 2
67/* Decoder status received from AUDPPTASK */
68#define AUDPP_DEC_STATUS_SLEEP 0
69#define AUDPP_DEC_STATUS_INIT 1
70#define AUDPP_DEC_STATUS_CFG 2
71#define AUDPP_DEC_STATUS_PLAY 3
72
73struct buffer {
74 void *data;
75 unsigned size;
76 unsigned used; /* Input usage actual DSP produced PCM size */
77 unsigned addr;
78};
79
80struct audio {
81 struct buffer out[2];
82
83 spinlock_t dsp_lock;
84
85 uint8_t out_head;
86 uint8_t out_tail;
87 uint8_t out_needed; /* number of buffers the dsp is waiting for */
88 unsigned out_dma_sz;
89
90 atomic_t out_bytes;
91
92 struct mutex lock;
93 struct mutex write_lock;
94 wait_queue_head_t write_wait;
95
96 /* Host PCM section */
97 struct buffer in[PCM_BUF_MAX_COUNT];
98 struct mutex read_lock;
99 wait_queue_head_t read_wait; /* Wait queue for read */
100 char *read_data; /* pointer to reader buffer */
101 dma_addr_t read_phys; /* physical address of reader buffer */
102 uint8_t read_next; /* index to input buffers to be read next */
103 uint8_t fill_next; /* index to buffer that DSP should be filling */
104 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
105 /* ---- End of Host PCM section */
106
107 struct msm_adsp_module *audplay;
108
109 /* configuration to use on next enable */
110 uint32_t out_sample_rate;
111 uint32_t out_channel_mode;
112
113 struct audmgr audmgr;
114
115 /* data allocated for various buffers */
116 char *data;
117 dma_addr_t phys;
118
119 int rflush; /* Read flush */
120 int wflush; /* Write flush */
121 int opened;
122 int enabled;
123 int running;
124 int stopped; /* set when stopped, cleared on flush */
125 int pcm_feedback;
126 int buf_refresh;
127
128 int reserved; /* A byte is being reserved */
129 char rsv_byte; /* Handle odd length user data */
130
131 unsigned volume;
132
133 uint16_t dec_id;
134 uint32_t read_ptr_offset;
135};
136
137static int auddec_dsp_config(struct audio *audio, int enable);
138static void audpp_cmd_cfg_adec_params(struct audio *audio);
139static void audpp_cmd_cfg_routing_mode(struct audio *audio);
140static void audplay_send_data(struct audio *audio, unsigned needed);
141static void audplay_config_hostpcm(struct audio *audio);
142static void audplay_buffer_refresh(struct audio *audio);
143static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
144
145/* must be called with audio->lock held */
146static int audio_enable(struct audio *audio)
147{
148 struct audmgr_config cfg;
149 int rc;
150
151 pr_info("audio_enable()\n");
152
153 if (audio->enabled)
154 return 0;
155
156 audio->out_tail = 0;
157 audio->out_needed = 0;
158
159 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
160 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
161 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
162 cfg.codec = RPC_AUD_DEF_CODEC_MP3;
163 cfg.snd_method = RPC_SND_METHOD_MIDI;
164
165 rc = audmgr_enable(&audio->audmgr, &cfg);
166 if (rc < 0)
167 return rc;
168
169 if (msm_adsp_enable(audio->audplay)) {
170 pr_err("audio: msm_adsp_enable(audplay) failed\n");
171 audmgr_disable(&audio->audmgr);
172 return -ENODEV;
173 }
174
175 if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
176 pr_err("audio: audpp_enable() failed\n");
177 msm_adsp_disable(audio->audplay);
178 audmgr_disable(&audio->audmgr);
179 return -ENODEV;
180 }
181
182 audio->enabled = 1;
183 return 0;
184}
185
186/* must be called with audio->lock held */
187static int audio_disable(struct audio *audio)
188{
189 pr_info("audio_disable()\n");
190 if (audio->enabled) {
191 audio->enabled = 0;
192 auddec_dsp_config(audio, 0);
193 wake_up(&audio->write_wait);
194 wake_up(&audio->read_wait);
195 msm_adsp_disable(audio->audplay);
196 audpp_disable(audio->dec_id, audio);
197 audmgr_disable(&audio->audmgr);
198 audio->out_needed = 0;
199 }
200 return 0;
201}
202
203/* ------------------- dsp --------------------- */
204static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
205{
206 uint8_t index;
207 unsigned long flags;
208
209 if (audio->rflush) {
210 audio->buf_refresh = 1;
211 return;
212 }
213 spin_lock_irqsave(&audio->dsp_lock, flags);
214 for (index = 0; index < payload[1]; index++) {
215 if (audio->in[audio->fill_next].addr ==
216 payload[2 + index * 2]) {
217 pr_info("audio_update_pcm_buf_entry: in[%d] ready\n",
218 audio->fill_next);
219 audio->in[audio->fill_next].used =
220 payload[3 + index * 2];
221 if ((++audio->fill_next) == audio->pcm_buf_count)
222 audio->fill_next = 0;
223
224 } else {
225 pr_err
226 ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
227 , audio->in[audio->fill_next].addr,
228 payload[1 + index * 2]);
229 break;
230 }
231 }
232 if (audio->in[audio->fill_next].used == 0) {
233 audplay_buffer_refresh(audio);
234 } else {
235 pr_info("audio_update_pcm_buf_entry: read cannot keep up\n");
236 audio->buf_refresh = 1;
237 }
238 wake_up(&audio->read_wait);
239 spin_unlock_irqrestore(&audio->dsp_lock, flags);
240
241}
242
243static void audplay_dsp_event(void *data, unsigned id, size_t len,
244 void (*getevent) (void *ptr, size_t len))
245{
246 struct audio *audio = data;
247 uint32_t msg[28];
248 getevent(msg, sizeof(msg));
249
250 dprintk("audplay_dsp_event: msg_id=%x\n", id);
251
252 switch (id) {
253 case AUDPLAY_MSG_DEC_NEEDS_DATA:
254 audplay_send_data(audio, 1);
255 break;
256
257 case AUDPLAY_MSG_BUFFER_UPDATE:
258 audio_update_pcm_buf_entry(audio, msg);
259 break;
260
261 default:
262 pr_err("unexpected message from decoder \n");
263 break;
264 }
265}
266
267static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
268{
269 struct audio *audio = private;
270
271 switch (id) {
272 case AUDPP_MSG_STATUS_MSG:{
273 unsigned status = msg[1];
274
275 switch (status) {
276 case AUDPP_DEC_STATUS_SLEEP:
277 pr_info("decoder status: sleep \n");
278 break;
279
280 case AUDPP_DEC_STATUS_INIT:
281 pr_info("decoder status: init \n");
282 audpp_cmd_cfg_routing_mode(audio);
283 break;
284
285 case AUDPP_DEC_STATUS_CFG:
286 pr_info("decoder status: cfg \n");
287 break;
288 case AUDPP_DEC_STATUS_PLAY:
289 pr_info("decoder status: play \n");
290 if (audio->pcm_feedback) {
291 audplay_config_hostpcm(audio);
292 audplay_buffer_refresh(audio);
293 }
294 break;
295 default:
296 pr_err("unknown decoder status \n");
297 break;
298 }
299 break;
300 }
301 case AUDPP_MSG_CFG_MSG:
302 if (msg[0] == AUDPP_MSG_ENA_ENA) {
303 pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
304 auddec_dsp_config(audio, 1);
305 audio->out_needed = 0;
306 audio->running = 1;
307 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
308 0);
309 audpp_avsync(audio->dec_id, 22050);
310 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
311 pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
312 audpp_avsync(audio->dec_id, 0);
313 audio->running = 0;
314 } else {
315 pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
316 }
317 break;
318 case AUDPP_MSG_ROUTING_ACK:
319 pr_info("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
320 audpp_cmd_cfg_adec_params(audio);
321 break;
322
323 case AUDPP_MSG_FLUSH_ACK:
324 dprintk("%s: FLUSH_ACK\n", __func__);
325 audio->wflush = 0;
326 audio->rflush = 0;
327 if (audio->pcm_feedback)
328 audplay_buffer_refresh(audio);
329 break;
330
331 default:
332 pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
333 }
334
335}
336
337
338struct msm_adsp_ops audplay_adsp_ops = {
339 .event = audplay_dsp_event,
340};
341
342
343#define audplay_send_queue0(audio, cmd, len) \
344 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
345 cmd, len)
346
347static int auddec_dsp_config(struct audio *audio, int enable)
348{
349 audpp_cmd_cfg_dec_type cmd;
350
351 memset(&cmd, 0, sizeof(cmd));
352 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
353 if (enable)
354 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
355 AUDPP_CMD_ENA_DEC_V |
356 AUDDEC_DEC_MP3;
357 else
358 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
359 AUDPP_CMD_DIS_DEC_V;
360
361 return audpp_send_queue1(&cmd, sizeof(cmd));
362}
363
364static void audpp_cmd_cfg_adec_params(struct audio *audio)
365{
366 audpp_cmd_cfg_adec_params_mp3 cmd;
367
368 memset(&cmd, 0, sizeof(cmd));
369 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
370 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN;
371 cmd.common.dec_id = audio->dec_id;
372 cmd.common.input_sampling_frequency = audio->out_sample_rate;
373
374 audpp_send_queue2(&cmd, sizeof(cmd));
375}
376
377static void audpp_cmd_cfg_routing_mode(struct audio *audio)
378{
379 struct audpp_cmd_routing_mode cmd;
380 pr_info("audpp_cmd_cfg_routing_mode()\n");
381 memset(&cmd, 0, sizeof(cmd));
382 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
383 cmd.object_number = audio->dec_id;
384 if (audio->pcm_feedback)
385 cmd.routing_mode = ROUTING_MODE_FTRT;
386 else
387 cmd.routing_mode = ROUTING_MODE_RT;
388
389 audpp_send_queue1(&cmd, sizeof(cmd));
390}
391
392static int audplay_dsp_send_data_avail(struct audio *audio,
393 unsigned idx, unsigned len)
394{
395 audplay_cmd_bitstream_data_avail cmd;
396
397 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
398 cmd.decoder_id = audio->dec_id;
399 cmd.buf_ptr = audio->out[idx].addr;
400 cmd.buf_size = len/2;
401 cmd.partition_number = 0;
402 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
403}
404
405static void audplay_buffer_refresh(struct audio *audio)
406{
407 struct audplay_cmd_buffer_refresh refresh_cmd;
408
409 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
410 refresh_cmd.num_buffers = 1;
411 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
412 refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
413 (audio->in[audio->fill_next].size % 576); /* Mp3 frame size */
414 refresh_cmd.buf_read_count = 0;
415 pr_info("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
416 refresh_cmd.buf0_address, refresh_cmd.buf0_length);
417 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
418}
419
420static void audplay_config_hostpcm(struct audio *audio)
421{
422 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
423
424 pr_info("audplay_config_hostpcm()\n");
425 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
426 cfg_cmd.max_buffers = 1;
427 cfg_cmd.byte_swap = 0;
428 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
429 cfg_cmd.feedback_frequency = 1;
430 cfg_cmd.partition_number = 0;
431 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
432
433}
434
435static void audplay_send_data(struct audio *audio, unsigned needed)
436{
437 struct buffer *frame;
438 unsigned long flags;
439
440 spin_lock_irqsave(&audio->dsp_lock, flags);
441 if (!audio->running)
442 goto done;
443
444 if (audio->wflush) {
445 audio->out_needed = 1;
446 goto done;
447 }
448
449 if (needed && !audio->wflush) {
450 /* We were called from the callback because the DSP
451 * requested more data. Note that the DSP does want
452 * more data, and if a buffer was in-flight, mark it
453 * as available (since the DSP must now be done with
454 * it).
455 */
456 audio->out_needed = 1;
457 frame = audio->out + audio->out_tail;
458 if (frame->used == 0xffffffff) {
459 dprintk("frame %d free\n", audio->out_tail);
460 frame->used = 0;
461 audio->out_tail ^= 1;
462 wake_up(&audio->write_wait);
463 }
464 }
465
466 if (audio->out_needed) {
467 /* If the DSP currently wants data and we have a
468 * buffer available, we will send it and reset
469 * the needed flag. We'll mark the buffer as in-flight
470 * so that it won't be recycled until the next buffer
471 * is requested
472 */
473
474 frame = audio->out + audio->out_tail;
475 if (frame->used) {
476 BUG_ON(frame->used == 0xffffffff);
477 dprintk("frame %d busy\n", audio->out_tail);
478 audplay_dsp_send_data_avail(audio, audio->out_tail,
479 frame->used);
480 frame->used = 0xffffffff;
481 audio->out_needed = 0;
482 }
483 }
484done:
485 spin_unlock_irqrestore(&audio->dsp_lock, flags);
486}
487
488/* ------------------- device --------------------- */
489
490static void audio_flush(struct audio *audio)
491{
492 audio->out[0].used = 0;
493 audio->out[1].used = 0;
494 audio->out_head = 0;
495 audio->out_tail = 0;
496 audio->reserved = 0;
497 atomic_set(&audio->out_bytes, 0);
498}
499
500static void audio_flush_pcm_buf(struct audio *audio)
501{
502 uint8_t index;
503
504 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
505 audio->in[index].used = 0;
506
507 audio->read_next = 0;
508 audio->fill_next = 0;
509}
510
511static void audio_ioport_reset(struct audio *audio)
512{
513 /* Make sure read/write thread are free from
514 * sleep and knowing that system is not able
515 * to process io request at the moment
516 */
517 wake_up(&audio->write_wait);
518 mutex_lock(&audio->write_lock);
519 audio_flush(audio);
520 mutex_unlock(&audio->write_lock);
521 wake_up(&audio->read_wait);
522 mutex_lock(&audio->read_lock);
523 audio_flush_pcm_buf(audio);
524 mutex_unlock(&audio->read_lock);
525}
526
527static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
528{
529 struct audio *audio = file->private_data;
530 int rc = 0;
531
532 pr_info("audio_ioctl() cmd = %d\n", cmd);
533
534 if (cmd == AUDIO_GET_STATS) {
535 struct msm_audio_stats stats;
536 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
537 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
538 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
539 return -EFAULT;
540 return 0;
541 }
542 if (cmd == AUDIO_SET_VOLUME) {
543 unsigned long flags;
544 spin_lock_irqsave(&audio->dsp_lock, flags);
545 audio->volume = arg;
546 if (audio->running)
547 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
548 spin_unlock_irqrestore(&audio->dsp_lock, flags);
549 return 0;
550 }
551 mutex_lock(&audio->lock);
552 switch (cmd) {
553 case AUDIO_START:
554 rc = audio_enable(audio);
555 break;
556 case AUDIO_STOP:
557 rc = audio_disable(audio);
558 audio->stopped = 1;
559 audio_ioport_reset(audio);
560 audio->stopped = 0;
561 break;
562 case AUDIO_FLUSH:
563 dprintk("%s: AUDIO_FLUSH\n", __func__);
564 audio->rflush = 1;
565 audio->wflush = 1;
566 audio_ioport_reset(audio);
567 audio->rflush = 0;
568 audio->wflush = 0;
569
570 if (audio->buf_refresh) {
571 audio->buf_refresh = 0;
572 audplay_buffer_refresh(audio);
573 }
574 break;
575
576 case AUDIO_SET_CONFIG: {
577 struct msm_audio_config config;
578 if (copy_from_user(&config, (void *) arg, sizeof(config))) {
579 rc = -EFAULT;
580 break;
581 }
582 if (config.channel_count == 1) {
583 config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
584 } else if (config.channel_count == 2) {
585 config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
586 } else {
587 rc = -EINVAL;
588 break;
589 }
590 audio->out_sample_rate = config.sample_rate;
591 audio->out_channel_mode = config.channel_count;
592 rc = 0;
593 break;
594 }
595 case AUDIO_GET_CONFIG: {
596 struct msm_audio_config config;
597 config.buffer_size = (audio->out_dma_sz >> 1);
598 config.buffer_count = 2;
599 config.sample_rate = audio->out_sample_rate;
600 if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
601 config.channel_count = 1;
602 } else {
603 config.channel_count = 2;
604 }
605 config.unused[0] = 0;
606 config.unused[1] = 0;
607 config.unused[2] = 0;
608 config.unused[3] = 0;
609 if (copy_to_user((void *) arg, &config, sizeof(config))) {
610 rc = -EFAULT;
611 } else {
612 rc = 0;
613 }
614 break;
615 }
616 case AUDIO_GET_PCM_CONFIG:{
617 struct msm_audio_pcm_config config;
618 config.pcm_feedback = 0;
619 config.buffer_count = PCM_BUF_MAX_COUNT;
620 config.buffer_size = PCM_BUFSZ_MIN;
621 if (copy_to_user((void *)arg, &config,
622 sizeof(config)))
623 rc = -EFAULT;
624 else
625 rc = 0;
626 break;
627 }
628 case AUDIO_SET_PCM_CONFIG:{
629 struct msm_audio_pcm_config config;
630 if (copy_from_user
631 (&config, (void *)arg, sizeof(config))) {
632 rc = -EFAULT;
633 break;
634 }
635 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
636 (config.buffer_count == 1))
637 config.buffer_count = PCM_BUF_MAX_COUNT;
638
639 if (config.buffer_size < PCM_BUFSZ_MIN)
640 config.buffer_size = PCM_BUFSZ_MIN;
641
642 /* Check if pcm feedback is required */
643 if ((config.pcm_feedback) && (!audio->read_data)) {
644 pr_info("ioctl: allocate PCM buffer %d\n",
645 config.buffer_count *
646 config.buffer_size);
647 audio->read_data =
648 dma_alloc_coherent(NULL,
649 config.buffer_size *
650 config.buffer_count,
651 &audio->read_phys,
652 GFP_KERNEL);
653 if (!audio->read_data) {
654 pr_err("audio_mp3: malloc pcm buf failed\n");
655 rc = -1;
656 } else {
657 uint8_t index;
658 uint32_t offset = 0;
659 audio->pcm_feedback = 1;
660 audio->buf_refresh = 0;
661 audio->pcm_buf_count =
662 config.buffer_count;
663 audio->read_next = 0;
664 audio->fill_next = 0;
665
666 for (index = 0;
667 index < config.buffer_count;
668 index++) {
669 audio->in[index].data =
670 audio->read_data + offset;
671 audio->in[index].addr =
672 audio->read_phys + offset;
673 audio->in[index].size =
674 config.buffer_size;
675 audio->in[index].used = 0;
676 offset += config.buffer_size;
677 }
678 rc = 0;
679 }
680 } else {
681 rc = 0;
682 }
683 break;
684 }
685 case AUDIO_PAUSE:
686 dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
687 rc = audpp_pause(audio->dec_id, (int) arg);
688 break;
689 default:
690 rc = -EINVAL;
691 }
692 mutex_unlock(&audio->lock);
693 return rc;
694}
695
696static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
697 loff_t *pos)
698{
699 struct audio *audio = file->private_data;
700 const char __user *start = buf;
701 int rc = 0;
702
703 if (!audio->pcm_feedback)
704 return 0; /* PCM feedback disabled. Nothing to read */
705
706 mutex_lock(&audio->read_lock);
707 pr_info("audio_read() %d \n", count);
708 while (count > 0) {
709 rc = wait_event_interruptible(audio->read_wait,
710 (audio->in[audio->read_next].
711 used > 0) || (audio->stopped)
712 || (audio->rflush));
713
714 if (rc < 0)
715 break;
716
717 if (audio->stopped || audio->rflush) {
718 rc = -EBUSY;
719 break;
720 }
721
722 if (count < audio->in[audio->read_next].used) {
723 /* Read must happen in frame boundary. Since
724 * driver does not know frame size, read count
725 * must be greater or equal
726 * to size of PCM samples
727 */
728 pr_info("audio_read: no partial frame done reading\n");
729 break;
730 } else {
731 pr_info("audio_read: read from in[%d]\n",
732 audio->read_next);
733 if (copy_to_user
734 (buf, audio->in[audio->read_next].data,
735 audio->in[audio->read_next].used)) {
736 pr_err("audio_read: invalid addr %x \n",
737 (unsigned int)buf);
738 rc = -EFAULT;
739 break;
740 }
741 count -= audio->in[audio->read_next].used;
742 buf += audio->in[audio->read_next].used;
743 audio->in[audio->read_next].used = 0;
744 if ((++audio->read_next) == audio->pcm_buf_count)
745 audio->read_next = 0;
746 if (audio->in[audio->read_next].used == 0)
747 break; /* No data ready at this moment
748 * Exit while loop to prevent
749 * output thread sleep too long
750 */
751 }
752 }
753
754 /* don't feed output buffer to HW decoder during flushing
755 * buffer refresh command will be sent once flush completes
756 * send buf refresh command here can confuse HW decoder
757 */
758 if (audio->buf_refresh && !audio->rflush) {
759 audio->buf_refresh = 0;
760 pr_info("audio_read: kick start pcm feedback again\n");
761 audplay_buffer_refresh(audio);
762 }
763
764 mutex_unlock(&audio->read_lock);
765
766 if (buf > start)
767 rc = buf - start;
768
769 pr_info("audio_read: read %d bytes\n", rc);
770 return rc;
771}
772
773static ssize_t audio_write(struct file *file, const char __user *buf,
774 size_t count, loff_t *pos)
775{
776 struct audio *audio = file->private_data;
777 const char __user *start = buf;
778 struct buffer *frame;
779 size_t xfer;
780 char *cpy_ptr;
781 int rc = 0;
782 unsigned dsize;
783
784 mutex_lock(&audio->write_lock);
785 while (count > 0) {
786 frame = audio->out + audio->out_head;
787 cpy_ptr = frame->data;
788 dsize = 0;
789 rc = wait_event_interruptible(audio->write_wait,
790 (frame->used == 0)
791 || (audio->stopped)
792 || (audio->wflush));
793 if (rc < 0)
794 break;
795 if (audio->stopped || audio->wflush) {
796 rc = -EBUSY;
797 break;
798 }
799
800 if (audio->reserved) {
801 dprintk("%s: append reserved byte %x\n",
802 __func__, audio->rsv_byte);
803 *cpy_ptr = audio->rsv_byte;
804 xfer = (count > (frame->size - 1)) ?
805 frame->size - 1 : count;
806 cpy_ptr++;
807 dsize = 1;
808 audio->reserved = 0;
809 } else
810 xfer = (count > frame->size) ? frame->size : count;
811
812 if (copy_from_user(cpy_ptr, buf, xfer)) {
813 rc = -EFAULT;
814 break;
815 }
816
817 dsize += xfer;
818 if (dsize & 1) {
819 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
820 dprintk("%s: odd length buf reserve last byte %x\n",
821 __func__, audio->rsv_byte);
822 audio->reserved = 1;
823 dsize--;
824 }
825 count -= xfer;
826 buf += xfer;
827
828 if (dsize > 0) {
829 audio->out_head ^= 1;
830 frame->used = dsize;
831 audplay_send_data(audio, 0);
832 }
833 }
834 mutex_unlock(&audio->write_lock);
835 if (buf > start)
836 return buf - start;
837 return rc;
838}
839
840static int audio_release(struct inode *inode, struct file *file)
841{
842 struct audio *audio = file->private_data;
843
844 dprintk("audio_release()\n");
845
846 mutex_lock(&audio->lock);
847 audio_disable(audio);
848 audio_flush(audio);
849 audio_flush_pcm_buf(audio);
850 msm_adsp_put(audio->audplay);
851 audio->audplay = NULL;
852 audio->opened = 0;
853 audio->reserved = 0;
854 dma_free_coherent(NULL, audio->out_dma_sz, audio->data, audio->phys);
855 audio->data = NULL;
856 if (audio->read_data != NULL) {
857 dma_free_coherent(NULL,
858 audio->in[0].size * audio->pcm_buf_count,
859 audio->read_data, audio->read_phys);
860 audio->read_data = NULL;
861 }
862 audio->pcm_feedback = 0;
863 mutex_unlock(&audio->lock);
864 return 0;
865}
866
867static struct audio the_mp3_audio;
868
869static int audio_open(struct inode *inode, struct file *file)
870{
871 struct audio *audio = &the_mp3_audio;
872 int rc;
873 unsigned pmem_sz;
874
875 mutex_lock(&audio->lock);
876
877 if (audio->opened) {
878 pr_err("audio: busy\n");
879 rc = -EBUSY;
880 goto done;
881 }
882
883 pmem_sz = DMASZ_MAX;
884
885 while (pmem_sz >= DMASZ_MIN) {
886 audio->data = dma_alloc_coherent(NULL, pmem_sz,
887 &audio->phys, GFP_KERNEL);
888 if (audio->data)
889 break;
890 else if (pmem_sz == DMASZ_MIN) {
891 pr_err("audio: could not allocate DMA buffers\n");
892 rc = -ENOMEM;
893 goto done;
894 } else
895 pmem_sz >>= 1;
896 }
897
898 dprintk("%s: allocated %d bytes DMA buffer\n", __func__, pmem_sz);
899
900 rc = audmgr_open(&audio->audmgr);
901 if (rc) {
902 dma_free_coherent(NULL, pmem_sz,
903 audio->data, audio->phys);
904 goto done;
905 }
906
907 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, &audplay_adsp_ops,
908 audio);
909 if (rc) {
910 pr_err("audio: failed to get audplay0 dsp module\n");
911 dma_free_coherent(NULL, pmem_sz,
912 audio->data, audio->phys);
913 audmgr_close(&audio->audmgr);
914 goto done;
915 }
916
917 audio->out_dma_sz = pmem_sz;
918 pmem_sz >>= 1; /* Shift by 1 to get size of ping pong buffer */
919
920 audio->out_sample_rate = 44100;
921 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
922 audio->dec_id = 0;
923
924 audio->out[0].data = audio->data + 0;
925 audio->out[0].addr = audio->phys + 0;
926 audio->out[0].size = pmem_sz;
927
928 audio->out[1].data = audio->data + pmem_sz;
929 audio->out[1].addr = audio->phys + pmem_sz;
930 audio->out[1].size = pmem_sz;
931
932 audio->volume = 0x2000; /* equal to Q13 number 1.0 Unit Gain */
933
934 audio_flush(audio);
935
936 file->private_data = audio;
937 audio->opened = 1;
938 rc = 0;
939done:
940 mutex_unlock(&audio->lock);
941 return rc;
942}
943
944static struct file_operations audio_mp3_fops = {
945 .owner = THIS_MODULE,
946 .open = audio_open,
947 .release = audio_release,
948 .read = audio_read,
949 .write = audio_write,
950 .unlocked_ioctl = audio_ioctl,
951 .llseek = noop_llseek,
952};
953
954struct miscdevice audio_mp3_misc = {
955 .minor = MISC_DYNAMIC_MINOR,
956 .name = "msm_mp3",
957 .fops = &audio_mp3_fops,
958};
959
960static int __init audio_init(void)
961{
962 mutex_init(&the_mp3_audio.lock);
963 mutex_init(&the_mp3_audio.write_lock);
964 mutex_init(&the_mp3_audio.read_lock);
965 spin_lock_init(&the_mp3_audio.dsp_lock);
966 init_waitqueue_head(&the_mp3_audio.write_wait);
967 init_waitqueue_head(&the_mp3_audio.read_wait);
968 the_mp3_audio.read_data = NULL;
969 return misc_register(&audio_mp3_misc);
970}
971
972device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
deleted file mode 100644
index d20e89541567..000000000000
--- a/drivers/staging/dream/qdsp5/audio_out.c
+++ /dev/null
@@ -1,841 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audio_out.c
2 *
3 * pcm audio output device
4 *
5 * Copyright (C) 2008 Google, Inc.
6 * Copyright (C) 2008 HTC Corporation
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/fs.h>
21#include <linux/miscdevice.h>
22#include <linux/uaccess.h>
23#include <linux/kthread.h>
24#include <linux/wait.h>
25#include <linux/dma-mapping.h>
26#include <linux/debugfs.h>
27#include <linux/delay.h>
28#include <linux/wakelock.h>
29#include <linux/gfp.h>
30
31#include <linux/msm_audio.h>
32
33#include <asm/atomic.h>
34#include <asm/ioctls.h>
35#include <mach/msm_adsp.h>
36
37#include "audmgr.h"
38
39#include <mach/qdsp5/qdsp5audppcmdi.h>
40#include <mach/qdsp5/qdsp5audppmsg.h>
41
42#include "evlog.h"
43
44#define LOG_AUDIO_EVENTS 1
45#define LOG_AUDIO_FAULTS 0
46
47enum {
48 EV_NULL,
49 EV_OPEN,
50 EV_WRITE,
51 EV_RETURN,
52 EV_IOCTL,
53 EV_WRITE_WAIT,
54 EV_WAIT_EVENT,
55 EV_FILL_BUFFER,
56 EV_SEND_BUFFER,
57 EV_DSP_EVENT,
58 EV_ENABLE,
59};
60
61#if (LOG_AUDIO_EVENTS != 1)
62static inline void LOG(unsigned id, unsigned arg) {}
63#else
64static const char *pcm_log_strings[] = {
65 "NULL",
66 "OPEN",
67 "WRITE",
68 "RETURN",
69 "IOCTL",
70 "WRITE_WAIT",
71 "WAIT_EVENT",
72 "FILL_BUFFER",
73 "SEND_BUFFER",
74 "DSP_EVENT",
75 "ENABLE",
76};
77
78DECLARE_LOG(pcm_log, 64, pcm_log_strings);
79
80static int __init _pcm_log_init(void)
81{
82 return ev_log_init(&pcm_log);
83}
84module_init(_pcm_log_init);
85
86#define LOG(id,arg) ev_log_write(&pcm_log, id, arg)
87#endif
88
89
90
91
92
93#define BUFSZ (960 * 5)
94#define DMASZ (BUFSZ * 2)
95
96#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
97#define AUDPP_CMD_EQ_FLAG_DIS 0x0000
98#define AUDPP_CMD_EQ_FLAG_ENA -1
99#define AUDPP_CMD_IIR_FLAG_DIS 0x0000
100#define AUDPP_CMD_IIR_FLAG_ENA -1
101
102#define AUDPP_CMD_IIR_TUNING_FILTER 1
103#define AUDPP_CMD_EQUALIZER 2
104#define AUDPP_CMD_ADRC 3
105
106#define ADRC_ENABLE 0x0001
107#define EQ_ENABLE 0x0002
108#define IIR_ENABLE 0x0004
109
110struct adrc_filter {
111 uint16_t compression_th;
112 uint16_t compression_slope;
113 uint16_t rms_time;
114 uint16_t attack_const_lsw;
115 uint16_t attack_const_msw;
116 uint16_t release_const_lsw;
117 uint16_t release_const_msw;
118 uint16_t adrc_system_delay;
119};
120
121struct eqalizer {
122 uint16_t num_bands;
123 uint16_t eq_params[132];
124};
125
126struct rx_iir_filter {
127 uint16_t num_bands;
128 uint16_t iir_params[48];
129};
130
131typedef struct {
132 audpp_cmd_cfg_object_params_common common;
133 uint16_t eq_flag;
134 uint16_t num_bands;
135 uint16_t eq_params[132];
136} audpp_cmd_cfg_object_params_eq;
137
138typedef struct {
139 audpp_cmd_cfg_object_params_common common;
140 uint16_t active_flag;
141 uint16_t num_bands;
142 uint16_t iir_params[48];
143} audpp_cmd_cfg_object_params_rx_iir;
144
145struct buffer {
146 void *data;
147 unsigned size;
148 unsigned used;
149 unsigned addr;
150};
151
152struct audio {
153 struct buffer out[2];
154
155 spinlock_t dsp_lock;
156
157 uint8_t out_head;
158 uint8_t out_tail;
159 uint8_t out_needed; /* number of buffers the dsp is waiting for */
160
161 atomic_t out_bytes;
162
163 struct mutex lock;
164 struct mutex write_lock;
165 wait_queue_head_t wait;
166
167 /* configuration to use on next enable */
168 uint32_t out_sample_rate;
169 uint32_t out_channel_mode;
170 uint32_t out_weight;
171 uint32_t out_buffer_size;
172
173 struct audmgr audmgr;
174
175 /* data allocated for various buffers */
176 char *data;
177 dma_addr_t phys;
178
179 int opened;
180 int enabled;
181 int running;
182 int stopped; /* set when stopped, cleared on flush */
183 unsigned volume;
184
185 int adrc_enable;
186 struct adrc_filter adrc;
187
188 int eq_enable;
189 struct eqalizer eq;
190
191 int rx_iir_enable;
192 struct rx_iir_filter iir;
193};
194
195static void audio_prevent_sleep(struct audio *audio)
196{
197 printk(KERN_INFO "++++++++++++++++++++++++++++++\n");
198}
199
200static void audio_allow_sleep(struct audio *audio)
201{
202 printk(KERN_INFO "------------------------------\n");
203}
204
205static int audio_dsp_out_enable(struct audio *audio, int yes);
206static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len);
207static int audio_dsp_set_adrc(struct audio *audio);
208static int audio_dsp_set_eq(struct audio *audio);
209static int audio_dsp_set_rx_iir(struct audio *audio);
210
211static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
212
213/* must be called with audio->lock held */
214static int audio_enable(struct audio *audio)
215{
216 struct audmgr_config cfg;
217 int rc;
218
219 pr_info("audio_enable()\n");
220
221 if (audio->enabled)
222 return 0;
223
224 /* refuse to start if we're not ready */
225 if (!audio->out[0].used || !audio->out[1].used)
226 return -EIO;
227
228 /* we start buffers 0 and 1, so buffer 0 will be the
229 * next one the dsp will want
230 */
231 audio->out_tail = 0;
232 audio->out_needed = 0;
233
234 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
235 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
236 cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM;
237 cfg.codec = RPC_AUD_DEF_CODEC_PCM;
238 cfg.snd_method = RPC_SND_METHOD_MIDI;
239
240 audio_prevent_sleep(audio);
241 rc = audmgr_enable(&audio->audmgr, &cfg);
242 if (rc < 0) {
243 audio_allow_sleep(audio);
244 return rc;
245 }
246
247 if (audpp_enable(-1, audio_dsp_event, audio)) {
248 pr_err("audio: audpp_enable() failed\n");
249 audmgr_disable(&audio->audmgr);
250 audio_allow_sleep(audio);
251 return -ENODEV;
252 }
253
254 audio->enabled = 1;
255 return 0;
256}
257
258/* must be called with audio->lock held */
259static int audio_disable(struct audio *audio)
260{
261 pr_info("audio_disable()\n");
262 if (audio->enabled) {
263 audio->enabled = 0;
264 audio_dsp_out_enable(audio, 0);
265
266 audpp_disable(-1, audio);
267
268 wake_up(&audio->wait);
269 audmgr_disable(&audio->audmgr);
270 audio->out_needed = 0;
271 audio_allow_sleep(audio);
272 }
273 return 0;
274}
275
276/* ------------------- dsp --------------------- */
277static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
278{
279 struct audio *audio = private;
280 struct buffer *frame;
281 unsigned long flags;
282
283 LOG(EV_DSP_EVENT, id);
284 switch (id) {
285 case AUDPP_MSG_HOST_PCM_INTF_MSG: {
286 unsigned id = msg[2];
287 unsigned idx = msg[3] - 1;
288
289 /* pr_info("audio_dsp_event: HOST_PCM id %d idx %d\n", id, idx); */
290 if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) {
291 pr_err("bogus id\n");
292 break;
293 }
294 if (idx > 1) {
295 pr_err("bogus buffer idx\n");
296 break;
297 }
298
299 spin_lock_irqsave(&audio->dsp_lock, flags);
300 if (audio->running) {
301 atomic_add(audio->out[idx].used, &audio->out_bytes);
302 audio->out[idx].used = 0;
303
304 frame = audio->out + audio->out_tail;
305 if (frame->used) {
306 audio_dsp_send_buffer(
307 audio, audio->out_tail, frame->used);
308 audio->out_tail ^= 1;
309 } else {
310 audio->out_needed++;
311 }
312 wake_up(&audio->wait);
313 }
314 spin_unlock_irqrestore(&audio->dsp_lock, flags);
315 break;
316 }
317 case AUDPP_MSG_PCMDMAMISSED:
318 pr_info("audio_dsp_event: PCMDMAMISSED %d\n", msg[0]);
319 break;
320 case AUDPP_MSG_CFG_MSG:
321 if (msg[0] == AUDPP_MSG_ENA_ENA) {
322 LOG(EV_ENABLE, 1);
323 pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
324 audio->out_needed = 0;
325 audio->running = 1;
326 audpp_set_volume_and_pan(5, audio->volume, 0);
327 audio_dsp_set_adrc(audio);
328 audio_dsp_set_eq(audio);
329 audio_dsp_set_rx_iir(audio);
330 audio_dsp_out_enable(audio, 1);
331 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
332 LOG(EV_ENABLE, 0);
333 pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
334 audio->running = 0;
335 } else {
336 pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
337 }
338 break;
339 default:
340 pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
341 }
342}
343
344static int audio_dsp_out_enable(struct audio *audio, int yes)
345{
346 audpp_cmd_pcm_intf cmd;
347
348 memset(&cmd, 0, sizeof(cmd));
349 cmd.cmd_id = AUDPP_CMD_PCM_INTF_2;
350 cmd.object_num = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
351 cmd.config = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V;
352 cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
353
354 if (yes) {
355 cmd.write_buf1LSW = audio->out[0].addr;
356 cmd.write_buf1MSW = audio->out[0].addr >> 16;
357 cmd.write_buf1_len = audio->out[0].size;
358 cmd.write_buf2LSW = audio->out[1].addr;
359 cmd.write_buf2MSW = audio->out[1].addr >> 16;
360 cmd.write_buf2_len = audio->out[1].size;
361 cmd.arm_to_rx_flag = AUDPP_CMD_PCM_INTF_ENA_V;
362 cmd.weight_decoder_to_rx = audio->out_weight;
363 cmd.weight_arm_to_rx = 1;
364 cmd.partition_number_arm_to_dsp = 0;
365 cmd.sample_rate = audio->out_sample_rate;
366 cmd.channel_mode = audio->out_channel_mode;
367 }
368
369 return audpp_send_queue2(&cmd, sizeof(cmd));
370}
371
372static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len)
373{
374 audpp_cmd_pcm_intf_send_buffer cmd;
375
376 cmd.cmd_id = AUDPP_CMD_PCM_INTF_2;
377 cmd.host_pcm_object = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
378 cmd.config = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V;
379 cmd.intf_type = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
380 cmd.dsp_to_arm_buf_id = 0;
381 cmd.arm_to_dsp_buf_id = idx + 1;
382 cmd.arm_to_dsp_buf_len = len;
383
384 LOG(EV_SEND_BUFFER, idx);
385 return audpp_send_queue2(&cmd, sizeof(cmd));
386}
387
388static int audio_dsp_set_adrc(struct audio *audio)
389{
390 audpp_cmd_cfg_object_params_adrc cmd;
391
392 memset(&cmd, 0, sizeof(cmd));
393 cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
394 cmd.common.command_type = AUDPP_CMD_ADRC;
395
396 if (audio->adrc_enable) {
397 cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_ENA;
398 cmd.compression_th = audio->adrc.compression_th;
399 cmd.compression_slope = audio->adrc.compression_slope;
400 cmd.rms_time = audio->adrc.rms_time;
401 cmd.attack_const_lsw = audio->adrc.attack_const_lsw;
402 cmd.attack_const_msw = audio->adrc.attack_const_msw;
403 cmd.release_const_lsw = audio->adrc.release_const_lsw;
404 cmd.release_const_msw = audio->adrc.release_const_msw;
405 cmd.adrc_system_delay = audio->adrc.adrc_system_delay;
406 } else {
407 cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_DIS;
408 }
409 return audpp_send_queue3(&cmd, sizeof(cmd));
410}
411
412static int audio_dsp_set_eq(struct audio *audio)
413{
414 audpp_cmd_cfg_object_params_eq cmd;
415
416 memset(&cmd, 0, sizeof(cmd));
417 cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
418 cmd.common.command_type = AUDPP_CMD_EQUALIZER;
419
420 if (audio->eq_enable) {
421 cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA;
422 cmd.num_bands = audio->eq.num_bands;
423 memcpy(&cmd.eq_params, audio->eq.eq_params,
424 sizeof(audio->eq.eq_params));
425 } else {
426 cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS;
427 }
428 return audpp_send_queue3(&cmd, sizeof(cmd));
429}
430
431static int audio_dsp_set_rx_iir(struct audio *audio)
432{
433 audpp_cmd_cfg_object_params_rx_iir cmd;
434
435 memset(&cmd, 0, sizeof(cmd));
436 cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
437 cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER;
438
439 if (audio->rx_iir_enable) {
440 cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA;
441 cmd.num_bands = audio->iir.num_bands;
442 memcpy(&cmd.iir_params, audio->iir.iir_params,
443 sizeof(audio->iir.iir_params));
444 } else {
445 cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS;
446 }
447
448 return audpp_send_queue3(&cmd, sizeof(cmd));
449}
450
451/* ------------------- device --------------------- */
452
453static int audio_enable_adrc(struct audio *audio, int enable)
454{
455 if (audio->adrc_enable != enable) {
456 audio->adrc_enable = enable;
457 if (audio->running)
458 audio_dsp_set_adrc(audio);
459 }
460 return 0;
461}
462
463static int audio_enable_eq(struct audio *audio, int enable)
464{
465 if (audio->eq_enable != enable) {
466 audio->eq_enable = enable;
467 if (audio->running)
468 audio_dsp_set_eq(audio);
469 }
470 return 0;
471}
472
473static int audio_enable_rx_iir(struct audio *audio, int enable)
474{
475 if (audio->rx_iir_enable != enable) {
476 audio->rx_iir_enable = enable;
477 if (audio->running)
478 audio_dsp_set_rx_iir(audio);
479 }
480 return 0;
481}
482
483static void audio_flush(struct audio *audio)
484{
485 audio->out[0].used = 0;
486 audio->out[1].used = 0;
487 audio->out_head = 0;
488 audio->out_tail = 0;
489 audio->stopped = 0;
490}
491
492static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
493{
494 struct audio *audio = file->private_data;
495 int rc;
496
497 if (cmd == AUDIO_GET_STATS) {
498 struct msm_audio_stats stats;
499 stats.byte_count = atomic_read(&audio->out_bytes);
500 if (copy_to_user((void*) arg, &stats, sizeof(stats)))
501 return -EFAULT;
502 return 0;
503 }
504 if (cmd == AUDIO_SET_VOLUME) {
505 unsigned long flags;
506 spin_lock_irqsave(&audio->dsp_lock, flags);
507 audio->volume = arg;
508 if (audio->running)
509 audpp_set_volume_and_pan(6, arg, 0);
510 spin_unlock_irqrestore(&audio->dsp_lock, flags);
511 }
512
513 LOG(EV_IOCTL, cmd);
514 mutex_lock(&audio->lock);
515 switch (cmd) {
516 case AUDIO_START:
517 rc = audio_enable(audio);
518 break;
519 case AUDIO_STOP:
520 rc = audio_disable(audio);
521 audio->stopped = 1;
522 break;
523 case AUDIO_FLUSH:
524 if (audio->stopped) {
525 /* Make sure we're stopped and we wake any threads
526 * that might be blocked holding the write_lock.
527 * While audio->stopped write threads will always
528 * exit immediately.
529 */
530 wake_up(&audio->wait);
531 mutex_lock(&audio->write_lock);
532 audio_flush(audio);
533 mutex_unlock(&audio->write_lock);
534 }
535 case AUDIO_SET_CONFIG: {
536 struct msm_audio_config config;
537 if (copy_from_user(&config, (void*) arg, sizeof(config))) {
538 rc = -EFAULT;
539 break;
540 }
541 if (config.channel_count == 1) {
542 config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
543 } else if (config.channel_count == 2) {
544 config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V;
545 } else {
546 rc = -EINVAL;
547 break;
548 }
549 audio->out_sample_rate = config.sample_rate;
550 audio->out_channel_mode = config.channel_count;
551 rc = 0;
552 break;
553 }
554 case AUDIO_GET_CONFIG: {
555 struct msm_audio_config config;
556 config.buffer_size = BUFSZ;
557 config.buffer_count = 2;
558 config.sample_rate = audio->out_sample_rate;
559 if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
560 config.channel_count = 1;
561 } else {
562 config.channel_count = 2;
563 }
564 config.unused[0] = 0;
565 config.unused[1] = 0;
566 config.unused[2] = 0;
567 config.unused[3] = 0;
568 if (copy_to_user((void*) arg, &config, sizeof(config))) {
569 rc = -EFAULT;
570 } else {
571 rc = 0;
572 }
573 break;
574 }
575 default:
576 rc = -EINVAL;
577 }
578 mutex_unlock(&audio->lock);
579 return rc;
580}
581
582static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
583{
584 return -EINVAL;
585}
586
587static inline int rt_policy(int policy)
588{
589 if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
590 return 1;
591 return 0;
592}
593
594static inline int task_has_rt_policy(struct task_struct *p)
595{
596 return rt_policy(p->policy);
597}
598
599static ssize_t audio_write(struct file *file, const char __user *buf,
600 size_t count, loff_t *pos)
601{
602 struct sched_param s = { .sched_priority = 1 };
603 struct audio *audio = file->private_data;
604 unsigned long flags;
605 const char __user *start = buf;
606 struct buffer *frame;
607 size_t xfer;
608 int old_prio = current->rt_priority;
609 int old_policy = current->policy;
610 int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
611 int rc = 0;
612
613 LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24));
614
615 /* just for this write, set us real-time */
616 if (!task_has_rt_policy(current)) {
617 struct cred *new = prepare_creds();
618 cap_raise(new->cap_effective, CAP_SYS_NICE);
619 commit_creds(new);
620 sched_setscheduler(current, SCHED_RR, &s);
621 }
622
623 mutex_lock(&audio->write_lock);
624 while (count > 0) {
625 frame = audio->out + audio->out_head;
626
627 LOG(EV_WAIT_EVENT, 0);
628 rc = wait_event_interruptible(audio->wait,
629 (frame->used == 0) || (audio->stopped));
630 LOG(EV_WAIT_EVENT, 1);
631
632 if (rc < 0)
633 break;
634 if (audio->stopped) {
635 rc = -EBUSY;
636 break;
637 }
638 xfer = count > frame->size ? frame->size : count;
639 if (copy_from_user(frame->data, buf, xfer)) {
640 rc = -EFAULT;
641 break;
642 }
643 frame->used = xfer;
644 audio->out_head ^= 1;
645 count -= xfer;
646 buf += xfer;
647
648 spin_lock_irqsave(&audio->dsp_lock, flags);
649 LOG(EV_FILL_BUFFER, audio->out_head ^ 1);
650 frame = audio->out + audio->out_tail;
651 if (frame->used && audio->out_needed) {
652 audio_dsp_send_buffer(audio, audio->out_tail, frame->used);
653 audio->out_tail ^= 1;
654 audio->out_needed--;
655 }
656 spin_unlock_irqrestore(&audio->dsp_lock, flags);
657 }
658
659 mutex_unlock(&audio->write_lock);
660
661 /* restore scheduling policy and priority */
662 if (!rt_policy(old_policy)) {
663 struct sched_param v = { .sched_priority = old_prio };
664 sched_setscheduler(current, old_policy, &v);
665 if (likely(!cap_nice)) {
666 struct cred *new = prepare_creds();
667 cap_lower(new->cap_effective, CAP_SYS_NICE);
668 commit_creds(new);
669 sched_setscheduler(current, SCHED_RR, &s);
670 }
671 }
672
673 LOG(EV_RETURN,(buf > start) ? (buf - start) : rc);
674 if (buf > start)
675 return buf - start;
676 return rc;
677}
678
679static int audio_release(struct inode *inode, struct file *file)
680{
681 struct audio *audio = file->private_data;
682
683 LOG(EV_OPEN, 0);
684 mutex_lock(&audio->lock);
685 audio_disable(audio);
686 audio_flush(audio);
687 audio->opened = 0;
688 mutex_unlock(&audio->lock);
689 return 0;
690}
691
692static struct audio the_audio;
693
694static int audio_open(struct inode *inode, struct file *file)
695{
696 struct audio *audio = &the_audio;
697 int rc;
698
699 mutex_lock(&audio->lock);
700
701 if (audio->opened) {
702 pr_err("audio: busy\n");
703 rc = -EBUSY;
704 goto done;
705 }
706
707 if (!audio->data) {
708 audio->data = dma_alloc_coherent(NULL, DMASZ,
709 &audio->phys, GFP_KERNEL);
710 if (!audio->data) {
711 pr_err("audio: could not allocate DMA buffers\n");
712 rc = -ENOMEM;
713 goto done;
714 }
715 }
716
717 rc = audmgr_open(&audio->audmgr);
718 if (rc)
719 goto done;
720
721 audio->out_buffer_size = BUFSZ;
722 audio->out_sample_rate = 44100;
723 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
724 audio->out_weight = 100;
725
726 audio->out[0].data = audio->data + 0;
727 audio->out[0].addr = audio->phys + 0;
728 audio->out[0].size = BUFSZ;
729
730 audio->out[1].data = audio->data + BUFSZ;
731 audio->out[1].addr = audio->phys + BUFSZ;
732 audio->out[1].size = BUFSZ;
733
734 audio->volume = 0x2000;
735
736 audio_flush(audio);
737
738 file->private_data = audio;
739 audio->opened = 1;
740 rc = 0;
741 LOG(EV_OPEN, 1);
742done:
743 mutex_unlock(&audio->lock);
744 return rc;
745}
746
747static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
748{
749 struct audio *audio = file->private_data;
750 int rc = 0, enable;
751 uint16_t enable_mask;
752
753 mutex_lock(&audio->lock);
754 switch (cmd) {
755 case AUDIO_ENABLE_AUDPP:
756 if (copy_from_user(&enable_mask, (void *) arg, sizeof(enable_mask)))
757 goto out_fault;
758
759 enable = (enable_mask & ADRC_ENABLE)? 1 : 0;
760 audio_enable_adrc(audio, enable);
761 enable = (enable_mask & EQ_ENABLE)? 1 : 0;
762 audio_enable_eq(audio, enable);
763 enable = (enable_mask & IIR_ENABLE)? 1 : 0;
764 audio_enable_rx_iir(audio, enable);
765 break;
766
767 case AUDIO_SET_ADRC:
768 if (copy_from_user(&audio->adrc, (void*) arg, sizeof(audio->adrc)))
769 goto out_fault;
770 break;
771
772 case AUDIO_SET_EQ:
773 if (copy_from_user(&audio->eq, (void*) arg, sizeof(audio->eq)))
774 goto out_fault;
775 break;
776
777 case AUDIO_SET_RX_IIR:
778 if (copy_from_user(&audio->iir, (void*) arg, sizeof(audio->iir)))
779 goto out_fault;
780 break;
781
782 default:
783 rc = -EINVAL;
784 }
785
786 goto out;
787
788 out_fault:
789 rc = -EFAULT;
790 out:
791 mutex_unlock(&audio->lock);
792 return rc;
793}
794
795static int audpp_open(struct inode *inode, struct file *file)
796{
797 struct audio *audio = &the_audio;
798
799 file->private_data = audio;
800 return 0;
801}
802
803static struct file_operations audio_fops = {
804 .owner = THIS_MODULE,
805 .open = audio_open,
806 .release = audio_release,
807 .read = audio_read,
808 .write = audio_write,
809 .unlocked_ioctl = audio_ioctl,
810 .llseek = noop_llseek,
811};
812
813static struct file_operations audpp_fops = {
814 .owner = THIS_MODULE,
815 .open = audpp_open,
816 .unlocked_ioctl = audpp_ioctl,
817 .llseek = noop_llseek,
818};
819
820struct miscdevice audio_misc = {
821 .minor = MISC_DYNAMIC_MINOR,
822 .name = "msm_pcm_out",
823 .fops = &audio_fops,
824};
825
826struct miscdevice audpp_misc = {
827 .minor = MISC_DYNAMIC_MINOR,
828 .name = "msm_pcm_ctl",
829 .fops = &audpp_fops,
830};
831
832static int __init audio_init(void)
833{
834 mutex_init(&the_audio.lock);
835 mutex_init(&the_audio.write_lock);
836 spin_lock_init(&the_audio.dsp_lock);
837 init_waitqueue_head(&the_audio.wait);
838 return (misc_register(&audio_misc) || misc_register(&audpp_misc));
839}
840
841device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c
deleted file mode 100644
index 911bab416b85..000000000000
--- a/drivers/staging/dream/qdsp5/audio_qcelp.c
+++ /dev/null
@@ -1,858 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audio_qcelp.c
2 *
3 * qcelp 13k audio decoder device
4 *
5 * Copyright (c) 2008 QUALCOMM USA, INC.
6 *
7 * This code is based in part on audio_mp3.c, which is
8 * Copyright (C) 2008 Google, Inc.
9 * Copyright (C) 2008 HTC Corporation
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * See the GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you can find it at http://www.fsf.org.
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/fs.h>
27#include <linux/miscdevice.h>
28#include <linux/uaccess.h>
29#include <linux/sched.h>
30#include <linux/wait.h>
31#include <linux/dma-mapping.h>
32#include <linux/gfp.h>
33
34#include <asm/ioctls.h>
35#include <mach/msm_adsp.h>
36#include <linux/msm_audio.h>
37#include <mach/qdsp5/qdsp5audppcmdi.h>
38#include <mach/qdsp5/qdsp5audppmsg.h>
39#include <mach/qdsp5/qdsp5audplaycmdi.h>
40#include <mach/qdsp5/qdsp5audplaymsg.h>
41
42#include "audmgr.h"
43/* for queue ids - should be relative to module number*/
44#include "adsp.h"
45
46#ifdef DEBUG
47#define dprintk(format, arg...) \
48printk(KERN_DEBUG format, ## arg)
49#else
50#define dprintk(format, arg...) do {} while (0)
51#endif
52
53#define BUFSZ 1080 /* QCELP 13K Hold 600ms packet data = 36 * 30 */
54#define BUF_COUNT 2
55#define DMASZ (BUFSZ * BUF_COUNT)
56
57#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
58#define PCM_BUF_MAX_COUNT 5
59
60#define AUDDEC_DEC_QCELP 9
61
62#define ROUTING_MODE_FTRT 1
63#define ROUTING_MODE_RT 2
64/* Decoder status received from AUDPPTASK */
65#define AUDPP_DEC_STATUS_SLEEP 0
66#define AUDPP_DEC_STATUS_INIT 1
67#define AUDPP_DEC_STATUS_CFG 2
68#define AUDPP_DEC_STATUS_PLAY 3
69
70struct buffer {
71 void *data;
72 unsigned size;
73 unsigned used; /* Input usage actual DSP produced PCM size */
74 unsigned addr;
75};
76
77struct audio {
78 struct buffer out[BUF_COUNT];
79
80 spinlock_t dsp_lock;
81
82 uint8_t out_head;
83 uint8_t out_tail;
84 uint8_t out_needed; /* number of buffers the dsp is waiting for */
85
86 struct mutex lock;
87 struct mutex write_lock;
88 wait_queue_head_t write_wait;
89
90 /* Host PCM section - START */
91 struct buffer in[PCM_BUF_MAX_COUNT];
92 struct mutex read_lock;
93 wait_queue_head_t read_wait; /* Wait queue for read */
94 char *read_data; /* pointer to reader buffer */
95 dma_addr_t read_phys; /* physical address of reader buffer */
96 uint8_t read_next; /* index to input buffers to be read next */
97 uint8_t fill_next; /* index to buffer that DSP should be filling */
98 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
99 /* Host PCM section - END */
100
101 struct msm_adsp_module *audplay;
102
103 struct audmgr audmgr;
104
105 /* data allocated for various buffers */
106 char *data;
107 dma_addr_t phys;
108
109 uint8_t opened:1;
110 uint8_t enabled:1;
111 uint8_t running:1;
112 uint8_t stopped:1; /* set when stopped, cleared on flush */
113 uint8_t pcm_feedback:1; /* set when non-tunnel mode */
114 uint8_t buf_refresh:1;
115
116 unsigned volume;
117
118 uint16_t dec_id;
119};
120
121static struct audio the_qcelp_audio;
122
123static int auddec_dsp_config(struct audio *audio, int enable);
124static void audpp_cmd_cfg_adec_params(struct audio *audio);
125static void audpp_cmd_cfg_routing_mode(struct audio *audio);
126static void audqcelp_send_data(struct audio *audio, unsigned needed);
127static void audqcelp_config_hostpcm(struct audio *audio);
128static void audqcelp_buffer_refresh(struct audio *audio);
129static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
130
131/* must be called with audio->lock held */
132static int audqcelp_enable(struct audio *audio)
133{
134 struct audmgr_config cfg;
135 int rc;
136
137 dprintk("audqcelp_enable()\n");
138
139 if (audio->enabled)
140 return 0;
141
142 audio->out_tail = 0;
143 audio->out_needed = 0;
144
145 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
146 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
147 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
148 cfg.codec = RPC_AUD_DEF_CODEC_13K;
149 cfg.snd_method = RPC_SND_METHOD_MIDI;
150
151 rc = audmgr_enable(&audio->audmgr, &cfg);
152 if (rc < 0)
153 return rc;
154
155 if (msm_adsp_enable(audio->audplay)) {
156 pr_err("audio: msm_adsp_enable(audplay) failed\n");
157 audmgr_disable(&audio->audmgr);
158 return -ENODEV;
159 }
160
161 if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) {
162 pr_err("audio: audpp_enable() failed\n");
163 msm_adsp_disable(audio->audplay);
164 audmgr_disable(&audio->audmgr);
165 return -ENODEV;
166 }
167 audio->enabled = 1;
168 return 0;
169}
170
171/* must be called with audio->lock held */
172static int audqcelp_disable(struct audio *audio)
173{
174 dprintk("audqcelp_disable()\n");
175 if (audio->enabled) {
176 audio->enabled = 0;
177 auddec_dsp_config(audio, 0);
178 wake_up(&audio->write_wait);
179 wake_up(&audio->read_wait);
180 msm_adsp_disable(audio->audplay);
181 audpp_disable(audio->dec_id, audio);
182 audmgr_disable(&audio->audmgr);
183 audio->out_needed = 0;
184 }
185 return 0;
186}
187
188/* ------------------- dsp --------------------- */
189static void audqcelp_update_pcm_buf_entry(struct audio *audio,
190 uint32_t *payload)
191{
192 uint8_t index;
193 unsigned long flags;
194
195 spin_lock_irqsave(&audio->dsp_lock, flags);
196 for (index = 0; index < payload[1]; index++) {
197 if (audio->in[audio->fill_next].addr ==
198 payload[2 + index * 2]) {
199 dprintk("audqcelp_update_pcm_buf_entry: in[%d] ready\n",
200 audio->fill_next);
201 audio->in[audio->fill_next].used =
202 payload[3 + index * 2];
203 if ((++audio->fill_next) == audio->pcm_buf_count)
204 audio->fill_next = 0;
205 } else {
206 pr_err(
207 "audqcelp_update_pcm_buf_entry: expected=%x ret=%x\n",
208 audio->in[audio->fill_next].addr,
209 payload[1 + index * 2]);
210 break;
211 }
212 }
213 if (audio->in[audio->fill_next].used == 0) {
214 audqcelp_buffer_refresh(audio);
215 } else {
216 dprintk("audqcelp_update_pcm_buf_entry: read cannot keep up\n");
217 audio->buf_refresh = 1;
218 }
219
220 spin_unlock_irqrestore(&audio->dsp_lock, flags);
221 wake_up(&audio->read_wait);
222}
223
224static void audplay_dsp_event(void *data, unsigned id, size_t len,
225 void (*getevent) (void *ptr, size_t len))
226{
227 struct audio *audio = data;
228 uint32_t msg[28];
229 getevent(msg, sizeof(msg));
230
231 dprintk("audplay_dsp_event: msg_id=%x\n", id);
232
233 switch (id) {
234 case AUDPLAY_MSG_DEC_NEEDS_DATA:
235 audqcelp_send_data(audio, 1);
236 break;
237
238 case AUDPLAY_MSG_BUFFER_UPDATE:
239 audqcelp_update_pcm_buf_entry(audio, msg);
240 break;
241
242 default:
243 pr_err("unexpected message from decoder \n");
244 }
245}
246
247static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg)
248{
249 struct audio *audio = private;
250
251 switch (id) {
252 case AUDPP_MSG_STATUS_MSG:{
253 unsigned status = msg[1];
254
255 switch (status) {
256 case AUDPP_DEC_STATUS_SLEEP:
257 dprintk("decoder status: sleep \n");
258 break;
259
260 case AUDPP_DEC_STATUS_INIT:
261 dprintk("decoder status: init \n");
262 audpp_cmd_cfg_routing_mode(audio);
263 break;
264
265 case AUDPP_DEC_STATUS_CFG:
266 dprintk("decoder status: cfg \n");
267 break;
268 case AUDPP_DEC_STATUS_PLAY:
269 dprintk("decoder status: play \n");
270 if (audio->pcm_feedback) {
271 audqcelp_config_hostpcm(audio);
272 audqcelp_buffer_refresh(audio);
273 }
274 break;
275 default:
276 pr_err("unknown decoder status \n");
277 }
278 break;
279 }
280 case AUDPP_MSG_CFG_MSG:
281 if (msg[0] == AUDPP_MSG_ENA_ENA) {
282 dprintk("audqcelp_dsp_event: CFG_MSG ENABLE\n");
283 auddec_dsp_config(audio, 1);
284 audio->out_needed = 0;
285 audio->running = 1;
286 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
287 0);
288 audpp_avsync(audio->dec_id, 22050);
289 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
290 dprintk("audqcelp_dsp_event: CFG_MSG DISABLE\n");
291 audpp_avsync(audio->dec_id, 0);
292 audio->running = 0;
293 } else {
294 pr_err("audqcelp_dsp_event: CFG_MSG %d?\n", msg[0]);
295 }
296 break;
297 case AUDPP_MSG_ROUTING_ACK:
298 dprintk("audqcelp_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
299 audpp_cmd_cfg_adec_params(audio);
300 break;
301 default:
302 pr_err("audqcelp_dsp_event: UNKNOWN (%d)\n", id);
303 }
304
305}
306
307struct msm_adsp_ops audplay_adsp_ops_qcelp = {
308 .event = audplay_dsp_event,
309};
310
311#define audplay_send_queue0(audio, cmd, len) \
312 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
313 cmd, len)
314
315static int auddec_dsp_config(struct audio *audio, int enable)
316{
317 audpp_cmd_cfg_dec_type cmd;
318
319 memset(&cmd, 0, sizeof(cmd));
320 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
321 if (enable)
322 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
323 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP;
324 else
325 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
326
327 return audpp_send_queue1(&cmd, sizeof(cmd));
328}
329
330static void audpp_cmd_cfg_adec_params(struct audio *audio)
331{
332 struct audpp_cmd_cfg_adec_params_v13k cmd;
333
334 memset(&cmd, 0, sizeof(cmd));
335 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
336 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
337 cmd.common.dec_id = audio->dec_id;
338 cmd.common.input_sampling_frequency = 8000;
339 cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
340
341 audpp_send_queue2(&cmd, sizeof(cmd));
342}
343
344static void audpp_cmd_cfg_routing_mode(struct audio *audio)
345{
346 struct audpp_cmd_routing_mode cmd;
347 dprintk("audpp_cmd_cfg_routing_mode()\n");
348 memset(&cmd, 0, sizeof(cmd));
349 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
350 cmd.object_number = audio->dec_id;
351 if (audio->pcm_feedback)
352 cmd.routing_mode = ROUTING_MODE_FTRT;
353 else
354 cmd.routing_mode = ROUTING_MODE_RT;
355 audpp_send_queue1(&cmd, sizeof(cmd));
356}
357
358static int audplay_dsp_send_data_avail(struct audio *audio,
359 unsigned idx, unsigned len)
360{
361 audplay_cmd_bitstream_data_avail cmd;
362
363 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
364 cmd.decoder_id = audio->dec_id;
365 cmd.buf_ptr = audio->out[idx].addr;
366 cmd.buf_size = len / 2;
367 cmd.partition_number = 0;
368 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
369}
370
371static void audqcelp_buffer_refresh(struct audio *audio)
372{
373 struct audplay_cmd_buffer_refresh refresh_cmd;
374
375 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
376 refresh_cmd.num_buffers = 1;
377 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
378 refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
379 refresh_cmd.buf_read_count = 0;
380 dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
381 refresh_cmd.buf0_address, refresh_cmd.buf0_length);
382
383 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
384}
385
386static void audqcelp_config_hostpcm(struct audio *audio)
387{
388 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
389
390 dprintk("audqcelp_config_hostpcm()\n");
391 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
392 cfg_cmd.max_buffers = audio->pcm_buf_count;
393 cfg_cmd.byte_swap = 0;
394 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
395 cfg_cmd.feedback_frequency = 1;
396 cfg_cmd.partition_number = 0;
397
398 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
399}
400
401static void audqcelp_send_data(struct audio *audio, unsigned needed)
402{
403 struct buffer *frame;
404 unsigned long flags;
405
406 spin_lock_irqsave(&audio->dsp_lock, flags);
407 if (!audio->running)
408 goto done;
409
410 if (needed) {
411 /* We were called from the callback because the DSP
412 * requested more data. Note that the DSP does want
413 * more data, and if a buffer was in-flight, mark it
414 * as available (since the DSP must now be done with
415 * it).
416 */
417 audio->out_needed = 1;
418 frame = audio->out + audio->out_tail;
419 if (frame->used == 0xffffffff) {
420 dprintk("frame %d free\n", audio->out_tail);
421 frame->used = 0;
422 audio->out_tail ^= 1;
423 wake_up(&audio->write_wait);
424 }
425 }
426
427 if (audio->out_needed) {
428 /* If the DSP currently wants data and we have a
429 * buffer available, we will send it and reset
430 * the needed flag. We'll mark the buffer as in-flight
431 * so that it won't be recycled until the next buffer
432 * is requested
433 */
434
435 frame = audio->out + audio->out_tail;
436 if (frame->used) {
437 BUG_ON(frame->used == 0xffffffff);
438 dprintk("frame %d busy\n", audio->out_tail);
439 audplay_dsp_send_data_avail(audio, audio->out_tail,
440 frame->used);
441 frame->used = 0xffffffff;
442 audio->out_needed = 0;
443 }
444 }
445 done:
446 spin_unlock_irqrestore(&audio->dsp_lock, flags);
447}
448
449/* ------------------- device --------------------- */
450
451static void audqcelp_flush(struct audio *audio)
452{
453 audio->out[0].used = 0;
454 audio->out[1].used = 0;
455 audio->out_head = 0;
456 audio->out_tail = 0;
457 audio->stopped = 0;
458}
459
460static void audqcelp_flush_pcm_buf(struct audio *audio)
461{
462 uint8_t index;
463
464 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
465 audio->in[index].used = 0;
466
467 audio->read_next = 0;
468 audio->fill_next = 0;
469}
470
471static long audqcelp_ioctl(struct file *file, unsigned int cmd,
472 unsigned long arg)
473{
474 struct audio *audio = file->private_data;
475 int rc = 0;
476
477 dprintk("audqcelp_ioctl() cmd = %d\n", cmd);
478
479 if (cmd == AUDIO_GET_STATS) {
480 struct msm_audio_stats stats;
481 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
482 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
483 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
484 return -EFAULT;
485 return 0;
486 }
487 if (cmd == AUDIO_SET_VOLUME) {
488 unsigned long flags;
489 spin_lock_irqsave(&audio->dsp_lock, flags);
490 audio->volume = arg;
491 if (audio->running)
492 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
493 spin_unlock_irqrestore(&audio->dsp_lock, flags);
494 return 0;
495 }
496 mutex_lock(&audio->lock);
497 switch (cmd) {
498 case AUDIO_START:
499 rc = audqcelp_enable(audio);
500 break;
501 case AUDIO_STOP:
502 rc = audqcelp_disable(audio);
503 audio->stopped = 1;
504 break;
505 case AUDIO_FLUSH:
506 if (audio->stopped) {
507 /* Make sure we're stopped and we wake any threads
508 * that might be blocked holding the write_lock.
509 * While audio->stopped write threads will always
510 * exit immediately.
511 */
512 wake_up(&audio->write_wait);
513 mutex_lock(&audio->write_lock);
514 audqcelp_flush(audio);
515 mutex_unlock(&audio->write_lock);
516 wake_up(&audio->read_wait);
517 mutex_lock(&audio->read_lock);
518 audqcelp_flush_pcm_buf(audio);
519 mutex_unlock(&audio->read_lock);
520 break;
521 }
522 break;
523 case AUDIO_SET_CONFIG:
524 dprintk("AUDIO_SET_CONFIG not applicable \n");
525 break;
526 case AUDIO_GET_CONFIG:{
527 struct msm_audio_config config;
528 config.buffer_size = BUFSZ;
529 config.buffer_count = BUF_COUNT;
530 config.sample_rate = 8000;
531 config.channel_count = 1;
532 config.unused[0] = 0;
533 config.unused[1] = 0;
534 config.unused[2] = 0;
535 config.unused[3] = 0;
536 if (copy_to_user((void *)arg, &config,
537 sizeof(config)))
538 rc = -EFAULT;
539 else
540 rc = 0;
541
542 break;
543 }
544 case AUDIO_GET_PCM_CONFIG:{
545 struct msm_audio_pcm_config config;
546
547 config.pcm_feedback = 0;
548 config.buffer_count = PCM_BUF_MAX_COUNT;
549 config.buffer_size = PCM_BUFSZ_MIN;
550 if (copy_to_user((void *)arg, &config,
551 sizeof(config)))
552 rc = -EFAULT;
553 else
554 rc = 0;
555 break;
556 }
557 case AUDIO_SET_PCM_CONFIG:{
558 struct msm_audio_pcm_config config;
559
560 if (copy_from_user(&config, (void *)arg,
561 sizeof(config))) {
562 rc = -EFAULT;
563 break;
564 }
565 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
566 (config.buffer_count == 1))
567 config.buffer_count = PCM_BUF_MAX_COUNT;
568
569 if (config.buffer_size < PCM_BUFSZ_MIN)
570 config.buffer_size = PCM_BUFSZ_MIN;
571
572 /* Check if pcm feedback is required */
573 if ((config.pcm_feedback) && (!audio->read_data)) {
574 dprintk(
575 "audqcelp_ioctl: allocate PCM buf %d\n",
576 config.buffer_count * config.buffer_size);
577 audio->read_data = dma_alloc_coherent(NULL,
578 config.buffer_size * config.buffer_count,
579 &audio->read_phys, GFP_KERNEL);
580 if (!audio->read_data) {
581 pr_err(
582 "audqcelp_ioctl: no mem for pcm buf\n"
583 );
584 rc = -ENOMEM;
585 } else {
586 uint8_t index;
587 uint32_t offset = 0;
588
589 audio->pcm_feedback = 1;
590 audio->buf_refresh = 0;
591 audio->pcm_buf_count =
592 config.buffer_count;
593 audio->read_next = 0;
594 audio->fill_next = 0;
595
596 for (index = 0;
597 index < config.buffer_count; index++) {
598 audio->in[index].data =
599 audio->read_data + offset;
600 audio->in[index].addr =
601 audio->read_phys + offset;
602 audio->in[index].size =
603 config.buffer_size;
604 audio->in[index].used = 0;
605 offset += config.buffer_size;
606 }
607 rc = 0;
608 }
609 } else {
610 rc = 0;
611 }
612 break;
613 }
614 case AUDIO_PAUSE:
615 dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
616 rc = audpp_pause(audio->dec_id, (int) arg);
617 break;
618 default:
619 rc = -EINVAL;
620 }
621 mutex_unlock(&audio->lock);
622 return rc;
623}
624
625static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count,
626 loff_t *pos)
627{
628 struct audio *audio = file->private_data;
629 const char __user *start = buf;
630 int rc = 0;
631
632 if (!audio->pcm_feedback)
633 return 0; /* PCM feedback is not enabled. Nothing to read */
634
635 mutex_lock(&audio->read_lock);
636 dprintk("audqcelp_read() %d \n", count);
637 while (count > 0) {
638 rc = wait_event_interruptible(audio->read_wait,
639 (audio->in[audio->read_next].used > 0) ||
640 (audio->stopped));
641 if (rc < 0)
642 break;
643
644 if (audio->stopped) {
645 rc = -EBUSY;
646 break;
647 }
648
649 if (count < audio->in[audio->read_next].used) {
650 /* Read must happen in frame boundary. Since driver does
651 not know frame size, read count must be greater or equal
652 to size of PCM samples */
653 dprintk("audqcelp_read:read stop - partial frame\n");
654 break;
655 } else {
656 dprintk("audqcelp_read: read from in[%d]\n",
657 audio->read_next);
658 if (copy_to_user(buf,
659 audio->in[audio->read_next].data,
660 audio->in[audio->read_next].used)) {
661 pr_err("audqcelp_read: invalid addr %x \n",
662 (unsigned int)buf);
663 rc = -EFAULT;
664 break;
665 }
666 count -= audio->in[audio->read_next].used;
667 buf += audio->in[audio->read_next].used;
668 audio->in[audio->read_next].used = 0;
669 if ((++audio->read_next) == audio->pcm_buf_count)
670 audio->read_next = 0;
671 }
672 }
673
674 if (audio->buf_refresh) {
675 audio->buf_refresh = 0;
676 dprintk("audqcelp_read: kick start pcm feedback again\n");
677 audqcelp_buffer_refresh(audio);
678 }
679
680 mutex_unlock(&audio->read_lock);
681
682 if (buf > start)
683 rc = buf - start;
684
685 dprintk("audqcelp_read: read %d bytes\n", rc);
686 return rc;
687}
688
689static ssize_t audqcelp_write(struct file *file, const char __user *buf,
690 size_t count, loff_t *pos)
691{
692 struct audio *audio = file->private_data;
693 const char __user *start = buf;
694 struct buffer *frame;
695 size_t xfer;
696 int rc = 0;
697
698 if (count & 1)
699 return -EINVAL;
700 dprintk("audqcelp_write() \n");
701 mutex_lock(&audio->write_lock);
702 while (count > 0) {
703 frame = audio->out + audio->out_head;
704 rc = wait_event_interruptible(audio->write_wait,
705 (frame->used == 0)
706 || (audio->stopped));
707 dprintk("audqcelp_write() buffer available\n");
708 if (rc < 0)
709 break;
710 if (audio->stopped) {
711 rc = -EBUSY;
712 break;
713 }
714 xfer = (count > frame->size) ? frame->size : count;
715 if (copy_from_user(frame->data, buf, xfer)) {
716 rc = -EFAULT;
717 break;
718 }
719
720 frame->used = xfer;
721 audio->out_head ^= 1;
722 count -= xfer;
723 buf += xfer;
724
725 audqcelp_send_data(audio, 0);
726
727 }
728 mutex_unlock(&audio->write_lock);
729 if (buf > start)
730 return buf - start;
731 return rc;
732}
733
734static int audqcelp_release(struct inode *inode, struct file *file)
735{
736 struct audio *audio = file->private_data;
737
738 dprintk("audqcelp_release()\n");
739
740 mutex_lock(&audio->lock);
741 audqcelp_disable(audio);
742 audqcelp_flush(audio);
743 audqcelp_flush_pcm_buf(audio);
744 msm_adsp_put(audio->audplay);
745 audio->audplay = NULL;
746 audio->opened = 0;
747 if (audio->data)
748 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
749 audio->data = NULL;
750 if (audio->read_data) {
751 dma_free_coherent(NULL,
752 audio->in[0].size * audio->pcm_buf_count,
753 audio->read_data, audio->read_phys);
754 audio->read_data = NULL;
755 }
756 audio->pcm_feedback = 0;
757 mutex_unlock(&audio->lock);
758 return 0;
759}
760
761static int audqcelp_open(struct inode *inode, struct file *file)
762{
763 struct audio *audio = &the_qcelp_audio;
764 int rc;
765
766 mutex_lock(&audio->lock);
767
768 if (audio->opened) {
769 pr_err("audio: busy\n");
770 rc = -EBUSY;
771 goto done;
772 }
773
774 audio->data = dma_alloc_coherent(NULL, DMASZ,
775 &audio->phys, GFP_KERNEL);
776 if (!audio->data) {
777 pr_err("audio: could not allocate DMA buffers\n");
778 rc = -ENOMEM;
779 goto done;
780 }
781
782 rc = audmgr_open(&audio->audmgr);
783 if (rc)
784 goto err;
785
786 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
787 &audplay_adsp_ops_qcelp, audio);
788 if (rc) {
789 pr_err("audio: failed to get audplay0 dsp module\n");
790 audmgr_close(&audio->audmgr);
791 goto err;
792 }
793
794 audio->dec_id = 0;
795
796 audio->out[0].data = audio->data + 0;
797 audio->out[0].addr = audio->phys + 0;
798 audio->out[0].size = BUFSZ;
799
800 audio->out[1].data = audio->data + BUFSZ;
801 audio->out[1].addr = audio->phys + BUFSZ;
802 audio->out[1].size = BUFSZ;
803
804 audio->volume = 0x2000; /* Q13 1.0 */
805
806 audqcelp_flush(audio);
807
808 file->private_data = audio;
809 audio->opened = 1;
810 rc = 0;
811done:
812 mutex_unlock(&audio->lock);
813 return rc;
814err:
815 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
816 mutex_unlock(&audio->lock);
817 return rc;
818}
819
820static struct file_operations audio_qcelp_fops = {
821 .owner = THIS_MODULE,
822 .open = audqcelp_open,
823 .release = audqcelp_release,
824 .read = audqcelp_read,
825 .write = audqcelp_write,
826 .unlocked_ioctl = audqcelp_ioctl,
827 .llseek = noop_llseek,
828};
829
830struct miscdevice audio_qcelp_misc = {
831 .minor = MISC_DYNAMIC_MINOR,
832 .name = "msm_qcelp",
833 .fops = &audio_qcelp_fops,
834};
835
836static int __init audqcelp_init(void)
837{
838 mutex_init(&the_qcelp_audio.lock);
839 mutex_init(&the_qcelp_audio.write_lock);
840 mutex_init(&the_qcelp_audio.read_lock);
841 spin_lock_init(&the_qcelp_audio.dsp_lock);
842 init_waitqueue_head(&the_qcelp_audio.write_wait);
843 init_waitqueue_head(&the_qcelp_audio.read_wait);
844 the_qcelp_audio.read_data = NULL;
845 return misc_register(&audio_qcelp_misc);
846}
847
848static void __exit audqcelp_exit(void)
849{
850 misc_deregister(&audio_qcelp_misc);
851}
852
853module_init(audqcelp_init);
854module_exit(audqcelp_exit);
855
856MODULE_DESCRIPTION("MSM QCELP 13K driver");
857MODULE_LICENSE("GPL v2");
858MODULE_AUTHOR("QUALCOMM");
diff --git a/drivers/staging/dream/qdsp5/audmgr.c b/drivers/staging/dream/qdsp5/audmgr.c
deleted file mode 100644
index 427ae6c0bea8..000000000000
--- a/drivers/staging/dream/qdsp5/audmgr.c
+++ /dev/null
@@ -1,314 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audmgr.c
2 *
3 * interface to "audmgr" service on the baseband cpu
4 *
5 * Copyright (C) 2008 Google, Inc.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#include <linux/module.h>
19#include <linux/fs.h>
20#include <linux/uaccess.h>
21#include <linux/slab.h>
22#include <linux/kthread.h>
23#include <linux/wait.h>
24
25#include <asm/atomic.h>
26#include <mach/msm_rpcrouter.h>
27
28#include "audmgr.h"
29
30#define STATE_CLOSED 0
31#define STATE_DISABLED 1
32#define STATE_ENABLING 2
33#define STATE_ENABLED 3
34#define STATE_DISABLING 4
35#define STATE_ERROR 5
36
37static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid)
38{
39 uint32_t rep[6];
40
41 rep[0] = cpu_to_be32(xid);
42 rep[1] = cpu_to_be32(1);
43 rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
44 rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
45 rep[4] = 0;
46 rep[5] = 0;
47
48 msm_rpc_write(ept, rep, sizeof(rep));
49}
50
51static void process_audmgr_callback(struct audmgr *am,
52 struct rpc_audmgr_cb_func_ptr *args,
53 int len)
54{
55 if (len < (sizeof(uint32_t) * 3))
56 return;
57 if (be32_to_cpu(args->set_to_one) != 1)
58 return;
59
60 switch (be32_to_cpu(args->status)) {
61 case RPC_AUDMGR_STATUS_READY:
62 if (len < sizeof(uint32_t) * 4)
63 break;
64 am->handle = be32_to_cpu(args->u.handle);
65 pr_info("audmgr: rpc READY handle=0x%08x\n", am->handle);
66 break;
67 case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
68 uint32_t volume;
69 if (len < sizeof(uint32_t) * 4)
70 break;
71 volume = be32_to_cpu(args->u.volume);
72 pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume);
73 am->state = STATE_ENABLED;
74 wake_up(&am->wait);
75 break;
76 }
77 case RPC_AUDMGR_STATUS_PENDING:
78 pr_err("audmgr: PENDING?\n");
79 break;
80 case RPC_AUDMGR_STATUS_SUSPEND:
81 pr_err("audmgr: SUSPEND?\n");
82 break;
83 case RPC_AUDMGR_STATUS_FAILURE:
84 pr_err("audmgr: FAILURE\n");
85 break;
86 case RPC_AUDMGR_STATUS_VOLUME_CHANGE:
87 pr_err("audmgr: VOLUME_CHANGE?\n");
88 break;
89 case RPC_AUDMGR_STATUS_DISABLED:
90 pr_err("audmgr: DISABLED\n");
91 am->state = STATE_DISABLED;
92 wake_up(&am->wait);
93 break;
94 case RPC_AUDMGR_STATUS_ERROR:
95 pr_err("audmgr: ERROR?\n");
96 am->state = STATE_ERROR;
97 wake_up(&am->wait);
98 break;
99 default:
100 break;
101 }
102}
103
104static void process_rpc_request(uint32_t proc, uint32_t xid,
105 void *data, int len, void *private)
106{
107 struct audmgr *am = private;
108 uint32_t *x = data;
109
110 if (0) {
111 int n = len / 4;
112 pr_info("rpc_call proc %d:", proc);
113 while (n--)
114 printk(" %08x", be32_to_cpu(*x++));
115 printk("\n");
116 }
117
118 if (proc == AUDMGR_CB_FUNC_PTR)
119 process_audmgr_callback(am, data, len);
120 else
121 pr_err("audmgr: unknown rpc proc %d\n", proc);
122 rpc_ack(am->ept, xid);
123}
124
125#define RPC_TYPE_REQUEST 0
126#define RPC_TYPE_REPLY 1
127
128#define RPC_VERSION 2
129
130#define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2)
131#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr))
132#define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3)
133#define RPC_REPLY_SZ (sizeof(uint32_t) * 6)
134
135static int audmgr_rpc_thread(void *data)
136{
137 struct audmgr *am = data;
138 struct rpc_request_hdr *hdr = NULL;
139 uint32_t type;
140 int len;
141
142 pr_info("audmgr_rpc_thread() start\n");
143
144 while (!kthread_should_stop()) {
145 if (hdr) {
146 kfree(hdr);
147 hdr = NULL;
148 }
149 len = msm_rpc_read(am->ept, (void **) &hdr, -1, -1);
150 if (len < 0) {
151 pr_err("audmgr: rpc read failed (%d)\n", len);
152 break;
153 }
154 if (len < RPC_COMMON_HDR_SZ)
155 continue;
156
157 type = be32_to_cpu(hdr->type);
158 if (type == RPC_TYPE_REPLY) {
159 struct rpc_reply_hdr *rep = (void *) hdr;
160 uint32_t status;
161 if (len < RPC_REPLY_HDR_SZ)
162 continue;
163 status = be32_to_cpu(rep->reply_stat);
164 if (status == RPCMSG_REPLYSTAT_ACCEPTED) {
165 status = be32_to_cpu(rep->data.acc_hdr.accept_stat);
166 pr_info("audmgr: rpc_reply status %d\n", status);
167 } else {
168 pr_info("audmgr: rpc_reply denied!\n");
169 }
170 /* process reply */
171 continue;
172 }
173
174 if (len < RPC_REQUEST_HDR_SZ)
175 continue;
176
177 process_rpc_request(be32_to_cpu(hdr->procedure),
178 be32_to_cpu(hdr->xid),
179 (void *) (hdr + 1),
180 len - sizeof(*hdr),
181 data);
182 }
183 pr_info("audmgr_rpc_thread() exit\n");
184 if (hdr) {
185 kfree(hdr);
186 hdr = NULL;
187 }
188 am->task = NULL;
189 wake_up(&am->wait);
190 return 0;
191}
192
193struct audmgr_enable_msg {
194 struct rpc_request_hdr hdr;
195 struct rpc_audmgr_enable_client_args args;
196};
197
198struct audmgr_disable_msg {
199 struct rpc_request_hdr hdr;
200 uint32_t handle;
201};
202
203int audmgr_open(struct audmgr *am)
204{
205 int rc;
206
207 if (am->state != STATE_CLOSED)
208 return 0;
209
210 am->ept = msm_rpc_connect(AUDMGR_PROG,
211 AUDMGR_VERS,
212 MSM_RPC_UNINTERRUPTIBLE);
213
214 init_waitqueue_head(&am->wait);
215
216 if (IS_ERR(am->ept)) {
217 rc = PTR_ERR(am->ept);
218 am->ept = NULL;
219 pr_err("audmgr: failed to connect to audmgr svc\n");
220 return rc;
221 }
222
223 am->task = kthread_run(audmgr_rpc_thread, am, "audmgr_rpc");
224 if (IS_ERR(am->task)) {
225 rc = PTR_ERR(am->task);
226 am->task = NULL;
227 msm_rpc_close(am->ept);
228 am->ept = NULL;
229 return rc;
230 }
231
232 am->state = STATE_DISABLED;
233 return 0;
234}
235EXPORT_SYMBOL(audmgr_open);
236
237int audmgr_close(struct audmgr *am)
238{
239 return -EBUSY;
240}
241EXPORT_SYMBOL(audmgr_close);
242
243int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg)
244{
245 struct audmgr_enable_msg msg;
246 int rc;
247
248 if (am->state == STATE_ENABLED)
249 return 0;
250
251 if (am->state == STATE_DISABLING)
252 pr_err("audmgr: state is DISABLING in enable?\n");
253 am->state = STATE_ENABLING;
254
255 msg.args.set_to_one = cpu_to_be32(1);
256 msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate);
257 msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate);
258 msg.args.def_method = cpu_to_be32(cfg->def_method);
259 msg.args.codec_type = cpu_to_be32(cfg->codec);
260 msg.args.snd_method = cpu_to_be32(cfg->snd_method);
261 msg.args.cb_func = cpu_to_be32(0x11111111);
262 msg.args.client_data = cpu_to_be32(0x11223344);
263
264 msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
265 AUDMGR_ENABLE_CLIENT);
266
267 rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
268 if (rc < 0)
269 return rc;
270
271 rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ);
272 if (rc == 0) {
273 pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am->state);
274 BUG();
275 }
276 if (am->state == STATE_ENABLED)
277 return 0;
278
279 pr_err("audmgr: unexpected state %d while enabling?!\n", am->state);
280 return -ENODEV;
281}
282EXPORT_SYMBOL(audmgr_enable);
283
284int audmgr_disable(struct audmgr *am)
285{
286 struct audmgr_disable_msg msg;
287 int rc;
288
289 if (am->state == STATE_DISABLED)
290 return 0;
291
292 msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
293 AUDMGR_DISABLE_CLIENT);
294 msg.handle = cpu_to_be32(am->handle);
295
296 am->state = STATE_DISABLING;
297
298 rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
299 if (rc < 0)
300 return rc;
301
302 rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ);
303 if (rc == 0) {
304 pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am->state);
305 BUG();
306 }
307
308 if (am->state == STATE_DISABLED)
309 return 0;
310
311 pr_err("audmgr: unexpected state %d while disabling?!\n", am->state);
312 return -ENODEV;
313}
314EXPORT_SYMBOL(audmgr_disable);
diff --git a/drivers/staging/dream/qdsp5/audmgr.h b/drivers/staging/dream/qdsp5/audmgr.h
deleted file mode 100644
index c07c36b3a0a3..000000000000
--- a/drivers/staging/dream/qdsp5/audmgr.h
+++ /dev/null
@@ -1,215 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audmgr.h
2 *
3 * Copyright 2008 (c) QUALCOMM Incorporated.
4 * Copyright (C) 2008 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_H
18#define _ARCH_ARM_MACH_MSM_AUDMGR_H
19
20#if CONFIG_MSM_AMSS_VERSION==6350
21#include "audmgr_new.h"
22#else
23
24enum rpc_aud_def_sample_rate_type {
25 RPC_AUD_DEF_SAMPLE_RATE_NONE,
26 RPC_AUD_DEF_SAMPLE_RATE_8000,
27 RPC_AUD_DEF_SAMPLE_RATE_11025,
28 RPC_AUD_DEF_SAMPLE_RATE_12000,
29 RPC_AUD_DEF_SAMPLE_RATE_16000,
30 RPC_AUD_DEF_SAMPLE_RATE_22050,
31 RPC_AUD_DEF_SAMPLE_RATE_24000,
32 RPC_AUD_DEF_SAMPLE_RATE_32000,
33 RPC_AUD_DEF_SAMPLE_RATE_44100,
34 RPC_AUD_DEF_SAMPLE_RATE_48000,
35 RPC_AUD_DEF_SAMPLE_RATE_MAX,
36};
37
38enum rpc_aud_def_method_type {
39 RPC_AUD_DEF_METHOD_NONE,
40 RPC_AUD_DEF_METHOD_KEY_BEEP,
41 RPC_AUD_DEF_METHOD_PLAYBACK,
42 RPC_AUD_DEF_METHOD_VOICE,
43 RPC_AUD_DEF_METHOD_RECORD,
44 RPC_AUD_DEF_METHOD_HOST_PCM,
45 RPC_AUD_DEF_METHOD_MIDI_OUT,
46 RPC_AUD_DEF_METHOD_RECORD_SBC,
47 RPC_AUD_DEF_METHOD_DTMF_RINGER,
48 RPC_AUD_DEF_METHOD_MAX,
49};
50
51enum rpc_aud_def_codec_type {
52 RPC_AUD_DEF_CODEC_NONE,
53 RPC_AUD_DEF_CODEC_DTMF,
54 RPC_AUD_DEF_CODEC_MIDI,
55 RPC_AUD_DEF_CODEC_MP3,
56 RPC_AUD_DEF_CODEC_PCM,
57 RPC_AUD_DEF_CODEC_AAC,
58 RPC_AUD_DEF_CODEC_WMA,
59 RPC_AUD_DEF_CODEC_RA,
60 RPC_AUD_DEF_CODEC_ADPCM,
61 RPC_AUD_DEF_CODEC_GAUDIO,
62 RPC_AUD_DEF_CODEC_VOC_EVRC,
63 RPC_AUD_DEF_CODEC_VOC_13K,
64 RPC_AUD_DEF_CODEC_VOC_4GV_NB,
65 RPC_AUD_DEF_CODEC_VOC_AMR,
66 RPC_AUD_DEF_CODEC_VOC_EFR,
67 RPC_AUD_DEF_CODEC_VOC_FR,
68 RPC_AUD_DEF_CODEC_VOC_HR,
69 RPC_AUD_DEF_CODEC_VOC,
70 RPC_AUD_DEF_CODEC_SBC,
71 RPC_AUD_DEF_CODEC_VOC_PCM,
72 RPC_AUD_DEF_CODEC_AMR_WB,
73 RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
74 RPC_AUD_DEF_CODEC_MAX,
75};
76
77enum rpc_snd_method_type {
78 RPC_SND_METHOD_VOICE = 0,
79 RPC_SND_METHOD_KEY_BEEP,
80 RPC_SND_METHOD_MESSAGE,
81 RPC_SND_METHOD_RING,
82 RPC_SND_METHOD_MIDI,
83 RPC_SND_METHOD_AUX,
84 RPC_SND_METHOD_MAX,
85};
86
87enum rpc_voc_codec_type {
88 RPC_VOC_CODEC_DEFAULT,
89 RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
90 RPC_VOC_CODEC_ON_CHIP_1,
91 RPC_VOC_CODEC_STEREO_HEADSET,
92 RPC_VOC_CODEC_ON_CHIP_AUX,
93 RPC_VOC_CODEC_BT_OFF_BOARD,
94 RPC_VOC_CODEC_BT_A2DP,
95 RPC_VOC_CODEC_OFF_BOARD,
96 RPC_VOC_CODEC_SDAC,
97 RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
98 RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
99 RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
100 RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
101 RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
102 RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
103 RPC_VOC_CODEC_TTY_ON_CHIP_1,
104 RPC_VOC_CODEC_TTY_OFF_BOARD,
105 RPC_VOC_CODEC_TTY_VCO,
106 RPC_VOC_CODEC_TTY_HCO,
107 RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
108 RPC_VOC_CODEC_MAX,
109 RPC_VOC_CODEC_NONE,
110};
111
112enum rpc_audmgr_status_type {
113 RPC_AUDMGR_STATUS_READY,
114 RPC_AUDMGR_STATUS_CODEC_CONFIG,
115 RPC_AUDMGR_STATUS_PENDING,
116 RPC_AUDMGR_STATUS_SUSPEND,
117 RPC_AUDMGR_STATUS_FAILURE,
118 RPC_AUDMGR_STATUS_VOLUME_CHANGE,
119 RPC_AUDMGR_STATUS_DISABLED,
120 RPC_AUDMGR_STATUS_ERROR,
121};
122
123struct rpc_audmgr_enable_client_args {
124 uint32_t set_to_one;
125 uint32_t tx_sample_rate;
126 uint32_t rx_sample_rate;
127 uint32_t def_method;
128 uint32_t codec_type;
129 uint32_t snd_method;
130
131 uint32_t cb_func;
132 uint32_t client_data;
133};
134
135#define AUDMGR_ENABLE_CLIENT 2
136#define AUDMGR_DISABLE_CLIENT 3
137#define AUDMGR_SUSPEND_EVENT_RSP 4
138#define AUDMGR_REGISTER_OPERATION_LISTENER 5
139#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6
140#define AUDMGR_REGISTER_CODEC_LISTENER 7
141#define AUDMGR_GET_RX_SAMPLE_RATE 8
142#define AUDMGR_GET_TX_SAMPLE_RATE 9
143#define AUDMGR_SET_DEVICE_MODE 10
144
145#if CONFIG_MSM_AMSS_VERSION < 6220
146#define AUDMGR_PROG_VERS "rs30000013:46255756"
147#define AUDMGR_PROG 0x30000013
148#define AUDMGR_VERS 0x46255756
149#else
150#define AUDMGR_PROG_VERS "rs30000013:e94e8f0c"
151#define AUDMGR_PROG 0x30000013
152#define AUDMGR_VERS 0xe94e8f0c
153#endif
154
155struct rpc_audmgr_cb_func_ptr {
156 uint32_t cb_id;
157 uint32_t set_to_one;
158 uint32_t status;
159 union {
160 uint32_t handle;
161 uint32_t volume;
162
163 } u;
164};
165
166#define AUDMGR_CB_FUNC_PTR 1
167#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2
168#define AUDMGR_CODEC_LSTR_FUNC_PTR 3
169
170#if CONFIG_MSM_AMSS_VERSION < 6220
171#define AUDMGR_CB_PROG 0x31000013
172#define AUDMGR_CB_VERS 0x5fa922a9
173#else
174#define AUDMGR_CB_PROG 0x31000013
175#define AUDMGR_CB_VERS 0x21570ba7
176#endif
177
178struct audmgr {
179 wait_queue_head_t wait;
180 uint32_t handle;
181 struct msm_rpc_endpoint *ept;
182 struct task_struct *task;
183 int state;
184};
185
186struct audmgr_config {
187 uint32_t tx_rate;
188 uint32_t rx_rate;
189 uint32_t def_method;
190 uint32_t codec;
191 uint32_t snd_method;
192};
193
194int audmgr_open(struct audmgr *am);
195int audmgr_close(struct audmgr *am);
196int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
197int audmgr_disable(struct audmgr *am);
198
199typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
200
201int audpp_enable(int id, audpp_event_func func, void *private);
202void audpp_disable(int id, void *private);
203
204int audpp_send_queue1(void *cmd, unsigned len);
205int audpp_send_queue2(void *cmd, unsigned len);
206int audpp_send_queue3(void *cmd, unsigned len);
207
208int audpp_pause(unsigned id, int pause);
209int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
210void audpp_avsync(int id, unsigned rate);
211unsigned audpp_avsync_sample_count(int id);
212unsigned audpp_avsync_byte_count(int id);
213
214#endif
215#endif
diff --git a/drivers/staging/dream/qdsp5/audmgr_new.h b/drivers/staging/dream/qdsp5/audmgr_new.h
deleted file mode 100644
index 49670fe48b9e..000000000000
--- a/drivers/staging/dream/qdsp5/audmgr_new.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/audmgr.h
2 *
3 * Copyright 2008 (c) QUALCOMM Incorporated.
4 * Copyright (C) 2008 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
18#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
19
20enum rpc_aud_def_sample_rate_type {
21 RPC_AUD_DEF_SAMPLE_RATE_NONE,
22 RPC_AUD_DEF_SAMPLE_RATE_8000,
23 RPC_AUD_DEF_SAMPLE_RATE_11025,
24 RPC_AUD_DEF_SAMPLE_RATE_12000,
25 RPC_AUD_DEF_SAMPLE_RATE_16000,
26 RPC_AUD_DEF_SAMPLE_RATE_22050,
27 RPC_AUD_DEF_SAMPLE_RATE_24000,
28 RPC_AUD_DEF_SAMPLE_RATE_32000,
29 RPC_AUD_DEF_SAMPLE_RATE_44100,
30 RPC_AUD_DEF_SAMPLE_RATE_48000,
31 RPC_AUD_DEF_SAMPLE_RATE_MAX,
32};
33
34enum rpc_aud_def_method_type {
35 RPC_AUD_DEF_METHOD_NONE,
36 RPC_AUD_DEF_METHOD_KEY_BEEP,
37 RPC_AUD_DEF_METHOD_PLAYBACK,
38 RPC_AUD_DEF_METHOD_VOICE,
39 RPC_AUD_DEF_METHOD_RECORD,
40 RPC_AUD_DEF_METHOD_HOST_PCM,
41 RPC_AUD_DEF_METHOD_MIDI_OUT,
42 RPC_AUD_DEF_METHOD_RECORD_SBC,
43 RPC_AUD_DEF_METHOD_DTMF_RINGER,
44 RPC_AUD_DEF_METHOD_MAX,
45};
46
47enum rpc_aud_def_codec_type {
48 RPC_AUD_DEF_CODEC_NONE,
49 RPC_AUD_DEF_CODEC_DTMF,
50 RPC_AUD_DEF_CODEC_MIDI,
51 RPC_AUD_DEF_CODEC_MP3,
52 RPC_AUD_DEF_CODEC_PCM,
53 RPC_AUD_DEF_CODEC_AAC,
54 RPC_AUD_DEF_CODEC_WMA,
55 RPC_AUD_DEF_CODEC_RA,
56 RPC_AUD_DEF_CODEC_ADPCM,
57 RPC_AUD_DEF_CODEC_GAUDIO,
58 RPC_AUD_DEF_CODEC_VOC_EVRC,
59 RPC_AUD_DEF_CODEC_VOC_13K,
60 RPC_AUD_DEF_CODEC_VOC_4GV_NB,
61 RPC_AUD_DEF_CODEC_VOC_AMR,
62 RPC_AUD_DEF_CODEC_VOC_EFR,
63 RPC_AUD_DEF_CODEC_VOC_FR,
64 RPC_AUD_DEF_CODEC_VOC_HR,
65 RPC_AUD_DEF_CODEC_VOC_CDMA,
66 RPC_AUD_DEF_CODEC_VOC_CDMA_WB,
67 RPC_AUD_DEF_CODEC_VOC_UMTS,
68 RPC_AUD_DEF_CODEC_VOC_UMTS_WB,
69 RPC_AUD_DEF_CODEC_SBC,
70 RPC_AUD_DEF_CODEC_VOC_PCM,
71 RPC_AUD_DEF_CODEC_AMR_WB,
72 RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
73 RPC_AUD_DEF_CODEC_AAC_BSAC,
74 RPC_AUD_DEF_CODEC_MAX,
75 RPC_AUD_DEF_CODEC_AMR_NB,
76 RPC_AUD_DEF_CODEC_13K,
77 RPC_AUD_DEF_CODEC_EVRC,
78 RPC_AUD_DEF_CODEC_MAX_002,
79};
80
81enum rpc_snd_method_type {
82 RPC_SND_METHOD_VOICE = 0,
83 RPC_SND_METHOD_KEY_BEEP,
84 RPC_SND_METHOD_MESSAGE,
85 RPC_SND_METHOD_RING,
86 RPC_SND_METHOD_MIDI,
87 RPC_SND_METHOD_AUX,
88 RPC_SND_METHOD_MAX,
89};
90
91enum rpc_voc_codec_type {
92 RPC_VOC_CODEC_DEFAULT,
93 RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
94 RPC_VOC_CODEC_ON_CHIP_1,
95 RPC_VOC_CODEC_STEREO_HEADSET,
96 RPC_VOC_CODEC_ON_CHIP_AUX,
97 RPC_VOC_CODEC_BT_OFF_BOARD,
98 RPC_VOC_CODEC_BT_A2DP,
99 RPC_VOC_CODEC_OFF_BOARD,
100 RPC_VOC_CODEC_SDAC,
101 RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
102 RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
103 RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
104 RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
105 RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
106 RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
107 RPC_VOC_CODEC_TTY_ON_CHIP_1,
108 RPC_VOC_CODEC_TTY_OFF_BOARD,
109 RPC_VOC_CODEC_TTY_VCO,
110 RPC_VOC_CODEC_TTY_HCO,
111 RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
112 RPC_VOC_CODEC_MAX,
113 RPC_VOC_CODEC_NONE,
114};
115
116enum rpc_audmgr_status_type {
117 RPC_AUDMGR_STATUS_READY,
118 RPC_AUDMGR_STATUS_CODEC_CONFIG,
119 RPC_AUDMGR_STATUS_PENDING,
120 RPC_AUDMGR_STATUS_SUSPEND,
121 RPC_AUDMGR_STATUS_FAILURE,
122 RPC_AUDMGR_STATUS_VOLUME_CHANGE,
123 RPC_AUDMGR_STATUS_DISABLED,
124 RPC_AUDMGR_STATUS_ERROR,
125};
126
127struct rpc_audmgr_enable_client_args {
128 uint32_t set_to_one;
129 uint32_t tx_sample_rate;
130 uint32_t rx_sample_rate;
131 uint32_t def_method;
132 uint32_t codec_type;
133 uint32_t snd_method;
134
135 uint32_t cb_func;
136 uint32_t client_data;
137};
138
139#define AUDMGR_ENABLE_CLIENT 2
140#define AUDMGR_DISABLE_CLIENT 3
141#define AUDMGR_SUSPEND_EVENT_RSP 4
142#define AUDMGR_REGISTER_OPERATION_LISTENER 5
143#define AUDMGR_UNREGISTER_OPERATION_LISTENER 6
144#define AUDMGR_REGISTER_CODEC_LISTENER 7
145#define AUDMGR_GET_RX_SAMPLE_RATE 8
146#define AUDMGR_GET_TX_SAMPLE_RATE 9
147#define AUDMGR_SET_DEVICE_MODE 10
148
149#define AUDMGR_PROG 0x30000013
150#define AUDMGR_VERS MSM_RPC_VERS(1,0)
151
152struct rpc_audmgr_cb_func_ptr {
153 uint32_t cb_id;
154 uint32_t status; /* Audmgr status */
155 uint32_t set_to_one; /* Pointer status (1 = valid, 0 = invalid) */
156 uint32_t disc;
157 /* disc = AUDMGR_STATUS_READY => data=handle
158 disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle
159 disc = AUDMGR_STATUS_DISABLED => data =status_disabled
160 disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */
161 union {
162 uint32_t handle;
163 uint32_t volume;
164 uint32_t status_disabled;
165 uint32_t volume_change;
166 } u;
167};
168
169#define AUDMGR_CB_FUNC_PTR 1
170#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR 2
171#define AUDMGR_CODEC_LSTR_FUNC_PTR 3
172
173#define AUDMGR_CB_PROG 0x31000013
174#define AUDMGR_CB_VERS 0xf8e3e2d9
175
176struct audmgr {
177 wait_queue_head_t wait;
178 uint32_t handle;
179 struct msm_rpc_endpoint *ept;
180 struct task_struct *task;
181 int state;
182};
183
184struct audmgr_config {
185 uint32_t tx_rate;
186 uint32_t rx_rate;
187 uint32_t def_method;
188 uint32_t codec;
189 uint32_t snd_method;
190};
191
192int audmgr_open(struct audmgr *am);
193int audmgr_close(struct audmgr *am);
194int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
195int audmgr_disable(struct audmgr *am);
196
197typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
198
199int audpp_enable(int id, audpp_event_func func, void *private);
200void audpp_disable(int id, void *private);
201
202int audpp_send_queue1(void *cmd, unsigned len);
203int audpp_send_queue2(void *cmd, unsigned len);
204int audpp_send_queue3(void *cmd, unsigned len);
205
206int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
207int audpp_pause(unsigned id, int pause);
208int audpp_flush(unsigned id);
209void audpp_avsync(int id, unsigned rate);
210unsigned audpp_avsync_sample_count(int id);
211unsigned audpp_avsync_byte_count(int id);
212
213#endif
diff --git a/drivers/staging/dream/qdsp5/audpp.c b/drivers/staging/dream/qdsp5/audpp.c
deleted file mode 100644
index d06556eda316..000000000000
--- a/drivers/staging/dream/qdsp5/audpp.c
+++ /dev/null
@@ -1,429 +0,0 @@
1
2/* arch/arm/mach-msm/qdsp5/audpp.c
3 *
4 * common code to deal with the AUDPP dsp task (audio postproc)
5 *
6 * Copyright (C) 2008 Google, Inc.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/wait.h>
22#include <linux/delay.h>
23
24#include <asm/atomic.h>
25#include <asm/ioctls.h>
26#include <mach/msm_adsp.h>
27
28#include "audmgr.h"
29
30#include <mach/qdsp5/qdsp5audppcmdi.h>
31#include <mach/qdsp5/qdsp5audppmsg.h>
32
33/* for queue ids - should be relative to module number*/
34#include "adsp.h"
35
36#include "evlog.h"
37
38
39enum {
40 EV_NULL,
41 EV_ENABLE,
42 EV_DISABLE,
43 EV_EVENT,
44 EV_DATA,
45};
46
47static const char *dsp_log_strings[] = {
48 "NULL",
49 "ENABLE",
50 "DISABLE",
51 "EVENT",
52 "DATA",
53};
54
55DECLARE_LOG(dsp_log, 64, dsp_log_strings);
56
57static int __init _dsp_log_init(void)
58{
59 return ev_log_init(&dsp_log);
60}
61module_init(_dsp_log_init);
62#define LOG(id,arg) ev_log_write(&dsp_log, id, arg)
63
64static DEFINE_MUTEX(audpp_lock);
65
66#define CH_COUNT 5
67#define AUDPP_CLNT_MAX_COUNT 6
68#define AUDPP_AVSYNC_INFO_SIZE 7
69
70struct audpp_state {
71 struct msm_adsp_module *mod;
72 audpp_event_func func[AUDPP_CLNT_MAX_COUNT];
73 void *private[AUDPP_CLNT_MAX_COUNT];
74 struct mutex *lock;
75 unsigned open_count;
76 unsigned enabled;
77
78 /* which channels are actually enabled */
79 unsigned avsync_mask;
80
81 /* flags, 48 bits sample/bytes counter per channel */
82 uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1];
83};
84
85struct audpp_state the_audpp_state = {
86 .lock = &audpp_lock,
87};
88
89int audpp_send_queue1(void *cmd, unsigned len)
90{
91 return msm_adsp_write(the_audpp_state.mod,
92 QDSP_uPAudPPCmd1Queue, cmd, len);
93}
94EXPORT_SYMBOL(audpp_send_queue1);
95
96int audpp_send_queue2(void *cmd, unsigned len)
97{
98 return msm_adsp_write(the_audpp_state.mod,
99 QDSP_uPAudPPCmd2Queue, cmd, len);
100}
101EXPORT_SYMBOL(audpp_send_queue2);
102
103int audpp_send_queue3(void *cmd, unsigned len)
104{
105 return msm_adsp_write(the_audpp_state.mod,
106 QDSP_uPAudPPCmd3Queue, cmd, len);
107}
108EXPORT_SYMBOL(audpp_send_queue3);
109
110static int audpp_dsp_config(int enable)
111{
112 audpp_cmd_cfg cmd;
113
114 cmd.cmd_id = AUDPP_CMD_CFG;
115 cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP;
116
117 return audpp_send_queue1(&cmd, sizeof(cmd));
118}
119
120static void audpp_broadcast(struct audpp_state *audpp, unsigned id,
121 uint16_t *msg)
122{
123 unsigned n;
124 for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
125 if (audpp->func[n])
126 audpp->func[n] (audpp->private[n], id, msg);
127 }
128}
129
130static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id,
131 unsigned id, uint16_t *msg)
132{
133 if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id])
134 audpp->func[clnt_id] (audpp->private[clnt_id], id, msg);
135}
136
137static void audpp_dsp_event(void *data, unsigned id, size_t len,
138 void (*getevent)(void *ptr, size_t len))
139{
140 struct audpp_state *audpp = data;
141 uint16_t msg[8];
142
143 if (id == AUDPP_MSG_AVSYNC_MSG) {
144 getevent(audpp->avsync, sizeof(audpp->avsync));
145
146 /* mask off any channels we're not watching to avoid
147 * cases where we might get one last update after
148 * disabling avsync and end up in an odd state when
149 * we next read...
150 */
151 audpp->avsync[0] &= audpp->avsync_mask;
152 return;
153 }
154
155 getevent(msg, sizeof(msg));
156
157 LOG(EV_EVENT, (id << 16) | msg[0]);
158 LOG(EV_DATA, (msg[1] << 16) | msg[2]);
159
160 switch (id) {
161 case AUDPP_MSG_STATUS_MSG:{
162 unsigned cid = msg[0];
163 pr_info("audpp: status %d %d %d\n", cid, msg[1],
164 msg[2]);
165 if ((cid < 5) && audpp->func[cid])
166 audpp->func[cid] (audpp->private[cid], id, msg);
167 break;
168 }
169 case AUDPP_MSG_HOST_PCM_INTF_MSG:
170 if (audpp->func[5])
171 audpp->func[5] (audpp->private[5], id, msg);
172 break;
173 case AUDPP_MSG_PCMDMAMISSED:
174 pr_err("audpp: DMA missed obj=%x\n", msg[0]);
175 break;
176 case AUDPP_MSG_CFG_MSG:
177 if (msg[0] == AUDPP_MSG_ENA_ENA) {
178 pr_info("audpp: ENABLE\n");
179 audpp->enabled = 1;
180 audpp_broadcast(audpp, id, msg);
181 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
182 pr_info("audpp: DISABLE\n");
183 audpp->enabled = 0;
184 audpp_broadcast(audpp, id, msg);
185 } else {
186 pr_err("audpp: invalid config msg %d\n", msg[0]);
187 }
188 break;
189 case AUDPP_MSG_ROUTING_ACK:
190 audpp_broadcast(audpp, id, msg);
191 break;
192 case AUDPP_MSG_FLUSH_ACK:
193 audpp_notify_clnt(audpp, msg[0], id, msg);
194 break;
195 default:
196 pr_info("audpp: unhandled msg id %x\n", id);
197 }
198}
199
200static struct msm_adsp_ops adsp_ops = {
201 .event = audpp_dsp_event,
202};
203
204static void audpp_fake_event(struct audpp_state *audpp, int id,
205 unsigned event, unsigned arg)
206{
207 uint16_t msg[1];
208 msg[0] = arg;
209 audpp->func[id] (audpp->private[id], event, msg);
210}
211
212int audpp_enable(int id, audpp_event_func func, void *private)
213{
214 struct audpp_state *audpp = &the_audpp_state;
215 int res = 0;
216
217 if (id < -1 || id > 4)
218 return -EINVAL;
219
220 if (id == -1)
221 id = 5;
222
223 mutex_lock(audpp->lock);
224 if (audpp->func[id]) {
225 res = -EBUSY;
226 goto out;
227 }
228
229 audpp->func[id] = func;
230 audpp->private[id] = private;
231
232 LOG(EV_ENABLE, 1);
233 if (audpp->open_count++ == 0) {
234 pr_info("audpp: enable\n");
235 res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp);
236 if (res < 0) {
237 pr_err("audpp: cannot open AUDPPTASK\n");
238 audpp->open_count = 0;
239 audpp->func[id] = NULL;
240 audpp->private[id] = NULL;
241 goto out;
242 }
243 LOG(EV_ENABLE, 2);
244 msm_adsp_enable(audpp->mod);
245 audpp_dsp_config(1);
246 } else {
247 unsigned long flags;
248 local_irq_save(flags);
249 if (audpp->enabled)
250 audpp_fake_event(audpp, id,
251 AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA);
252 local_irq_restore(flags);
253 }
254
255 res = 0;
256out:
257 mutex_unlock(audpp->lock);
258 return res;
259}
260EXPORT_SYMBOL(audpp_enable);
261
262void audpp_disable(int id, void *private)
263{
264 struct audpp_state *audpp = &the_audpp_state;
265 unsigned long flags;
266
267 if (id < -1 || id > 4)
268 return;
269
270 if (id == -1)
271 id = 5;
272
273 mutex_lock(audpp->lock);
274 LOG(EV_DISABLE, 1);
275 if (!audpp->func[id])
276 goto out;
277 if (audpp->private[id] != private)
278 goto out;
279
280 local_irq_save(flags);
281 audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS);
282 audpp->func[id] = NULL;
283 audpp->private[id] = NULL;
284 local_irq_restore(flags);
285
286 if (--audpp->open_count == 0) {
287 pr_info("audpp: disable\n");
288 LOG(EV_DISABLE, 2);
289 audpp_dsp_config(0);
290 msm_adsp_disable(audpp->mod);
291 msm_adsp_put(audpp->mod);
292 audpp->mod = NULL;
293 }
294out:
295 mutex_unlock(audpp->lock);
296}
297EXPORT_SYMBOL(audpp_disable);
298
299#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT))
300
301void audpp_avsync(int id, unsigned rate)
302{
303 unsigned long flags;
304 audpp_cmd_avsync cmd;
305
306 if (BAD_ID(id))
307 return;
308
309 local_irq_save(flags);
310 if (rate)
311 the_audpp_state.avsync_mask |= (1 << id);
312 else
313 the_audpp_state.avsync_mask &= (~(1 << id));
314 the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask;
315 local_irq_restore(flags);
316
317 cmd.cmd_id = AUDPP_CMD_AVSYNC;
318 cmd.object_number = id;
319 cmd.interrupt_interval_lsw = rate;
320 cmd.interrupt_interval_msw = rate >> 16;
321 audpp_send_queue1(&cmd, sizeof(cmd));
322}
323EXPORT_SYMBOL(audpp_avsync);
324
325unsigned audpp_avsync_sample_count(int id)
326{
327 uint16_t *avsync = the_audpp_state.avsync;
328 unsigned val;
329 unsigned long flags;
330 unsigned mask;
331
332 if (BAD_ID(id))
333 return 0;
334
335 mask = 1 << id;
336 id = id * AUDPP_AVSYNC_INFO_SIZE + 2;
337 local_irq_save(flags);
338 if (avsync[0] & mask)
339 val = (avsync[id] << 16) | avsync[id + 1];
340 else
341 val = 0;
342 local_irq_restore(flags);
343
344 return val;
345}
346EXPORT_SYMBOL(audpp_avsync_sample_count);
347
348unsigned audpp_avsync_byte_count(int id)
349{
350 uint16_t *avsync = the_audpp_state.avsync;
351 unsigned val;
352 unsigned long flags;
353 unsigned mask;
354
355 if (BAD_ID(id))
356 return 0;
357
358 mask = 1 << id;
359 id = id * AUDPP_AVSYNC_INFO_SIZE + 5;
360 local_irq_save(flags);
361 if (avsync[0] & mask)
362 val = (avsync[id] << 16) | avsync[id + 1];
363 else
364 val = 0;
365 local_irq_restore(flags);
366
367 return val;
368}
369EXPORT_SYMBOL(audpp_avsync_byte_count);
370
371#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
372#define AUDPP_CMD_VOLUME_PAN 0
373
374int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan)
375{
376 /* cmd, obj_cfg[7], cmd_type, volume, pan */
377 uint16_t cmd[11];
378
379 if (id > 6)
380 return -EINVAL;
381
382 memset(cmd, 0, sizeof(cmd));
383 cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS;
384 cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE;
385 cmd[8] = AUDPP_CMD_VOLUME_PAN;
386 cmd[9] = volume;
387 cmd[10] = pan;
388
389 return audpp_send_queue3(cmd, sizeof(cmd));
390}
391EXPORT_SYMBOL(audpp_set_volume_and_pan);
392
393int audpp_pause(unsigned id, int pause)
394{
395 /* pause 1 = pause 0 = resume */
396 u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
397
398 if (id >= CH_COUNT)
399 return -EINVAL;
400
401 memset(pause_cmd, 0, sizeof(pause_cmd));
402
403 pause_cmd[0] = AUDPP_CMD_DEC_CTRL;
404 if (pause == 1)
405 pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V;
406 else if (pause == 0)
407 pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V;
408 else
409 return -EINVAL;
410
411 return audpp_send_queue1(pause_cmd, sizeof(pause_cmd));
412}
413EXPORT_SYMBOL(audpp_pause);
414
415int audpp_flush(unsigned id)
416{
417 u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
418
419 if (id >= CH_COUNT)
420 return -EINVAL;
421
422 memset(flush_cmd, 0, sizeof(flush_cmd));
423
424 flush_cmd[0] = AUDPP_CMD_DEC_CTRL;
425 flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V;
426
427 return audpp_send_queue1(flush_cmd, sizeof(flush_cmd));
428}
429EXPORT_SYMBOL(audpp_flush);
diff --git a/drivers/staging/dream/qdsp5/evlog.h b/drivers/staging/dream/qdsp5/evlog.h
deleted file mode 100644
index e5ab86b9dd7c..000000000000
--- a/drivers/staging/dream/qdsp5/evlog.h
+++ /dev/null
@@ -1,134 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/evlog.h
2 *
3 * simple event log debugging facility
4 *
5 * Copyright (C) 2008 Google, Inc.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#include <linux/fs.h>
19#include <linux/hrtimer.h>
20#include <linux/debugfs.h>
21
22#define EV_LOG_ENTRY_NAME(n) n##_entry
23
24#define DECLARE_LOG(_name, _size, _str) \
25static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
26static struct ev_log _name = { \
27 .name = #_name, \
28 .strings = _str, \
29 .num_strings = ARRAY_SIZE(_str), \
30 .entry = EV_LOG_ENTRY_NAME(_name), \
31 .max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
32}
33
34struct ev_entry {
35 ktime_t when;
36 uint32_t id;
37 uint32_t arg;
38};
39
40struct ev_log {
41 struct ev_entry *entry;
42 unsigned max;
43 unsigned next;
44 unsigned fault;
45 const char **strings;
46 unsigned num_strings;
47 const char *name;
48};
49
50static char ev_buf[4096];
51
52static ssize_t ev_log_read(struct file *file, char __user *buf,
53 size_t count, loff_t *ppos)
54{
55 struct ev_log *log = file->private_data;
56 struct ev_entry *entry;
57 unsigned long flags;
58 int size = 0;
59 unsigned n, id, max;
60 ktime_t now, t;
61
62 max = log->max;
63 now = ktime_get();
64 local_irq_save(flags);
65 n = (log->next - 1) & (max - 1);
66 entry = log->entry;
67 while (n != log->next) {
68 t = ktime_sub(now, entry[n].when);
69 id = entry[n].id;
70 if (id) {
71 const char *str;
72 if (id < log->num_strings)
73 str = log->strings[id];
74 else
75 str = "UNKNOWN";
76 size += scnprintf(ev_buf + size, 4096 - size,
77 "%8d.%03d %08x %s\n",
78 t.tv.sec, t.tv.nsec / 1000000,
79 entry[n].arg, str);
80 }
81 n = (n - 1) & (max - 1);
82 }
83 log->fault = 0;
84 local_irq_restore(flags);
85 return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
86}
87
88static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
89{
90 struct ev_entry *entry;
91 unsigned long flags;
92 local_irq_save(flags);
93
94 if (log->fault) {
95 if (log->fault == 1)
96 goto done;
97 log->fault--;
98 }
99
100 entry = log->entry + log->next;
101 entry->when = ktime_get();
102 entry->id = id;
103 entry->arg = arg;
104 log->next = (log->next + 1) & (log->max - 1);
105done:
106 local_irq_restore(flags);
107}
108
109static void ev_log_freeze(struct ev_log *log, unsigned count)
110{
111 unsigned long flags;
112 local_irq_save(flags);
113 log->fault = count;
114 local_irq_restore(flags);
115}
116
117static int ev_log_open(struct inode *inode, struct file *file)
118{
119 file->private_data = inode->i_private;
120 return 0;
121}
122
123static const struct file_operations ev_log_ops = {
124 .read = ev_log_read,
125 .open = ev_log_open,
126 .llseek = default_llseek,
127};
128
129static int ev_log_init(struct ev_log *log)
130{
131 debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
132 return 0;
133}
134
diff --git a/drivers/staging/dream/qdsp5/snd.c b/drivers/staging/dream/qdsp5/snd.c
deleted file mode 100644
index e0f2f7bca29e..000000000000
--- a/drivers/staging/dream/qdsp5/snd.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/* arch/arm/mach-msm/qdsp5/snd.c
2 *
3 * interface to "snd" service on the baseband cpu
4 *
5 * Copyright (C) 2008 HTC Corporation
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#include <linux/module.h>
19#include <linux/fs.h>
20#include <linux/miscdevice.h>
21#include <linux/uaccess.h>
22#include <linux/kthread.h>
23#include <linux/delay.h>
24#include <linux/msm_audio.h>
25
26#include <asm/atomic.h>
27#include <asm/ioctls.h>
28#include <mach/board.h>
29#include <mach/msm_rpcrouter.h>
30
31struct snd_ctxt {
32 struct mutex lock;
33 int opened;
34 struct msm_rpc_endpoint *ept;
35 struct msm_snd_endpoints *snd_epts;
36};
37
38static struct snd_ctxt the_snd;
39
40#define RPC_SND_PROG 0x30000002
41#define RPC_SND_CB_PROG 0x31000002
42#if CONFIG_MSM_AMSS_VERSION == 6210
43#define RPC_SND_VERS 0x94756085 /* 2490720389 */
44#elif (CONFIG_MSM_AMSS_VERSION == 6220) || \
45 (CONFIG_MSM_AMSS_VERSION == 6225)
46#define RPC_SND_VERS 0xaa2b1a44 /* 2854951492 */
47#elif CONFIG_MSM_AMSS_VERSION == 6350
48#define RPC_SND_VERS MSM_RPC_VERS(1,0)
49#endif
50
51#define SND_SET_DEVICE_PROC 2
52#define SND_SET_VOLUME_PROC 3
53
54struct rpc_snd_set_device_args {
55 uint32_t device;
56 uint32_t ear_mute;
57 uint32_t mic_mute;
58
59 uint32_t cb_func;
60 uint32_t client_data;
61};
62
63struct rpc_snd_set_volume_args {
64 uint32_t device;
65 uint32_t method;
66 uint32_t volume;
67
68 uint32_t cb_func;
69 uint32_t client_data;
70};
71
72struct snd_set_device_msg {
73 struct rpc_request_hdr hdr;
74 struct rpc_snd_set_device_args args;
75};
76
77struct snd_set_volume_msg {
78 struct rpc_request_hdr hdr;
79 struct rpc_snd_set_volume_args args;
80};
81
82struct snd_endpoint *get_snd_endpoints(int *size);
83
84static inline int check_mute(int mute)
85{
86 return (mute == SND_MUTE_MUTED ||
87 mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
88}
89
90static int get_endpoint(struct snd_ctxt *snd, unsigned long arg)
91{
92 int rc = 0, index;
93 struct msm_snd_endpoint ept;
94
95 if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
96 pr_err("snd_ioctl get endpoint: invalid read pointer.\n");
97 return -EFAULT;
98 }
99
100 index = ept.id;
101 if (index < 0 || index >= snd->snd_epts->num) {
102 pr_err("snd_ioctl get endpoint: invalid index!\n");
103 return -EINVAL;
104 }
105
106 ept.id = snd->snd_epts->endpoints[index].id;
107 strncpy(ept.name,
108 snd->snd_epts->endpoints[index].name,
109 sizeof(ept.name));
110
111 if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
112 pr_err("snd_ioctl get endpoint: invalid write pointer.\n");
113 rc = -EFAULT;
114 }
115
116 return rc;
117}
118
119static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
120{
121 struct snd_set_device_msg dmsg;
122 struct snd_set_volume_msg vmsg;
123 struct msm_snd_device_config dev;
124 struct msm_snd_volume_config vol;
125 struct snd_ctxt *snd = file->private_data;
126 int rc = 0;
127
128 mutex_lock(&snd->lock);
129 switch (cmd) {
130 case SND_SET_DEVICE:
131 if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
132 pr_err("snd_ioctl set device: invalid pointer.\n");
133 rc = -EFAULT;
134 break;
135 }
136
137 dmsg.args.device = cpu_to_be32(dev.device);
138 dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
139 dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
140 if (check_mute(dev.ear_mute) < 0 ||
141 check_mute(dev.mic_mute) < 0) {
142 pr_err("snd_ioctl set device: invalid mute status.\n");
143 rc = -EINVAL;
144 break;
145 }
146 dmsg.args.cb_func = -1;
147 dmsg.args.client_data = 0;
148
149 pr_info("snd_set_device %d %d %d\n", dev.device,
150 dev.ear_mute, dev.mic_mute);
151
152 rc = msm_rpc_call(snd->ept,
153 SND_SET_DEVICE_PROC,
154 &dmsg, sizeof(dmsg), 5 * HZ);
155 break;
156
157 case SND_SET_VOLUME:
158 if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
159 pr_err("snd_ioctl set volume: invalid pointer.\n");
160 rc = -EFAULT;
161 break;
162 }
163
164 vmsg.args.device = cpu_to_be32(vol.device);
165 vmsg.args.method = cpu_to_be32(vol.method);
166 if (vol.method != SND_METHOD_VOICE) {
167 pr_err("snd_ioctl set volume: invalid method.\n");
168 rc = -EINVAL;
169 break;
170 }
171
172 vmsg.args.volume = cpu_to_be32(vol.volume);
173 vmsg.args.cb_func = -1;
174 vmsg.args.client_data = 0;
175
176 pr_info("snd_set_volume %d %d %d\n", vol.device,
177 vol.method, vol.volume);
178
179 rc = msm_rpc_call(snd->ept,
180 SND_SET_VOLUME_PROC,
181 &vmsg, sizeof(vmsg), 5 * HZ);
182 break;
183
184 case SND_GET_NUM_ENDPOINTS:
185 if (copy_to_user((void __user *)arg,
186 &snd->snd_epts->num, sizeof(unsigned))) {
187 pr_err("snd_ioctl get endpoint: invalid pointer.\n");
188 rc = -EFAULT;
189 }
190 break;
191
192 case SND_GET_ENDPOINT:
193 rc = get_endpoint(snd, arg);
194 break;
195
196 default:
197 pr_err("snd_ioctl unknown command.\n");
198 rc = -EINVAL;
199 break;
200 }
201 mutex_unlock(&snd->lock);
202
203 return rc;
204}
205
206static int snd_release(struct inode *inode, struct file *file)
207{
208 struct snd_ctxt *snd = file->private_data;
209
210 mutex_lock(&snd->lock);
211 snd->opened = 0;
212 mutex_unlock(&snd->lock);
213 return 0;
214}
215
216static int snd_open(struct inode *inode, struct file *file)
217{
218 struct snd_ctxt *snd = &the_snd;
219 int rc = 0;
220
221 mutex_lock(&snd->lock);
222 if (snd->opened == 0) {
223 if (snd->ept == NULL) {
224 snd->ept = msm_rpc_connect(RPC_SND_PROG, RPC_SND_VERS,
225 MSM_RPC_UNINTERRUPTIBLE);
226 if (IS_ERR(snd->ept)) {
227 rc = PTR_ERR(snd->ept);
228 snd->ept = NULL;
229 pr_err("snd: failed to connect snd svc\n");
230 goto err;
231 }
232 }
233 file->private_data = snd;
234 snd->opened = 1;
235 } else {
236 pr_err("snd already opened.\n");
237 rc = -EBUSY;
238 }
239
240err:
241 mutex_unlock(&snd->lock);
242 return rc;
243}
244
245static struct file_operations snd_fops = {
246 .owner = THIS_MODULE,
247 .open = snd_open,
248 .release = snd_release,
249 .unlocked_ioctl = snd_ioctl,
250 .llseek = noop_llseek,
251};
252
253struct miscdevice snd_misc = {
254 .minor = MISC_DYNAMIC_MINOR,
255 .name = "msm_snd",
256 .fops = &snd_fops,
257};
258
259static int snd_probe(struct platform_device *pdev)
260{
261 struct snd_ctxt *snd = &the_snd;
262 mutex_init(&snd->lock);
263 snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data;
264 return misc_register(&snd_misc);
265}
266
267static struct platform_driver snd_plat_driver = {
268 .probe = snd_probe,
269 .driver = {
270 .name = "msm_snd",
271 .owner = THIS_MODULE,
272 },
273};
274
275static int __init snd_init(void)
276{
277 return platform_driver_register(&snd_plat_driver);
278}
279
280module_init(snd_init);
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
deleted file mode 100644
index 3320359408a9..000000000000
--- a/drivers/staging/dream/synaptics_i2c_rmi.c
+++ /dev/null
@@ -1,649 +0,0 @@
1/*
2 * Support for synaptics touchscreen.
3 *
4 * Copyright (C) 2007 Google, Inc.
5 * Author: Arve Hjønnevåg <arve@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 * http://www.synaptics.com/sites/default/files/511_000099_01F.pdf
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/slab.h>
22#ifdef CONFIG_HAS_EARLYSUSPEND
23#include <linux/earlysuspend.h>
24#endif
25#include <linux/hrtimer.h>
26#include <linux/i2c.h>
27#include <linux/input.h>
28#include <linux/interrupt.h>
29#include <linux/io.h>
30#include <linux/platform_device.h>
31#include "synaptics_i2c_rmi.h"
32
33static struct workqueue_struct *synaptics_wq;
34
35struct synaptics_ts_data {
36 u16 addr;
37 struct i2c_client *client;
38 struct input_dev *input_dev;
39 int use_irq;
40 struct hrtimer timer;
41 struct work_struct work;
42 u16 max[2];
43 int snap_state[2][2];
44 int snap_down_on[2];
45 int snap_down_off[2];
46 int snap_up_on[2];
47 int snap_up_off[2];
48 int snap_down[2];
49 int snap_up[2];
50 u32 flags;
51 int (*power)(int on);
52#ifdef CONFIG_HAS_EARLYSUSPEND
53 struct early_suspend early_suspend;
54#endif
55};
56
57static int i2c_set(struct synaptics_ts_data *ts, u8 reg, u8 val, char *msg)
58{
59 int ret = i2c_smbus_write_byte_data(ts->client, reg, val);
60 if (ret < 0)
61 pr_err("i2c_smbus_write_byte_data failed (%s)\n", msg);
62 return ret;
63}
64
65static int i2c_read(struct synaptics_ts_data *ts, u8 reg, char *msg)
66{
67 int ret = i2c_smbus_read_byte_data(ts->client, reg);
68 if (ret < 0)
69 pr_err("i2c_smbus_read_byte_data failed (%s)\n", msg);
70 return ret;
71}
72#ifdef CONFIG_HAS_EARLYSUSPEND
73static void synaptics_ts_early_suspend(struct early_suspend *h);
74static void synaptics_ts_late_resume(struct early_suspend *h);
75#endif
76
77static int synaptics_init_panel(struct synaptics_ts_data *ts)
78{
79 int ret;
80
81 ret = i2c_set(ts, 0xff, 0x10, "set page select");
82 if (ret == 0)
83 ret = i2c_set(ts, 0x41, 0x04, "set No Clip Z");
84
85 ret = i2c_set(ts, 0xff, 0x04, "fallback page select");
86 ret = i2c_set(ts, 0xf0, 0x81, "select 80 reports per second");
87 return ret;
88}
89
90static void decode_report(struct synaptics_ts_data *ts, u8 *buf)
91{
92/*
93 * This sensor sends two 6-byte absolute finger reports, an optional
94 * 2-byte relative report followed by a status byte. This function
95 * reads the two finger reports and transforms the coordinates
96 * according the platform data so they can be aligned with the lcd
97 * behind the touchscreen. Typically we flip the y-axis since the
98 * sensor uses the bottom left corner as the origin, but if the sensor
99 * is mounted upside down the platform data will request that the
100 * x-axis should be flipped instead. The snap to inactive edge border
101 * are used to allow tapping the edges of the screen on the G1. The
102 * active area of the touchscreen is smaller than the lcd. When the
103 * finger gets close the edge of the screen we snap it to the
104 * edge. This allows ui elements at the edge of the screen to be hit,
105 * and it prevents hitting ui elements that are not at the edge of the
106 * screen when the finger is touching the edge.
107 */
108 int pos[2][2];
109 int f, a;
110 int base = 2;
111 int z = buf[1];
112 int finger = buf[0] & 7;
113
114 for (f = 0; f < 2; f++) {
115 u32 flip_flag = SYNAPTICS_FLIP_X;
116 for (a = 0; a < 2; a++) {
117 int p = buf[base + 1];
118 p |= (u16)(buf[base] & 0x1f) << 8;
119 if (ts->flags & flip_flag)
120 p = ts->max[a] - p;
121 if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
122 if (ts->snap_state[f][a]) {
123 if (p <= ts->snap_down_off[a])
124 p = ts->snap_down[a];
125 else if (p >= ts->snap_up_off[a])
126 p = ts->snap_up[a];
127 else
128 ts->snap_state[f][a] = 0;
129 } else {
130 if (p <= ts->snap_down_on[a]) {
131 p = ts->snap_down[a];
132 ts->snap_state[f][a] = 1;
133 } else if (p >= ts->snap_up_on[a]) {
134 p = ts->snap_up[a];
135 ts->snap_state[f][a] = 1;
136 }
137 }
138 }
139 pos[f][a] = p;
140 base += 2;
141 flip_flag <<= 1;
142 }
143 base += 2;
144 if (ts->flags & SYNAPTICS_SWAP_XY)
145 swap(pos[f][0], pos[f][1]);
146 }
147 if (z) {
148 input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
149 input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
150 }
151 input_report_abs(ts->input_dev, ABS_PRESSURE, z);
152 input_report_key(ts->input_dev, BTN_TOUCH, finger);
153 input_sync(ts->input_dev);
154}
155
156static void synaptics_ts_work_func(struct work_struct *work)
157{
158 int i;
159 int ret;
160 int bad_data = 0;
161 struct i2c_msg msg[2];
162 u8 start_reg = 0;
163 u8 buf[15];
164 struct synaptics_ts_data *ts =
165 container_of(work, struct synaptics_ts_data, work);
166
167 msg[0].addr = ts->client->addr;
168 msg[0].flags = 0;
169 msg[0].len = 1;
170 msg[0].buf = &start_reg;
171 msg[1].addr = ts->client->addr;
172 msg[1].flags = I2C_M_RD;
173 msg[1].len = sizeof(buf);
174 msg[1].buf = buf;
175
176 for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
177 ret = i2c_transfer(ts->client->adapter, msg, 2);
178 if (ret < 0) {
179 pr_err("ts_work: i2c_transfer failed\n");
180 bad_data = 1;
181 continue;
182 }
183 if ((buf[14] & 0xc0) != 0x40) {
184 pr_warning("synaptics_ts_work_func:"
185 " bad read %x %x %x %x %x %x %x %x %x"
186 " %x %x %x %x %x %x, ret %d\n",
187 buf[0], buf[1], buf[2], buf[3],
188 buf[4], buf[5], buf[6], buf[7],
189 buf[8], buf[9], buf[10], buf[11],
190 buf[12], buf[13], buf[14], ret);
191 if (bad_data)
192 synaptics_init_panel(ts);
193 bad_data = 1;
194 continue;
195 }
196 bad_data = 0;
197 if ((buf[14] & 1) == 0)
198 break;
199
200 decode_report(ts, buf);
201 }
202}
203
204static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
205{
206 struct synaptics_ts_data *ts =
207 container_of(timer, struct synaptics_ts_data, timer);
208
209 queue_work(synaptics_wq, &ts->work);
210
211 hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
212 return HRTIMER_NORESTART;
213}
214
215static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
216{
217 struct synaptics_ts_data *ts = dev_id;
218
219 synaptics_ts_work_func(&ts->work);
220 return IRQ_HANDLED;
221}
222
223static int detect(struct synaptics_ts_data *ts, u32 *panel_version)
224{
225 int ret;
226 int retry = 10;
227
228 ret = i2c_set(ts, 0xf4, 0x01, "reset device");
229
230 while (retry-- > 0) {
231 ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
232 if (ret >= 0)
233 break;
234 msleep(100);
235 }
236 if (ret < 0) {
237 pr_err("i2c_smbus_read_byte_data failed\n");
238 return ret;
239 }
240
241 *panel_version = ret << 8;
242 ret = i2c_read(ts, 0xe5, "product minor");
243 if (ret < 0)
244 return ret;
245 *panel_version |= ret;
246
247 ret = i2c_read(ts, 0xe3, "property");
248 if (ret < 0)
249 return ret;
250
251 pr_info("synaptics: version %x, product property %x\n",
252 *panel_version, ret);
253 return 0;
254}
255
256static void compute_areas(struct synaptics_ts_data *ts,
257 struct synaptics_i2c_rmi_platform_data *pdata,
258 u16 max_x, u16 max_y)
259{
260 int inactive_area_left;
261 int inactive_area_right;
262 int inactive_area_top;
263 int inactive_area_bottom;
264 int snap_left_on;
265 int snap_left_off;
266 int snap_right_on;
267 int snap_right_off;
268 int snap_top_on;
269 int snap_top_off;
270 int snap_bottom_on;
271 int snap_bottom_off;
272 int fuzz_x;
273 int fuzz_y;
274 int fuzz_p;
275 int fuzz_w;
276 int swapped = !!(ts->flags & SYNAPTICS_SWAP_XY);
277
278 inactive_area_left = pdata->inactive_left;
279 inactive_area_right = pdata->inactive_right;
280 inactive_area_top = pdata->inactive_top;
281 inactive_area_bottom = pdata->inactive_bottom;
282 snap_left_on = pdata->snap_left_on;
283 snap_left_off = pdata->snap_left_off;
284 snap_right_on = pdata->snap_right_on;
285 snap_right_off = pdata->snap_right_off;
286 snap_top_on = pdata->snap_top_on;
287 snap_top_off = pdata->snap_top_off;
288 snap_bottom_on = pdata->snap_bottom_on;
289 snap_bottom_off = pdata->snap_bottom_off;
290 fuzz_x = pdata->fuzz_x;
291 fuzz_y = pdata->fuzz_y;
292 fuzz_p = pdata->fuzz_p;
293 fuzz_w = pdata->fuzz_w;
294
295 inactive_area_left = inactive_area_left * max_x / 0x10000;
296 inactive_area_right = inactive_area_right * max_x / 0x10000;
297 inactive_area_top = inactive_area_top * max_y / 0x10000;
298 inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
299 snap_left_on = snap_left_on * max_x / 0x10000;
300 snap_left_off = snap_left_off * max_x / 0x10000;
301 snap_right_on = snap_right_on * max_x / 0x10000;
302 snap_right_off = snap_right_off * max_x / 0x10000;
303 snap_top_on = snap_top_on * max_y / 0x10000;
304 snap_top_off = snap_top_off * max_y / 0x10000;
305 snap_bottom_on = snap_bottom_on * max_y / 0x10000;
306 snap_bottom_off = snap_bottom_off * max_y / 0x10000;
307 fuzz_x = fuzz_x * max_x / 0x10000;
308 fuzz_y = fuzz_y * max_y / 0x10000;
309
310
311 ts->snap_down[swapped] = -inactive_area_left;
312 ts->snap_up[swapped] = max_x + inactive_area_right;
313 ts->snap_down[!swapped] = -inactive_area_top;
314 ts->snap_up[!swapped] = max_y + inactive_area_bottom;
315 ts->snap_down_on[swapped] = snap_left_on;
316 ts->snap_down_off[swapped] = snap_left_off;
317 ts->snap_up_on[swapped] = max_x - snap_right_on;
318 ts->snap_up_off[swapped] = max_x - snap_right_off;
319 ts->snap_down_on[!swapped] = snap_top_on;
320 ts->snap_down_off[!swapped] = snap_top_off;
321 ts->snap_up_on[!swapped] = max_y - snap_bottom_on;
322 ts->snap_up_off[!swapped] = max_y - snap_bottom_off;
323 pr_info("synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
324 pr_info("synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
325 inactive_area_left, inactive_area_right,
326 inactive_area_top, inactive_area_bottom);
327 pr_info("synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
328 snap_left_on, snap_left_off, snap_right_on, snap_right_off,
329 snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
330
331 input_set_abs_params(ts->input_dev, ABS_X,
332 -inactive_area_left, max_x + inactive_area_right,
333 fuzz_x, 0);
334 input_set_abs_params(ts->input_dev, ABS_Y,
335 -inactive_area_top, max_y + inactive_area_bottom,
336 fuzz_y, 0);
337 input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
338}
339
340static struct synaptics_i2c_rmi_platform_data fake_pdata;
341
342static int __devinit synaptics_ts_probe(
343 struct i2c_client *client, const struct i2c_device_id *id)
344{
345 struct synaptics_ts_data *ts;
346 u8 buf0[4];
347 u8 buf1[8];
348 struct i2c_msg msg[2];
349 int ret = 0;
350 struct synaptics_i2c_rmi_platform_data *pdata;
351 u32 panel_version = 0;
352 u16 max_x, max_y;
353
354 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
355 pr_err("synaptics_ts_probe: need I2C_FUNC_I2C\n");
356 ret = -ENODEV;
357 goto err_check_functionality_failed;
358 }
359
360 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
361 pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
362 ret = -ENODEV;
363 goto err_check_functionality_failed;
364 }
365
366 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
367 pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
368 ret = -ENODEV;
369 goto err_check_functionality_failed;
370 }
371
372 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
373 if (ts == NULL) {
374 ret = -ENOMEM;
375 goto err_alloc_data_failed;
376 }
377 INIT_WORK(&ts->work, synaptics_ts_work_func);
378 ts->client = client;
379 i2c_set_clientdata(client, ts);
380 pdata = client->dev.platform_data;
381 if (pdata)
382 ts->power = pdata->power;
383 else
384 pdata = &fake_pdata;
385
386 if (ts->power) {
387 ret = ts->power(1);
388 if (ret < 0) {
389 pr_err("synaptics_ts_probe power on failed\n");
390 goto err_power_failed;
391 }
392 }
393
394 ret = detect(ts, &panel_version);
395 if (ret)
396 goto err_detect_failed;
397
398 while (pdata->version > panel_version)
399 pdata++;
400 ts->flags = pdata->flags;
401
402 ret = i2c_read(ts, 0xf0, "device control");
403 if (ret < 0)
404 goto err_detect_failed;
405 pr_info("synaptics: device control %x\n", ret);
406
407 ret = i2c_read(ts, 0xf1, "interrupt enable");
408 if (ret < 0)
409 goto err_detect_failed;
410 pr_info("synaptics_ts_probe: interrupt enable %x\n", ret);
411
412 ret = i2c_set(ts, 0xf1, 0, "disable interrupt");
413 if (ret < 0)
414 goto err_detect_failed;
415
416 msg[0].addr = ts->client->addr;
417 msg[0].flags = 0;
418 msg[0].len = 1;
419 msg[0].buf = buf0;
420 buf0[0] = 0xe0;
421 msg[1].addr = ts->client->addr;
422 msg[1].flags = I2C_M_RD;
423 msg[1].len = 8;
424 msg[1].buf = buf1;
425 ret = i2c_transfer(ts->client->adapter, msg, 2);
426 if (ret < 0) {
427 pr_err("i2c_transfer failed\n");
428 goto err_detect_failed;
429 }
430 pr_info("synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
431 buf1[0], buf1[1], buf1[2], buf1[3],
432 buf1[4], buf1[5], buf1[6], buf1[7]);
433
434 ret = i2c_set(ts, 0xff, 0x10, "page select = 0x10");
435 if (ret < 0)
436 goto err_detect_failed;
437
438 ret = i2c_smbus_read_word_data(ts->client, 0x04);
439 if (ret < 0) {
440 pr_err("i2c_smbus_read_word_data failed\n");
441 goto err_detect_failed;
442 }
443 ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
444 ret = i2c_smbus_read_word_data(ts->client, 0x06);
445 if (ret < 0) {
446 pr_err("i2c_smbus_read_word_data failed\n");
447 goto err_detect_failed;
448 }
449 ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
450 if (ts->flags & SYNAPTICS_SWAP_XY)
451 swap(max_x, max_y);
452
453 /* will also switch back to page 0x04 */
454 ret = synaptics_init_panel(ts);
455 if (ret < 0) {
456 pr_err("synaptics_init_panel failed\n");
457 goto err_detect_failed;
458 }
459
460 ts->input_dev = input_allocate_device();
461 if (ts->input_dev == NULL) {
462 ret = -ENOMEM;
463 pr_err("synaptics: Failed to allocate input device\n");
464 goto err_input_dev_alloc_failed;
465 }
466 ts->input_dev->name = "synaptics-rmi-touchscreen";
467 ts->input_dev->phys = "msm/input0";
468 ts->input_dev->id.bustype = BUS_I2C;
469
470 __set_bit(EV_SYN, ts->input_dev->evbit);
471 __set_bit(EV_KEY, ts->input_dev->evbit);
472 __set_bit(BTN_TOUCH, ts->input_dev->keybit);
473 __set_bit(EV_ABS, ts->input_dev->evbit);
474
475 compute_areas(ts, pdata, max_x, max_y);
476
477
478 ret = input_register_device(ts->input_dev);
479 if (ret) {
480 pr_err("synaptics: Unable to register %s input device\n",
481 ts->input_dev->name);
482 goto err_input_register_device_failed;
483 }
484 if (client->irq) {
485 ret = request_threaded_irq(client->irq, NULL,
486 synaptics_ts_irq_handler,
487 IRQF_TRIGGER_LOW|IRQF_ONESHOT,
488 client->name, ts);
489 if (ret == 0) {
490 ret = i2c_set(ts, 0xf1, 0x01, "enable abs int");
491 if (ret)
492 free_irq(client->irq, ts);
493 }
494 if (ret == 0)
495 ts->use_irq = 1;
496 else
497 dev_err(&client->dev, "request_irq failed\n");
498 }
499 if (!ts->use_irq) {
500 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
501 ts->timer.function = synaptics_ts_timer_func;
502 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
503 }
504#ifdef CONFIG_HAS_EARLYSUSPEND
505 ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
506 ts->early_suspend.suspend = synaptics_ts_early_suspend;
507 ts->early_suspend.resume = synaptics_ts_late_resume;
508 register_early_suspend(&ts->early_suspend);
509#endif
510
511 pr_info("synaptics: Start touchscreen %s in %s mode\n",
512 ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
513
514 return 0;
515
516err_input_register_device_failed:
517 input_free_device(ts->input_dev);
518
519err_input_dev_alloc_failed:
520err_detect_failed:
521err_power_failed:
522 kfree(ts);
523err_alloc_data_failed:
524err_check_functionality_failed:
525 return ret;
526}
527
528static int synaptics_ts_remove(struct i2c_client *client)
529{
530 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
531#ifdef CONFIG_HAS_EARLYSUSPEND
532 unregister_early_suspend(&ts->early_suspend);
533#endif
534 if (ts->use_irq)
535 free_irq(client->irq, ts);
536 else
537 hrtimer_cancel(&ts->timer);
538 input_unregister_device(ts->input_dev);
539 kfree(ts);
540 return 0;
541}
542
543#ifdef CONFIG_PM
544static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
545{
546 int ret;
547 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
548
549 if (ts->use_irq)
550 disable_irq(client->irq);
551 else
552 hrtimer_cancel(&ts->timer);
553 ret = cancel_work_sync(&ts->work);
554 if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
555 enable_irq(client->irq);
556 i2c_set(ts, 0xf1, 0, "disable interrupt");
557 i2c_set(ts, 0xf0, 0x86, "deep sleep");
558
559 if (ts->power) {
560 ret = ts->power(0);
561 if (ret < 0)
562 pr_err("synaptics_ts_suspend power off failed\n");
563 }
564 return 0;
565}
566
567static int synaptics_ts_resume(struct i2c_client *client)
568{
569 int ret;
570 struct synaptics_ts_data *ts = i2c_get_clientdata(client);
571
572 if (ts->power) {
573 ret = ts->power(1);
574 if (ret < 0)
575 pr_err("synaptics_ts_resume power on failed\n");
576 }
577
578 synaptics_init_panel(ts);
579
580 if (ts->use_irq) {
581 enable_irq(client->irq);
582 i2c_set(ts, 0xf1, 0x01, "enable abs int");
583 } else
584 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
585
586 return 0;
587}
588
589#ifdef CONFIG_HAS_EARLYSUSPEND
590static void synaptics_ts_early_suspend(struct early_suspend *h)
591{
592 struct synaptics_ts_data *ts;
593 ts = container_of(h, struct synaptics_ts_data, early_suspend);
594 synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
595}
596
597static void synaptics_ts_late_resume(struct early_suspend *h)
598{
599 struct synaptics_ts_data *ts;
600 ts = container_of(h, struct synaptics_ts_data, early_suspend);
601 synaptics_ts_resume(ts->client);
602}
603#endif
604#else
605#define synaptics_ts_suspend NULL
606#define synaptics_ts_resume NULL
607#endif
608
609
610
611static const struct i2c_device_id synaptics_ts_id[] = {
612 { SYNAPTICS_I2C_RMI_NAME, 0 },
613 { }
614};
615
616static struct i2c_driver synaptics_ts_driver = {
617 .probe = synaptics_ts_probe,
618 .remove = synaptics_ts_remove,
619#ifndef CONFIG_HAS_EARLYSUSPEND
620 .suspend = synaptics_ts_suspend,
621 .resume = synaptics_ts_resume,
622#endif
623 .id_table = synaptics_ts_id,
624 .driver = {
625 .name = SYNAPTICS_I2C_RMI_NAME,
626 },
627};
628
629static int __devinit synaptics_ts_init(void)
630{
631 synaptics_wq = create_singlethread_workqueue("synaptics_wq");
632 if (!synaptics_wq)
633 return -ENOMEM;
634 return i2c_add_driver(&synaptics_ts_driver);
635}
636
637static void __exit synaptics_ts_exit(void)
638{
639 i2c_del_driver(&synaptics_ts_driver);
640 if (synaptics_wq)
641 destroy_workqueue(synaptics_wq);
642}
643
644module_init(synaptics_ts_init);
645module_exit(synaptics_ts_exit);
646
647MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
648MODULE_LICENSE("GPL");
649MODULE_AUTHOR("Arve Hjønnevåg <arve@android.com>");
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.h b/drivers/staging/dream/synaptics_i2c_rmi.h
deleted file mode 100644
index ca51b2fc564d..000000000000
--- a/drivers/staging/dream/synaptics_i2c_rmi.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * include/linux/synaptics_i2c_rmi.h - platform data structure for f75375s sensor
3 *
4 * Copyright (C) 2008 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef _LINUX_SYNAPTICS_I2C_RMI_H
18#define _LINUX_SYNAPTICS_I2C_RMI_H
19
20#define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts"
21
22enum {
23 SYNAPTICS_FLIP_X = 1UL << 0,
24 SYNAPTICS_FLIP_Y = 1UL << 1,
25 SYNAPTICS_SWAP_XY = 1UL << 2,
26 SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3,
27};
28
29struct synaptics_i2c_rmi_platform_data {
30 uint32_t version; /* Use this entry for panels with */
31 /* (major << 8 | minor) version or above. */
32 /* If non-zero another array entry follows */
33 int (*power)(int on); /* Only valid in first array entry */
34 uint32_t flags;
35 uint32_t inactive_left; /* 0x10000 = screen width */
36 uint32_t inactive_right; /* 0x10000 = screen width */
37 uint32_t inactive_top; /* 0x10000 = screen height */
38 uint32_t inactive_bottom; /* 0x10000 = screen height */
39 uint32_t snap_left_on; /* 0x10000 = screen width */
40 uint32_t snap_left_off; /* 0x10000 = screen width */
41 uint32_t snap_right_on; /* 0x10000 = screen width */
42 uint32_t snap_right_off; /* 0x10000 = screen width */
43 uint32_t snap_top_on; /* 0x10000 = screen height */
44 uint32_t snap_top_off; /* 0x10000 = screen height */
45 uint32_t snap_bottom_on; /* 0x10000 = screen height */
46 uint32_t snap_bottom_off; /* 0x10000 = screen height */
47 uint32_t fuzz_x; /* 0x10000 = screen width */
48 uint32_t fuzz_y; /* 0x10000 = screen height */
49 int fuzz_p;
50 int fuzz_w;
51};
52
53#endif /* _LINUX_SYNAPTICS_I2C_RMI_H */