162306a36Sopenharmony_ci#!/usr/bin/awk -f
262306a36Sopenharmony_ci#
362306a36Sopenharmony_ci# Copyright 2010 Ben Dooks <ben-linux@fluff.org>
462306a36Sopenharmony_ci#
562306a36Sopenharmony_ci# Released under GPLv2
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci# example usage
862306a36Sopenharmony_ci# ./clksrc-change-registers.awk arch/arm/plat-s5pc1xx/include/plat/regs-clock.h < src > dst
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cifunction extract_value(s)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci    eqat = index(s, "=")
1362306a36Sopenharmony_ci    comat = index(s, ",")
1462306a36Sopenharmony_ci    return substr(s, eqat+2, (comat-eqat)-2)
1562306a36Sopenharmony_ci}
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cifunction remove_brackets(b)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci    return substr(b, 2, length(b)-2)
2062306a36Sopenharmony_ci}
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cifunction splitdefine(l, p)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci    r = split(l, tp)
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci    p[0] = tp[2]
2762306a36Sopenharmony_ci    p[1] = remove_brackets(tp[3])
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cifunction find_length(f)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci    if (0)
3362306a36Sopenharmony_ci	printf "find_length " f "\n" > "/dev/stderr"
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci    if (f ~ /0x1/)
3662306a36Sopenharmony_ci	return 1
3762306a36Sopenharmony_ci    else if (f ~ /0x3/)
3862306a36Sopenharmony_ci	return 2
3962306a36Sopenharmony_ci    else if (f ~ /0x7/)
4062306a36Sopenharmony_ci	return 3
4162306a36Sopenharmony_ci    else if (f ~ /0xf/)
4262306a36Sopenharmony_ci	return 4
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci    printf "unknown length " f "\n" > "/dev/stderr"
4562306a36Sopenharmony_ci    exit
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cifunction find_shift(s)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci    id = index(s, "<")
5162306a36Sopenharmony_ci    if (id <= 0) {
5262306a36Sopenharmony_ci	printf "cannot find shift " s "\n" > "/dev/stderr"
5362306a36Sopenharmony_ci	exit
5462306a36Sopenharmony_ci    }
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci    return substr(s, id+2)
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciBEGIN {
6162306a36Sopenharmony_ci    if (ARGC < 2) {
6262306a36Sopenharmony_ci	print "too few arguments" > "/dev/stderr"
6362306a36Sopenharmony_ci	exit
6462306a36Sopenharmony_ci    }
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci# read the header file and find the mask values that we will need
6762306a36Sopenharmony_ci# to replace and create an associative array of values
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci    while (getline line < ARGV[1] > 0) {
7062306a36Sopenharmony_ci	if (line ~ /\#define.*_MASK/ &&
7162306a36Sopenharmony_ci	    !(line ~ /USB_SIG_MASK/)) {
7262306a36Sopenharmony_ci	    splitdefine(line, fields)
7362306a36Sopenharmony_ci	    name = fields[0]
7462306a36Sopenharmony_ci	    if (0)
7562306a36Sopenharmony_ci		printf "MASK " line "\n" > "/dev/stderr"
7662306a36Sopenharmony_ci	    dmask[name,0] = find_length(fields[1])
7762306a36Sopenharmony_ci	    dmask[name,1] = find_shift(fields[1])
7862306a36Sopenharmony_ci	    if (0)
7962306a36Sopenharmony_ci		printf "=> '" name "' LENGTH=" dmask[name,0] " SHIFT=" dmask[name,1] "\n" > "/dev/stderr"
8062306a36Sopenharmony_ci	} else {
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci    }
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci    delete ARGV[1]
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/clksrc_clk.*=.*{/ {
8862306a36Sopenharmony_ci    shift=""
8962306a36Sopenharmony_ci    mask=""
9062306a36Sopenharmony_ci    divshift=""
9162306a36Sopenharmony_ci    reg_div=""
9262306a36Sopenharmony_ci    reg_src=""
9362306a36Sopenharmony_ci    indent=1
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci    print $0
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci    for(; indent >= 1;) {
9862306a36Sopenharmony_ci	if ((getline line) <= 0) {
9962306a36Sopenharmony_ci	    printf "unexpected end of file" > "/dev/stderr"
10062306a36Sopenharmony_ci	    exit 1;
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	if (line ~ /\.shift/) {
10462306a36Sopenharmony_ci	    shift = extract_value(line)
10562306a36Sopenharmony_ci	} else if (line ~ /\.mask/) {
10662306a36Sopenharmony_ci	    mask = extract_value(line)
10762306a36Sopenharmony_ci	} else if (line ~ /\.reg_divider/) {
10862306a36Sopenharmony_ci	    reg_div = extract_value(line)
10962306a36Sopenharmony_ci	} else if (line ~ /\.reg_source/) {
11062306a36Sopenharmony_ci	    reg_src = extract_value(line)
11162306a36Sopenharmony_ci	} else if (line ~ /\.divider_shift/) {
11262306a36Sopenharmony_ci	    divshift = extract_value(line)
11362306a36Sopenharmony_ci	} else if (line ~ /{/) {
11462306a36Sopenharmony_ci		indent++
11562306a36Sopenharmony_ci		print line
11662306a36Sopenharmony_ci	    } else if (line ~ /}/) {
11762306a36Sopenharmony_ci	    indent--
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	    if (indent == 0) {
12062306a36Sopenharmony_ci		if (0) {
12162306a36Sopenharmony_ci		    printf "shift '" shift   "' ='" dmask[shift,0] "'\n" > "/dev/stderr"
12262306a36Sopenharmony_ci		    printf "mask  '" mask    "'\n" > "/dev/stderr"
12362306a36Sopenharmony_ci		    printf "dshft '" divshift "'\n" > "/dev/stderr"
12462306a36Sopenharmony_ci		    printf "rdiv  '" reg_div "'\n" > "/dev/stderr"
12562306a36Sopenharmony_ci		    printf "rsrc  '" reg_src "'\n" > "/dev/stderr"
12662306a36Sopenharmony_ci		}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		generated = mask
12962306a36Sopenharmony_ci		sub(reg_src, reg_div, generated)
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		if (0) {
13262306a36Sopenharmony_ci		    printf "/* rsrc " reg_src " */\n"
13362306a36Sopenharmony_ci		    printf "/* rdiv " reg_div " */\n"
13462306a36Sopenharmony_ci		    printf "/* shift " shift " */\n"
13562306a36Sopenharmony_ci		    printf "/* mask " mask " */\n"
13662306a36Sopenharmony_ci		    printf "/* generated " generated " */\n"
13762306a36Sopenharmony_ci		}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci		if (reg_div != "") {
14062306a36Sopenharmony_ci		    printf "\t.reg_div = { "
14162306a36Sopenharmony_ci		    printf ".reg = " reg_div ", "
14262306a36Sopenharmony_ci		    printf ".shift = " dmask[generated,1] ", "
14362306a36Sopenharmony_ci		    printf ".size = " dmask[generated,0] ", "
14462306a36Sopenharmony_ci		    printf "},\n"
14562306a36Sopenharmony_ci		}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		printf "\t.reg_src = { "
14862306a36Sopenharmony_ci		printf ".reg = " reg_src ", "
14962306a36Sopenharmony_ci		printf ".shift = " dmask[mask,1] ", "
15062306a36Sopenharmony_ci		printf ".size = " dmask[mask,0] ", "
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci		printf "},\n"
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	    }
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	    print line
15762306a36Sopenharmony_ci	} else {
15862306a36Sopenharmony_ci	    print line
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	if (0)
16262306a36Sopenharmony_ci	    printf indent ":" line "\n" > "/dev/stderr"
16362306a36Sopenharmony_ci    }
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci// && ! /clksrc_clk.*=.*{/ { print $0 }
167