blob: 3fa9c5994703d473494a4d2199ecae3e34a0c9c0 [file] [log] [blame]
Simon Glass63b17572014-02-26 15:59:23 -07001/*
2 * Copyright (c) 2013 Google, Inc
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <errno.h>
10#include <fdtdec.h>
11#include <malloc.h>
12#include <dm-demo.h>
13#include <asm/io.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17/* Shape size */
18#define WIDTH 8
19#define HEIGHT 6
20
21struct shape_data {
22 int num_chars; /* Number of non-space characters output so far */
23};
24
25/* Crazy little function to draw shapes on the console */
Heiko Schocherb74fcb42014-05-22 12:43:05 +020026static int shape_hello(struct udevice *dev, int ch)
Simon Glass63b17572014-02-26 15:59:23 -070027{
28 const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
29 struct shape_data *data = dev_get_priv(dev);
30 static const struct shape {
31 int start;
32 int end;
33 int dstart;
34 int dend;
35 } shapes[3] = {
36 { 0, 1, 0, 1 },
37 { 0, WIDTH, 0, 0 },
38 { HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
39 };
40 struct shape shape;
41 unsigned int index;
42 int line, pos, inside;
43 const char *colour = pdata->colour;
44 int first = 0;
45
46 if (!ch)
47 ch = pdata->default_char;
48 if (!ch)
49 ch = '@';
50
51 index = (pdata->sides / 2) - 1;
52 if (index >= ARRAY_SIZE(shapes))
53 return -EIO;
54 shape = shapes[index];
55
56 for (line = 0; line < HEIGHT; line++) {
57 first = 1;
58 for (pos = 0; pos < WIDTH; pos++) {
59 inside = pos >= shape.start && pos < shape.end;
60 if (inside) {
61 putc(first ? *colour++ : ch);
62 data->num_chars++;
63 first = 0;
64 if (!*colour)
65 colour = pdata->colour;
66 } else {
67 putc(' ');
68 }
69 }
70 putc('\n');
71 shape.start += shape.dstart;
72 shape.end += shape.dend;
73 if (shape.start < 0) {
74 shape.dstart = -shape.dstart;
75 shape.dend = -shape.dend;
76 shape.start += shape.dstart;
77 shape.end += shape.dend;
78 }
79 }
80
81 return 0;
82}
83
Heiko Schocherb74fcb42014-05-22 12:43:05 +020084static int shape_status(struct udevice *dev, int *status)
Simon Glass63b17572014-02-26 15:59:23 -070085{
86 struct shape_data *data = dev_get_priv(dev);
87
88 *status = data->num_chars;
89 return 0;
90}
91
92static const struct demo_ops shape_ops = {
93 .hello = shape_hello,
94 .status = shape_status,
95};
96
Heiko Schocherb74fcb42014-05-22 12:43:05 +020097static int shape_ofdata_to_platdata(struct udevice *dev)
Simon Glass63b17572014-02-26 15:59:23 -070098{
99 struct dm_demo_pdata *pdata = dev_get_platdata(dev);
100 int ret;
101
102 /* Parse the data that is common with all demo devices */
103 ret = demo_parse_dt(dev);
104 if (ret)
105 return ret;
106
107 /* Parse the data that only we need */
108 pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
109 "character", '@');
110
111 return 0;
112}
113
Simon Glass767827a2014-06-11 23:29:45 -0600114static const struct udevice_id demo_shape_id[] = {
Simon Glass63b17572014-02-26 15:59:23 -0700115 { "demo-shape", 0 },
116 { },
117};
118
119U_BOOT_DRIVER(demo_shape_drv) = {
120 .name = "demo_shape_drv",
121 .of_match = demo_shape_id,
122 .id = UCLASS_DEMO,
123 .ofdata_to_platdata = shape_ofdata_to_platdata,
124 .ops = &shape_ops,
125 .priv_auto_alloc_size = sizeof(struct shape_data),
126 .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
127};