• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Driver for the Atmel on-chip Audio Bitstream DAC (ABDAC)
3  *
4  * Copyright (C) 2006-2009 Atmel Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by
8  * the Free Software Foundation.
9  */
10 #include <linux/clk.h>
11 #include <linux/bitmap.h>
12 #include <linux/dmaengine.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/init.h>
15 #include <linux/interrupt.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/types.h>
19 #include <linux/io.h>
20 
21 #include <sound/core.h>
22 #include <sound/initval.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/atmel-abdac.h>
26 
27 #include <linux/platform_data/dma-dw.h>
28 #include <linux/dma/dw.h>
29 
30 /* DAC register offsets */
31 #define DAC_DATA                                0x0000
32 #define DAC_CTRL                                0x0008
33 #define DAC_INT_MASK                            0x000c
34 #define DAC_INT_EN                              0x0010
35 #define DAC_INT_DIS                             0x0014
36 #define DAC_INT_CLR                             0x0018
37 #define DAC_INT_STATUS                          0x001c
38 
39 /* Bitfields in CTRL */
40 #define DAC_SWAP_OFFSET                         30
41 #define DAC_SWAP_SIZE                           1
42 #define DAC_EN_OFFSET                           31
43 #define DAC_EN_SIZE                             1
44 
45 /* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */
46 #define DAC_UNDERRUN_OFFSET                     28
47 #define DAC_UNDERRUN_SIZE                       1
48 #define DAC_TX_READY_OFFSET                     29
49 #define DAC_TX_READY_SIZE                       1
50 
51 /* Bit manipulation macros */
52 #define DAC_BIT(name)					\
53 	(1 << DAC_##name##_OFFSET)
54 #define DAC_BF(name, value)				\
55 	(((value) & ((1 << DAC_##name##_SIZE) - 1))	\
56 	 << DAC_##name##_OFFSET)
57 #define DAC_BFEXT(name, value)				\
58 	(((value) >> DAC_##name##_OFFSET)		\
59 	 & ((1 << DAC_##name##_SIZE) - 1))
60 #define DAC_BFINS(name, value, old)			\
61 	(((old) & ~(((1 << DAC_##name##_SIZE) - 1)	\
62 		    << DAC_##name##_OFFSET))		\
63 	 | DAC_BF(name, value))
64 
65 /* Register access macros */
66 #define dac_readl(port, reg)				\
67 	__raw_readl((port)->regs + DAC_##reg)
68 #define dac_writel(port, reg, value)			\
69 	__raw_writel((value), (port)->regs + DAC_##reg)
70 
71 /*
72  * ABDAC supports a maximum of 6 different rates from a generic clock. The
73  * generic clock has a power of two divider, which gives 6 steps from 192 kHz
74  * to 5112 Hz.
75  */
76 #define MAX_NUM_RATES	6
77 /* ALSA seems to use rates between 192000 Hz and 5112 Hz. */
78 #define RATE_MAX	192000
79 #define RATE_MIN	5112
80 
81 enum {
82 	DMA_READY = 0,
83 };
84 
85 struct atmel_abdac_dma {
86 	struct dma_chan		*chan;
87 	struct dw_cyclic_desc	*cdesc;
88 };
89 
90 struct atmel_abdac {
91 	struct clk				*pclk;
92 	struct clk				*sample_clk;
93 	struct platform_device			*pdev;
94 	struct atmel_abdac_dma			dma;
95 
96 	struct snd_pcm_hw_constraint_list	constraints_rates;
97 	struct snd_pcm_substream		*substream;
98 	struct snd_card				*card;
99 	struct snd_pcm				*pcm;
100 
101 	void __iomem				*regs;
102 	unsigned long				flags;
103 	unsigned int				rates[MAX_NUM_RATES];
104 	unsigned int				rates_num;
105 	int					irq;
106 };
107 
108 #define get_dac(card) ((struct atmel_abdac *)(card)->private_data)
109 
110 /* This function is called by the DMA driver. */
atmel_abdac_dma_period_done(void * arg)111 static void atmel_abdac_dma_period_done(void *arg)
112 {
113 	struct atmel_abdac *dac = arg;
114 	snd_pcm_period_elapsed(dac->substream);
115 }
116 
atmel_abdac_prepare_dma(struct atmel_abdac * dac,struct snd_pcm_substream * substream,enum dma_data_direction direction)117 static int atmel_abdac_prepare_dma(struct atmel_abdac *dac,
118 		struct snd_pcm_substream *substream,
119 		enum dma_data_direction direction)
120 {
121 	struct dma_chan			*chan = dac->dma.chan;
122 	struct dw_cyclic_desc		*cdesc;
123 	struct snd_pcm_runtime		*runtime = substream->runtime;
124 	unsigned long			buffer_len, period_len;
125 
126 	/*
127 	 * We don't do DMA on "complex" transfers, i.e. with
128 	 * non-halfword-aligned buffers or lengths.
129 	 */
130 	if (runtime->dma_addr & 1 || runtime->buffer_size & 1) {
131 		dev_dbg(&dac->pdev->dev, "too complex transfer\n");
132 		return -EINVAL;
133 	}
134 
135 	buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
136 	period_len = frames_to_bytes(runtime, runtime->period_size);
137 
138 	cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
139 			period_len, DMA_MEM_TO_DEV);
140 	if (IS_ERR(cdesc)) {
141 		dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n");
142 		return PTR_ERR(cdesc);
143 	}
144 
145 	cdesc->period_callback = atmel_abdac_dma_period_done;
146 	cdesc->period_callback_param = dac;
147 
148 	dac->dma.cdesc = cdesc;
149 
150 	set_bit(DMA_READY, &dac->flags);
151 
152 	return 0;
153 }
154 
155 static struct snd_pcm_hardware atmel_abdac_hw = {
156 	.info			= (SNDRV_PCM_INFO_MMAP
157 				  | SNDRV_PCM_INFO_MMAP_VALID
158 				  | SNDRV_PCM_INFO_INTERLEAVED
159 				  | SNDRV_PCM_INFO_BLOCK_TRANSFER
160 				  | SNDRV_PCM_INFO_RESUME
161 				  | SNDRV_PCM_INFO_PAUSE),
162 	.formats		= (SNDRV_PCM_FMTBIT_S16_BE),
163 	.rates			= (SNDRV_PCM_RATE_KNOT),
164 	.rate_min		= RATE_MIN,
165 	.rate_max		= RATE_MAX,
166 	.channels_min		= 2,
167 	.channels_max		= 2,
168 	.buffer_bytes_max	= 64 * 4096,
169 	.period_bytes_min	= 4096,
170 	.period_bytes_max	= 4096,
171 	.periods_min		= 6,
172 	.periods_max		= 64,
173 };
174 
atmel_abdac_open(struct snd_pcm_substream * substream)175 static int atmel_abdac_open(struct snd_pcm_substream *substream)
176 {
177 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
178 
179 	dac->substream = substream;
180 	atmel_abdac_hw.rate_max = dac->rates[dac->rates_num - 1];
181 	atmel_abdac_hw.rate_min = dac->rates[0];
182 	substream->runtime->hw = atmel_abdac_hw;
183 
184 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
185 			SNDRV_PCM_HW_PARAM_RATE, &dac->constraints_rates);
186 }
187 
atmel_abdac_close(struct snd_pcm_substream * substream)188 static int atmel_abdac_close(struct snd_pcm_substream *substream)
189 {
190 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
191 	dac->substream = NULL;
192 	return 0;
193 }
194 
atmel_abdac_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)195 static int atmel_abdac_hw_params(struct snd_pcm_substream *substream,
196 		struct snd_pcm_hw_params *hw_params)
197 {
198 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
199 	int retval;
200 
201 	retval = snd_pcm_lib_malloc_pages(substream,
202 			params_buffer_bytes(hw_params));
203 	if (retval < 0)
204 		return retval;
205 	/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
206 	if (retval == 1)
207 		if (test_and_clear_bit(DMA_READY, &dac->flags))
208 			dw_dma_cyclic_free(dac->dma.chan);
209 
210 	return retval;
211 }
212 
atmel_abdac_hw_free(struct snd_pcm_substream * substream)213 static int atmel_abdac_hw_free(struct snd_pcm_substream *substream)
214 {
215 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
216 	if (test_and_clear_bit(DMA_READY, &dac->flags))
217 		dw_dma_cyclic_free(dac->dma.chan);
218 	return snd_pcm_lib_free_pages(substream);
219 }
220 
atmel_abdac_prepare(struct snd_pcm_substream * substream)221 static int atmel_abdac_prepare(struct snd_pcm_substream *substream)
222 {
223 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
224 	int retval;
225 
226 	retval = clk_set_rate(dac->sample_clk, 256 * substream->runtime->rate);
227 	if (retval)
228 		return retval;
229 
230 	if (!test_bit(DMA_READY, &dac->flags))
231 		retval = atmel_abdac_prepare_dma(dac, substream, DMA_TO_DEVICE);
232 
233 	return retval;
234 }
235 
atmel_abdac_trigger(struct snd_pcm_substream * substream,int cmd)236 static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd)
237 {
238 	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
239 	int retval = 0;
240 
241 	switch (cmd) {
242 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
243 	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
244 	case SNDRV_PCM_TRIGGER_START:
245 		clk_prepare_enable(dac->sample_clk);
246 		retval = dw_dma_cyclic_start(dac->dma.chan);
247 		if (retval)
248 			goto out;
249 		dac_writel(dac, CTRL, DAC_BIT(EN));
250 		break;
251 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
252 	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
253 	case SNDRV_PCM_TRIGGER_STOP:
254 		dw_dma_cyclic_stop(dac->dma.chan);
255 		dac_writel(dac, DATA, 0);
256 		dac_writel(dac, CTRL, 0);
257 		clk_disable_unprepare(dac->sample_clk);
258 		break;
259 	default:
260 		retval = -EINVAL;
261 		break;
262 	}
263 out:
264 	return retval;
265 }
266 
267 static snd_pcm_uframes_t
atmel_abdac_pointer(struct snd_pcm_substream * substream)268 atmel_abdac_pointer(struct snd_pcm_substream *substream)
269 {
270 	struct atmel_abdac	*dac = snd_pcm_substream_chip(substream);
271 	struct snd_pcm_runtime	*runtime = substream->runtime;
272 	snd_pcm_uframes_t	frames;
273 	unsigned long		bytes;
274 
275 	bytes = dw_dma_get_src_addr(dac->dma.chan);
276 	bytes -= runtime->dma_addr;
277 
278 	frames = bytes_to_frames(runtime, bytes);
279 	if (frames >= runtime->buffer_size)
280 		frames -= runtime->buffer_size;
281 
282 	return frames;
283 }
284 
abdac_interrupt(int irq,void * dev_id)285 static irqreturn_t abdac_interrupt(int irq, void *dev_id)
286 {
287 	struct atmel_abdac *dac = dev_id;
288 	u32 status;
289 
290 	status = dac_readl(dac, INT_STATUS);
291 	if (status & DAC_BIT(UNDERRUN)) {
292 		dev_err(&dac->pdev->dev, "underrun detected\n");
293 		dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN));
294 	} else {
295 		dev_err(&dac->pdev->dev, "spurious interrupt (status=0x%x)\n",
296 			status);
297 		dac_writel(dac, INT_CLR, status);
298 	}
299 
300 	return IRQ_HANDLED;
301 }
302 
303 static struct snd_pcm_ops atmel_abdac_ops = {
304 	.open		= atmel_abdac_open,
305 	.close		= atmel_abdac_close,
306 	.ioctl		= snd_pcm_lib_ioctl,
307 	.hw_params	= atmel_abdac_hw_params,
308 	.hw_free	= atmel_abdac_hw_free,
309 	.prepare	= atmel_abdac_prepare,
310 	.trigger	= atmel_abdac_trigger,
311 	.pointer	= atmel_abdac_pointer,
312 };
313 
atmel_abdac_pcm_new(struct atmel_abdac * dac)314 static int atmel_abdac_pcm_new(struct atmel_abdac *dac)
315 {
316 	struct snd_pcm_hardware hw = atmel_abdac_hw;
317 	struct snd_pcm *pcm;
318 	int retval;
319 
320 	retval = snd_pcm_new(dac->card, dac->card->shortname,
321 			dac->pdev->id, 1, 0, &pcm);
322 	if (retval)
323 		return retval;
324 
325 	strcpy(pcm->name, dac->card->shortname);
326 	pcm->private_data = dac;
327 	pcm->info_flags = 0;
328 	dac->pcm = pcm;
329 
330 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_abdac_ops);
331 
332 	retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
333 			&dac->pdev->dev, hw.periods_min * hw.period_bytes_min,
334 			hw.buffer_bytes_max);
335 
336 	return retval;
337 }
338 
filter(struct dma_chan * chan,void * slave)339 static bool filter(struct dma_chan *chan, void *slave)
340 {
341 	struct dw_dma_slave *dws = slave;
342 
343 	if (dws->dma_dev == chan->device->dev) {
344 		chan->private = dws;
345 		return true;
346 	} else
347 		return false;
348 }
349 
set_sample_rates(struct atmel_abdac * dac)350 static int set_sample_rates(struct atmel_abdac *dac)
351 {
352 	long new_rate = RATE_MAX;
353 	int retval = -EINVAL;
354 	int index = 0;
355 
356 	/* we start at 192 kHz and work our way down to 5112 Hz */
357 	while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) {
358 		new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate);
359 		if (new_rate <= 0)
360 			break;
361 		/* make sure we are below the ABDAC clock */
362 		if (index < MAX_NUM_RATES &&
363 		    new_rate <= clk_get_rate(dac->pclk)) {
364 			dac->rates[index] = new_rate / 256;
365 			index++;
366 		}
367 		/* divide by 256 and then by two to get next rate */
368 		new_rate /= 256 * 2;
369 	}
370 
371 	if (index) {
372 		int i;
373 
374 		/* reverse array, smallest go first */
375 		for (i = 0; i < (index / 2); i++) {
376 			unsigned int tmp = dac->rates[index - 1 - i];
377 			dac->rates[index - 1 - i] = dac->rates[i];
378 			dac->rates[i] = tmp;
379 		}
380 
381 		dac->constraints_rates.count = index;
382 		dac->constraints_rates.list = dac->rates;
383 		dac->constraints_rates.mask = 0;
384 		dac->rates_num = index;
385 
386 		retval = 0;
387 	}
388 
389 	return retval;
390 }
391 
atmel_abdac_probe(struct platform_device * pdev)392 static int atmel_abdac_probe(struct platform_device *pdev)
393 {
394 	struct snd_card		*card;
395 	struct atmel_abdac	*dac;
396 	struct resource		*regs;
397 	struct atmel_abdac_pdata	*pdata;
398 	struct clk		*pclk;
399 	struct clk		*sample_clk;
400 	int			retval;
401 	int			irq;
402 
403 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
404 	if (!regs) {
405 		dev_dbg(&pdev->dev, "no memory resource\n");
406 		return -ENXIO;
407 	}
408 
409 	irq = platform_get_irq(pdev, 0);
410 	if (irq < 0) {
411 		dev_dbg(&pdev->dev, "could not get IRQ number\n");
412 		return irq;
413 	}
414 
415 	pdata = pdev->dev.platform_data;
416 	if (!pdata) {
417 		dev_dbg(&pdev->dev, "no platform data\n");
418 		return -ENXIO;
419 	}
420 
421 	pclk = clk_get(&pdev->dev, "pclk");
422 	if (IS_ERR(pclk)) {
423 		dev_dbg(&pdev->dev, "no peripheral clock\n");
424 		return PTR_ERR(pclk);
425 	}
426 	sample_clk = clk_get(&pdev->dev, "sample_clk");
427 	if (IS_ERR(sample_clk)) {
428 		dev_dbg(&pdev->dev, "no sample clock\n");
429 		retval = PTR_ERR(sample_clk);
430 		goto out_put_pclk;
431 	}
432 	clk_prepare_enable(pclk);
433 
434 	retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
435 			      SNDRV_DEFAULT_STR1, THIS_MODULE,
436 			      sizeof(struct atmel_abdac), &card);
437 	if (retval) {
438 		dev_dbg(&pdev->dev, "could not create sound card device\n");
439 		goto out_put_sample_clk;
440 	}
441 
442 	dac = get_dac(card);
443 
444 	dac->irq = irq;
445 	dac->card = card;
446 	dac->pclk = pclk;
447 	dac->sample_clk = sample_clk;
448 	dac->pdev = pdev;
449 
450 	retval = set_sample_rates(dac);
451 	if (retval < 0) {
452 		dev_dbg(&pdev->dev, "could not set supported rates\n");
453 		goto out_free_card;
454 	}
455 
456 	dac->regs = ioremap(regs->start, resource_size(regs));
457 	if (!dac->regs) {
458 		dev_dbg(&pdev->dev, "could not remap register memory\n");
459 		retval = -ENOMEM;
460 		goto out_free_card;
461 	}
462 
463 	/* make sure the DAC is silent and disabled */
464 	dac_writel(dac, DATA, 0);
465 	dac_writel(dac, CTRL, 0);
466 
467 	retval = request_irq(irq, abdac_interrupt, 0, "abdac", dac);
468 	if (retval) {
469 		dev_dbg(&pdev->dev, "could not request irq\n");
470 		goto out_unmap_regs;
471 	}
472 
473 	if (pdata->dws.dma_dev) {
474 		dma_cap_mask_t mask;
475 
476 		dma_cap_zero(mask);
477 		dma_cap_set(DMA_SLAVE, mask);
478 
479 		dac->dma.chan = dma_request_channel(mask, filter, &pdata->dws);
480 		if (dac->dma.chan) {
481 			struct dma_slave_config dma_conf = {
482 				.dst_addr = regs->start + DAC_DATA,
483 				.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
484 				.src_maxburst = 1,
485 				.dst_maxburst = 1,
486 				.direction = DMA_MEM_TO_DEV,
487 				.device_fc = false,
488 			};
489 
490 			dmaengine_slave_config(dac->dma.chan, &dma_conf);
491 		}
492 	}
493 	if (!pdata->dws.dma_dev || !dac->dma.chan) {
494 		dev_dbg(&pdev->dev, "DMA not available\n");
495 		retval = -ENODEV;
496 		goto out_unmap_regs;
497 	}
498 
499 	strcpy(card->driver, "Atmel ABDAC");
500 	strcpy(card->shortname, "Atmel ABDAC");
501 	sprintf(card->longname, "Atmel Audio Bitstream DAC");
502 
503 	retval = atmel_abdac_pcm_new(dac);
504 	if (retval) {
505 		dev_dbg(&pdev->dev, "could not register ABDAC pcm device\n");
506 		goto out_release_dma;
507 	}
508 
509 	retval = snd_card_register(card);
510 	if (retval) {
511 		dev_dbg(&pdev->dev, "could not register sound card\n");
512 		goto out_release_dma;
513 	}
514 
515 	platform_set_drvdata(pdev, card);
516 
517 	dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n",
518 			dac->regs, dev_name(&dac->dma.chan->dev->device));
519 
520 	return retval;
521 
522 out_release_dma:
523 	dma_release_channel(dac->dma.chan);
524 	dac->dma.chan = NULL;
525 out_unmap_regs:
526 	iounmap(dac->regs);
527 out_free_card:
528 	snd_card_free(card);
529 out_put_sample_clk:
530 	clk_put(sample_clk);
531 	clk_disable_unprepare(pclk);
532 out_put_pclk:
533 	clk_put(pclk);
534 	return retval;
535 }
536 
537 #ifdef CONFIG_PM_SLEEP
atmel_abdac_suspend(struct device * pdev)538 static int atmel_abdac_suspend(struct device *pdev)
539 {
540 	struct snd_card *card = dev_get_drvdata(pdev);
541 	struct atmel_abdac *dac = card->private_data;
542 
543 	dw_dma_cyclic_stop(dac->dma.chan);
544 	clk_disable_unprepare(dac->sample_clk);
545 	clk_disable_unprepare(dac->pclk);
546 
547 	return 0;
548 }
549 
atmel_abdac_resume(struct device * pdev)550 static int atmel_abdac_resume(struct device *pdev)
551 {
552 	struct snd_card *card = dev_get_drvdata(pdev);
553 	struct atmel_abdac *dac = card->private_data;
554 
555 	clk_prepare_enable(dac->pclk);
556 	clk_prepare_enable(dac->sample_clk);
557 	if (test_bit(DMA_READY, &dac->flags))
558 		dw_dma_cyclic_start(dac->dma.chan);
559 
560 	return 0;
561 }
562 
563 static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
564 #define ATMEL_ABDAC_PM_OPS	&atmel_abdac_pm
565 #else
566 #define ATMEL_ABDAC_PM_OPS	NULL
567 #endif
568 
atmel_abdac_remove(struct platform_device * pdev)569 static int atmel_abdac_remove(struct platform_device *pdev)
570 {
571 	struct snd_card *card = platform_get_drvdata(pdev);
572 	struct atmel_abdac *dac = get_dac(card);
573 
574 	clk_put(dac->sample_clk);
575 	clk_disable_unprepare(dac->pclk);
576 	clk_put(dac->pclk);
577 
578 	dma_release_channel(dac->dma.chan);
579 	dac->dma.chan = NULL;
580 	iounmap(dac->regs);
581 	free_irq(dac->irq, dac);
582 	snd_card_free(card);
583 
584 	return 0;
585 }
586 
587 static struct platform_driver atmel_abdac_driver = {
588 	.remove		= atmel_abdac_remove,
589 	.driver		= {
590 		.name	= "atmel_abdac",
591 		.pm	= ATMEL_ABDAC_PM_OPS,
592 	},
593 };
594 
atmel_abdac_init(void)595 static int __init atmel_abdac_init(void)
596 {
597 	return platform_driver_probe(&atmel_abdac_driver,
598 			atmel_abdac_probe);
599 }
600 module_init(atmel_abdac_init);
601 
atmel_abdac_exit(void)602 static void __exit atmel_abdac_exit(void)
603 {
604 	platform_driver_unregister(&atmel_abdac_driver);
605 }
606 module_exit(atmel_abdac_exit);
607 
608 MODULE_LICENSE("GPL");
609 MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)");
610 MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
611