Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ppi.c
Go to the documentation of this file.
1 /*
2  * ppi.c Analog Devices Parallel Peripheral Interface driver
3  *
4  * Copyright (c) 2011 Analog Devices Inc.
5  *
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.
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  * 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.
18  */
19 
20 #include <linux/slab.h>
21 
22 #include <asm/bfin_ppi.h>
23 #include <asm/blackfin.h>
24 #include <asm/cacheflush.h>
25 #include <asm/dma.h>
26 #include <asm/portmux.h>
27 
28 #include <media/blackfin/ppi.h>
29 
30 static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler);
31 static void ppi_detach_irq(struct ppi_if *ppi);
32 static int ppi_start(struct ppi_if *ppi);
33 static int ppi_stop(struct ppi_if *ppi);
34 static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params);
35 static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr);
36 
37 static const struct ppi_ops ppi_ops = {
38  .attach_irq = ppi_attach_irq,
39  .detach_irq = ppi_detach_irq,
40  .start = ppi_start,
41  .stop = ppi_stop,
42  .set_params = ppi_set_params,
43  .update_addr = ppi_update_addr,
44 };
45 
46 static irqreturn_t ppi_irq_err(int irq, void *dev_id)
47 {
48  struct ppi_if *ppi = dev_id;
49  const struct ppi_info *info = ppi->info;
50 
51  switch (info->type) {
52  case PPI_TYPE_PPI:
53  {
54  struct bfin_ppi_regs *reg = info->base;
55  unsigned short status;
56 
57  /* register on bf561 is cleared when read
58  * others are W1C
59  */
60  status = bfin_read16(&reg->status);
61  bfin_write16(&reg->status, 0xff00);
62  break;
63  }
64  case PPI_TYPE_EPPI:
65  {
66  struct bfin_eppi_regs *reg = info->base;
67  bfin_write16(&reg->status, 0xffff);
68  break;
69  }
70  default:
71  break;
72  }
73 
74  return IRQ_HANDLED;
75 }
76 
77 static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler)
78 {
79  const struct ppi_info *info = ppi->info;
80  int ret;
81 
82  ret = request_dma(info->dma_ch, "PPI_DMA");
83 
84  if (ret) {
85  pr_err("Unable to allocate DMA channel for PPI\n");
86  return ret;
87  }
88  set_dma_callback(info->dma_ch, handler, ppi);
89 
90  if (ppi->err_int) {
91  ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi);
92  if (ret) {
93  pr_err("Unable to allocate IRQ for PPI\n");
94  free_dma(info->dma_ch);
95  }
96  }
97  return ret;
98 }
99 
100 static void ppi_detach_irq(struct ppi_if *ppi)
101 {
102  const struct ppi_info *info = ppi->info;
103 
104  if (ppi->err_int)
105  free_irq(info->irq_err, ppi);
106  free_dma(info->dma_ch);
107 }
108 
109 static int ppi_start(struct ppi_if *ppi)
110 {
111  const struct ppi_info *info = ppi->info;
112 
113  /* enable DMA */
114  enable_dma(info->dma_ch);
115 
116  /* enable PPI */
117  ppi->ppi_control |= PORT_EN;
118  switch (info->type) {
119  case PPI_TYPE_PPI:
120  {
121  struct bfin_ppi_regs *reg = info->base;
122  bfin_write16(&reg->control, ppi->ppi_control);
123  break;
124  }
125  case PPI_TYPE_EPPI:
126  {
127  struct bfin_eppi_regs *reg = info->base;
128  bfin_write32(&reg->control, ppi->ppi_control);
129  break;
130  }
131  default:
132  return -EINVAL;
133  }
134 
135  SSYNC();
136  return 0;
137 }
138 
139 static int ppi_stop(struct ppi_if *ppi)
140 {
141  const struct ppi_info *info = ppi->info;
142 
143  /* disable PPI */
144  ppi->ppi_control &= ~PORT_EN;
145  switch (info->type) {
146  case PPI_TYPE_PPI:
147  {
148  struct bfin_ppi_regs *reg = info->base;
149  bfin_write16(&reg->control, ppi->ppi_control);
150  break;
151  }
152  case PPI_TYPE_EPPI:
153  {
154  struct bfin_eppi_regs *reg = info->base;
155  bfin_write32(&reg->control, ppi->ppi_control);
156  break;
157  }
158  default:
159  return -EINVAL;
160  }
161 
162  /* disable DMA */
163  clear_dma_irqstat(info->dma_ch);
164  disable_dma(info->dma_ch);
165 
166  SSYNC();
167  return 0;
168 }
169 
170 static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
171 {
172  const struct ppi_info *info = ppi->info;
173  int dma32 = 0;
174  int dma_config, bytes_per_line, lines_per_frame;
175 
176  bytes_per_line = params->width * params->bpp / 8;
177  lines_per_frame = params->height;
178  if (params->int_mask == 0xFFFFFFFF)
179  ppi->err_int = false;
180  else
181  ppi->err_int = true;
182 
183  dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN);
184  ppi->ppi_control = params->ppi_control & ~PORT_EN;
185  switch (info->type) {
186  case PPI_TYPE_PPI:
187  {
188  struct bfin_ppi_regs *reg = info->base;
189 
190  if (params->ppi_control & DMA32)
191  dma32 = 1;
192 
193  bfin_write16(&reg->control, ppi->ppi_control);
194  bfin_write16(&reg->count, bytes_per_line - 1);
195  bfin_write16(&reg->frame, lines_per_frame);
196  break;
197  }
198  case PPI_TYPE_EPPI:
199  {
200  struct bfin_eppi_regs *reg = info->base;
201 
202  if ((params->ppi_control & PACK_EN)
203  || (params->ppi_control & 0x38000) > DLEN_16)
204  dma32 = 1;
205 
206  bfin_write32(&reg->control, ppi->ppi_control);
207  bfin_write16(&reg->line, bytes_per_line + params->blank_clocks);
208  bfin_write16(&reg->frame, lines_per_frame);
209  bfin_write16(&reg->hdelay, 0);
210  bfin_write16(&reg->vdelay, 0);
211  bfin_write16(&reg->hcount, bytes_per_line);
212  bfin_write16(&reg->vcount, lines_per_frame);
213  break;
214  }
215  default:
216  return -EINVAL;
217  }
218 
219  if (dma32) {
220  dma_config |= WDSIZE_32;
221  set_dma_x_count(info->dma_ch, bytes_per_line >> 2);
222  set_dma_x_modify(info->dma_ch, 4);
223  set_dma_y_modify(info->dma_ch, 4);
224  } else {
225  dma_config |= WDSIZE_16;
226  set_dma_x_count(info->dma_ch, bytes_per_line >> 1);
227  set_dma_x_modify(info->dma_ch, 2);
228  set_dma_y_modify(info->dma_ch, 2);
229  }
230  set_dma_y_count(info->dma_ch, lines_per_frame);
231  set_dma_config(info->dma_ch, dma_config);
232 
233  SSYNC();
234  return 0;
235 }
236 
237 static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr)
238 {
239  set_dma_start_addr(ppi->info->dma_ch, addr);
240 }
241 
242 struct ppi_if *ppi_create_instance(const struct ppi_info *info)
243 {
244  struct ppi_if *ppi;
245 
246  if (!info || !info->pin_req)
247  return NULL;
248 
249  if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
250  pr_err("request peripheral failed\n");
251  return NULL;
252  }
253 
254  ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
255  if (!ppi) {
257  pr_err("unable to allocate memory for ppi handle\n");
258  return NULL;
259  }
260  ppi->ops = &ppi_ops;
261  ppi->info = info;
262 
263  pr_info("ppi probe success\n");
264  return ppi;
265 }
266 
267 void ppi_delete_instance(struct ppi_if *ppi)
268 {
269  peripheral_free_list(ppi->info->pin_req);
270  kfree(ppi);
271 }