]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/demo/demo-shape.c
Merge branch 'master' of git://git.denx.de/u-boot-mips
[karo-tx-uboot.git] / drivers / demo / demo-shape.c
1 /*
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
15 DECLARE_GLOBAL_DATA_PTR;
16
17 /* Shape size */
18 #define WIDTH   8
19 #define HEIGHT  6
20
21 struct 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 */
26 static int shape_hello(struct device *dev, int ch)
27 {
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
84 static int shape_status(struct device *dev, int *status)
85 {
86         struct shape_data *data = dev_get_priv(dev);
87
88         *status = data->num_chars;
89         return 0;
90 }
91
92 static const struct demo_ops shape_ops = {
93         .hello = shape_hello,
94         .status = shape_status,
95 };
96
97 static int shape_ofdata_to_platdata(struct device *dev)
98 {
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
114 static const struct device_id demo_shape_id[] = {
115         { "demo-shape", 0 },
116         { },
117 };
118
119 U_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 };