u-boot-brain/drivers/demo/demo-shape.c
Simon Glass 41575d8e4c dm: treewide: Rename auto_alloc_size members to be shorter
This construct is quite long-winded. In earlier days it made some sense
since auto-allocation was a strange concept. But with driver model now
used pretty universally, we can shorten this to 'auto'. This reduces
verbosity and makes it easier to read.

Coincidentally it also ensures that every declaration is on one line,
thus making dtoc's job easier.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-12-13 08:00:25 -07:00

199 lines
4.0 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2013 Google, Inc
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
#include <dm-demo.h>
#include <asm/io.h>
#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
/* Shape size */
#define WIDTH 8
#define HEIGHT 6
struct shape_data {
int num_chars; /* Number of non-space characters output so far */
struct gpio_desc gpio_desc[8];
int gpio_count;
};
/* Crazy little function to draw shapes on the console */
static int shape_hello(struct udevice *dev, int ch)
{
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
struct shape_data *data = dev_get_priv(dev);
static const struct shape {
int start;
int end;
int dstart;
int dend;
} shapes[3] = {
{ 0, 1, 0, 1 },
{ 0, WIDTH, 0, 0 },
{ HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
};
struct shape shape;
unsigned int index;
int line, pos, inside;
const char *colour = pdata->colour;
int first = 0;
if (!ch)
ch = pdata->default_char;
if (!ch)
ch = '@';
index = (pdata->sides / 2) - 1;
if (index >= ARRAY_SIZE(shapes))
return -EIO;
shape = shapes[index];
for (line = 0; line < HEIGHT; line++) {
first = 1;
for (pos = 0; pos < WIDTH; pos++) {
inside = pos >= shape.start && pos < shape.end;
if (inside) {
putc(first ? *colour++ : ch);
data->num_chars++;
first = 0;
if (!*colour)
colour = pdata->colour;
} else {
putc(' ');
}
}
putc('\n');
shape.start += shape.dstart;
shape.end += shape.dend;
if (shape.start < 0) {
shape.dstart = -shape.dstart;
shape.dend = -shape.dend;
shape.start += shape.dstart;
shape.end += shape.dend;
}
}
return 0;
}
static int shape_status(struct udevice *dev, int *status)
{
struct shape_data *data = dev_get_priv(dev);
*status = data->num_chars;
return 0;
}
static int set_light(struct udevice *dev, int light)
{
struct shape_data *priv = dev_get_priv(dev);
struct gpio_desc *desc;
int ret;
int i;
desc = priv->gpio_desc;
for (i = 0; i < priv->gpio_count; i++, desc++) {
uint mask = 1 << i;
ret = dm_gpio_set_value(desc, light & mask);
if (ret < 0)
return ret;
}
return 0;
}
static int get_light(struct udevice *dev)
{
struct shape_data *priv = dev_get_priv(dev);
struct gpio_desc *desc;
uint value = 0;
int ret;
int i;
desc = priv->gpio_desc;
for (i = 0; i < priv->gpio_count; i++, desc++) {
uint mask = 1 << i;
ret = dm_gpio_get_value(desc);
if (ret < 0)
return ret;
if (ret)
value |= mask;
}
return value;
}
static const struct demo_ops shape_ops = {
.hello = shape_hello,
.status = shape_status,
.get_light = get_light,
.set_light = set_light,
};
static int shape_ofdata_to_platdata(struct udevice *dev)
{
struct dm_demo_pdata *pdata = dev_get_platdata(dev);
int ret;
/* Parse the data that is common with all demo devices */
ret = demo_parse_dt(dev);
if (ret)
return ret;
/* Parse the data that only we need */
pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"character", '@');
return 0;
}
static int dm_shape_probe(struct udevice *dev)
{
struct shape_data *priv = dev_get_priv(dev);
int ret;
ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc,
ARRAY_SIZE(priv->gpio_desc),
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret < 0)
return ret;
priv->gpio_count = ret;
debug("%s: %d GPIOs\n", __func__, priv->gpio_count);
return 0;
}
static int dm_shape_remove(struct udevice *dev)
{
struct shape_data *priv = dev_get_priv(dev);
return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count);
}
static const struct udevice_id demo_shape_id[] = {
{ "demo-shape", 0 },
{ },
};
U_BOOT_DRIVER(demo_shape_drv) = {
.name = "demo_shape_drv",
.of_match = demo_shape_id,
.id = UCLASS_DEMO,
.ofdata_to_platdata = shape_ofdata_to_platdata,
.ops = &shape_ops,
.probe = dm_shape_probe,
.remove = dm_shape_remove,
.priv_auto = sizeof(struct shape_data),
.platdata_auto = sizeof(struct dm_demo_pdata),
};