2 * ppi.c Analog Devices Parallel Peripheral Interface driver
4 * Copyright (c) 2011 Analog Devices Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <linux/module.h>
21 #include <linux/slab.h>
23 #include <asm/bfin_ppi.h>
24 #include <asm/blackfin.h>
25 #include <asm/cacheflush.h>
27 #include <asm/portmux.h>
29 #include <media/blackfin/ppi.h>
31 static int ppi_attach_irq(struct ppi_if
*ppi
, irq_handler_t handler
);
32 static void ppi_detach_irq(struct ppi_if
*ppi
);
33 static int ppi_start(struct ppi_if
*ppi
);
34 static int ppi_stop(struct ppi_if
*ppi
);
35 static int ppi_set_params(struct ppi_if
*ppi
, struct ppi_params
*params
);
36 static void ppi_update_addr(struct ppi_if
*ppi
, unsigned long addr
);
38 static const struct ppi_ops ppi_ops
= {
39 .attach_irq
= ppi_attach_irq
,
40 .detach_irq
= ppi_detach_irq
,
43 .set_params
= ppi_set_params
,
44 .update_addr
= ppi_update_addr
,
47 static irqreturn_t
ppi_irq_err(int irq
, void *dev_id
)
49 struct ppi_if
*ppi
= dev_id
;
50 const struct ppi_info
*info
= ppi
->info
;
55 struct bfin_ppi_regs
*reg
= info
->base
;
56 unsigned short status
;
58 /* register on bf561 is cleared when read
61 status
= bfin_read16(®
->status
);
64 bfin_write16(®
->status
, 0xff00);
69 struct bfin_eppi_regs
*reg
= info
->base
;
70 unsigned short status
;
72 status
= bfin_read16(®
->status
);
75 bfin_write16(®
->status
, 0xffff);
80 struct bfin_eppi3_regs
*reg
= info
->base
;
83 stat
= bfin_read32(®
->stat
);
86 bfin_write32(®
->stat
, 0xc0ff);
96 static int ppi_attach_irq(struct ppi_if
*ppi
, irq_handler_t handler
)
98 const struct ppi_info
*info
= ppi
->info
;
101 ret
= request_dma(info
->dma_ch
, "PPI_DMA");
104 pr_err("Unable to allocate DMA channel for PPI\n");
107 set_dma_callback(info
->dma_ch
, handler
, ppi
);
110 ret
= request_irq(info
->irq_err
, ppi_irq_err
, 0, "PPI ERROR", ppi
);
112 pr_err("Unable to allocate IRQ for PPI\n");
113 free_dma(info
->dma_ch
);
119 static void ppi_detach_irq(struct ppi_if
*ppi
)
121 const struct ppi_info
*info
= ppi
->info
;
124 free_irq(info
->irq_err
, ppi
);
125 free_dma(info
->dma_ch
);
128 static int ppi_start(struct ppi_if
*ppi
)
130 const struct ppi_info
*info
= ppi
->info
;
133 enable_dma(info
->dma_ch
);
136 ppi
->ppi_control
|= PORT_EN
;
137 switch (info
->type
) {
140 struct bfin_ppi_regs
*reg
= info
->base
;
141 bfin_write16(®
->control
, ppi
->ppi_control
);
146 struct bfin_eppi_regs
*reg
= info
->base
;
147 bfin_write32(®
->control
, ppi
->ppi_control
);
152 struct bfin_eppi3_regs
*reg
= info
->base
;
153 bfin_write32(®
->ctl
, ppi
->ppi_control
);
164 static int ppi_stop(struct ppi_if
*ppi
)
166 const struct ppi_info
*info
= ppi
->info
;
169 ppi
->ppi_control
&= ~PORT_EN
;
170 switch (info
->type
) {
173 struct bfin_ppi_regs
*reg
= info
->base
;
174 bfin_write16(®
->control
, ppi
->ppi_control
);
179 struct bfin_eppi_regs
*reg
= info
->base
;
180 bfin_write32(®
->control
, ppi
->ppi_control
);
185 struct bfin_eppi3_regs
*reg
= info
->base
;
186 bfin_write32(®
->ctl
, ppi
->ppi_control
);
194 clear_dma_irqstat(info
->dma_ch
);
195 disable_dma(info
->dma_ch
);
201 static int ppi_set_params(struct ppi_if
*ppi
, struct ppi_params
*params
)
203 const struct ppi_info
*info
= ppi
->info
;
205 int dma_config
, bytes_per_line
;
206 int hcount
, hdelay
, samples_per_line
;
208 bytes_per_line
= params
->width
* params
->bpp
/ 8;
209 /* convert parameters unit from pixels to samples */
210 hcount
= params
->width
* params
->bpp
/ params
->dlen
;
211 hdelay
= params
->hdelay
* params
->bpp
/ params
->dlen
;
212 samples_per_line
= params
->line
* params
->bpp
/ params
->dlen
;
213 if (params
->int_mask
== 0xFFFFFFFF)
214 ppi
->err_int
= false;
218 dma_config
= (DMA_FLOW_STOP
| RESTART
| DMA2D
| DI_EN_Y
);
219 ppi
->ppi_control
= params
->ppi_control
& ~PORT_EN
;
220 if (!(ppi
->ppi_control
& PORT_DIR
))
222 switch (info
->type
) {
225 struct bfin_ppi_regs
*reg
= info
->base
;
227 if (params
->ppi_control
& DMA32
)
230 bfin_write16(®
->control
, ppi
->ppi_control
);
231 bfin_write16(®
->count
, samples_per_line
- 1);
232 bfin_write16(®
->frame
, params
->frame
);
237 struct bfin_eppi_regs
*reg
= info
->base
;
239 if ((params
->ppi_control
& PACK_EN
)
240 || (params
->ppi_control
& 0x38000) > DLEN_16
)
243 bfin_write32(®
->control
, ppi
->ppi_control
);
244 bfin_write16(®
->line
, samples_per_line
);
245 bfin_write16(®
->frame
, params
->frame
);
246 bfin_write16(®
->hdelay
, hdelay
);
247 bfin_write16(®
->vdelay
, params
->vdelay
);
248 bfin_write16(®
->hcount
, hcount
);
249 bfin_write16(®
->vcount
, params
->height
);
254 struct bfin_eppi3_regs
*reg
= info
->base
;
256 if ((params
->ppi_control
& PACK_EN
)
257 || (params
->ppi_control
& 0x70000) > DLEN_16
)
260 bfin_write32(®
->ctl
, ppi
->ppi_control
);
261 bfin_write32(®
->line
, samples_per_line
);
262 bfin_write32(®
->frame
, params
->frame
);
263 bfin_write32(®
->hdly
, hdelay
);
264 bfin_write32(®
->vdly
, params
->vdelay
);
265 bfin_write32(®
->hcnt
, hcount
);
266 bfin_write32(®
->vcnt
, params
->height
);
267 if (params
->int_mask
)
268 bfin_write32(®
->imsk
, params
->int_mask
& 0xFF);
269 if (ppi
->ppi_control
& PORT_DIR
) {
270 u32 hsync_width
, vsync_width
, vsync_period
;
272 hsync_width
= params
->hsync
273 * params
->bpp
/ params
->dlen
;
274 vsync_width
= params
->vsync
* samples_per_line
;
275 vsync_period
= samples_per_line
* params
->frame
;
276 bfin_write32(®
->fs1_wlhb
, hsync_width
);
277 bfin_write32(®
->fs1_paspl
, samples_per_line
);
278 bfin_write32(®
->fs2_wlvb
, vsync_width
);
279 bfin_write32(®
->fs2_palpf
, vsync_period
);
288 dma_config
|= WDSIZE_32
| PSIZE_32
;
289 set_dma_x_count(info
->dma_ch
, bytes_per_line
>> 2);
290 set_dma_x_modify(info
->dma_ch
, 4);
291 set_dma_y_modify(info
->dma_ch
, 4);
293 dma_config
|= WDSIZE_16
| PSIZE_16
;
294 set_dma_x_count(info
->dma_ch
, bytes_per_line
>> 1);
295 set_dma_x_modify(info
->dma_ch
, 2);
296 set_dma_y_modify(info
->dma_ch
, 2);
298 set_dma_y_count(info
->dma_ch
, params
->height
);
299 set_dma_config(info
->dma_ch
, dma_config
);
305 static void ppi_update_addr(struct ppi_if
*ppi
, unsigned long addr
)
307 set_dma_start_addr(ppi
->info
->dma_ch
, addr
);
310 struct ppi_if
*ppi_create_instance(const struct ppi_info
*info
)
314 if (!info
|| !info
->pin_req
)
317 if (peripheral_request_list(info
->pin_req
, KBUILD_MODNAME
)) {
318 pr_err("request peripheral failed\n");
322 ppi
= kzalloc(sizeof(*ppi
), GFP_KERNEL
);
324 peripheral_free_list(info
->pin_req
);
325 pr_err("unable to allocate memory for ppi handle\n");
331 pr_info("ppi probe success\n");
334 EXPORT_SYMBOL(ppi_create_instance
);
336 void ppi_delete_instance(struct ppi_if
*ppi
)
338 peripheral_free_list(ppi
->info
->pin_req
);
341 EXPORT_SYMBOL(ppi_delete_instance
);
343 MODULE_DESCRIPTION("Analog Devices PPI driver");
344 MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
345 MODULE_LICENSE("GPL v2");